首页 > 代码库 > Spring依赖注入 --- 模拟实现
Spring依赖注入 --- 模拟实现
Spring依赖注入 --- 模拟实现
面向接口编程,又称面向抽象编程,
数据库如果发生更改,对应的数据访问层也应该改变
多写几个实现,需要用谁的时候在service里new谁就可以了
面向抽象编程的好处就是灵活。
创建用户实体类,
/ImitateSpring/src/yuki/spring/imitate/pojo/User.java
package yuki.spring.imitate.pojo;public class User { private String username; private String password; public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } }
/ImitateSpring/src/yuki/spring/imitate/service/UserService.java
package yuki.spring.imitate.service;import yuki.spring.imitate.dao.UserDAO;import yuki.spring.imitate.pojo.User;public class UserService { private UserDAO userDAO/* = new UserDAOImpl()*/; public UserDAO getUserDAO() { return userDAO; } public void setUserDAO(UserDAO userDAO) { this.userDAO = userDAO; } public void add(User u){ this.userDAO.save(u); }}
/ImitateSpring/src/yuki/spring/imitate/dao/UserDAO.java
package yuki.spring.imitate.dao;import yuki.spring.imitate.pojo.User;/*public class UserDAO { public void save(User u){ System.out.println("user saved..."); }}*/public interface UserDAO { void save(User u);}
/ImitateSpring/src/yuki/spring/imitate/dao/impl/UserDAOImpl.java
package yuki.spring.imitate.dao.impl;import yuki.spring.imitate.dao.UserDAO;import yuki.spring.imitate.pojo.User;public class UserDAOImpl implements UserDAO { @Override public void save(User u) { System.out.println("user saved..."); }}
之前的new很多DAO的解决方式是写工厂方法
现在,要新建一个总的工厂,把消息写在工厂文件中
用jdom解析xml,反射创建对象
引入jar包,jdom-2.0.5.jar
/ImitateSpring/src/yuki/spring/imitate/xml/test.xml
<?xml version="1.0" encoding="UTF-8"?><HD> <disk name="C"> <capacity>8G</capacity> <directories>200</directories> <files>1580</files> </disk> <disk name="D"> <capacity>10G</capacity> <directories>500</directories> <files>3000</files> </disk></HD>
/ImitateSpring/src/yuki/spring/imitate/spring/ClassPathXmlApplicationContext.java
package yuki.spring.imitate.xml;import java.util.List;import org.jdom2.Document;import org.jdom2.Element;import org.jdom2.input.SAXBuilder;public class Sample1 { public static void main(String[] args) throws Exception { SAXBuilder saxBuilder = new SAXBuilder(); Document document = saxBuilder.build( /*Sample1.class.getClassLoader().getResourceAsStream("/text.xml")*/ "D:/Workspaces/Eclipse/ImitateSpring/bin/yuki/spring/imitate/xml/test.xml"); Element root = document.getRootElement(); List<Element> elements = root.getChildren(); for(Element element : elements){ String name = element.getAttributeValue("name"); String capacity = element.getChildText("capacity"); String directories = element.getChildText("directories"); String files = element.getChildText("files"); System.out.println("磁盘信息:"); System.out.println("分区盘符:" + name); System.out.println("分区容量:" + capacity); System.out.println("目录数:" + directories); System.out.println("文件数:" + files); System.out.println("------------------------------"); } }}
运行结果如下:
磁盘信息:分区盘符:C分区容量:8G目录数:200文件数:1580------------------------------磁盘信息:分区盘符:D分区容量:10G目录数:500文件数:3000------------------------------
可以把bean作为另一个bean的属性注入
/ImitateSpring/src/beans.xml
<?xml version="1.0" encoding="UTF-8"?><beans> <bean id="u" class="yuki.spring.imitate.dao.impl.UserDAOImpl"></bean> <bean id="userService" class="yuki.spring.imitate.service.UserService"> <property name="userDAO" bean="u"></property> </bean></beans>
/ImitateSpring/src/yuki/spring/imitate/spring/BeanFactory.java
package yuki.spring.imitate.spring;public interface BeanFactory { Object getBean(String name);}
/ImitateSpring/src/yuki/spring/imitate/spring/ClassPathXmlApplicationContext.java
package yuki.spring.imitate.spring;import java.lang.reflect.Method;import java.util.HashMap;import java.util.List;import java.util.Map;import org.jdom2.Document;import org.jdom2.Element;import org.jdom2.input.SAXBuilder;public class ClassPathXmlApplicationContext implements BeanFactory { private Map<String, Object> beans = new HashMap<String, Object>(); public ClassPathXmlApplicationContext() throws Exception { SAXBuilder saxBuilder = new SAXBuilder(); Document document = saxBuilder.build( "D:/Workspaces/Eclipse/ImitateSpring/bin/beans.xml"); Element root = document.getRootElement(); List<Element> elements = root.getChildren(); for(Element element : elements){ String id = element.getAttributeValue("id"); String clazz = element.getAttributeValue("class"); System.out.println(id + " : " + clazz); Object o = Class.forName(clazz).newInstance(); beans.put(id, o); for(Element propertyElement : element.getChildren("property")){ String name = propertyElement.getAttributeValue("name"); String bean = propertyElement.getAttributeValue("bean"); Object beanObject = beans.get(bean); String methodName = "set" + name.substring(0, 1).toUpperCase() + name.substring(1); System.out.println("method name = " + methodName); Method m = o.getClass().getMethod(methodName, beanObject.getClass().getInterfaces()[0]); m.invoke(o, beanObject); } } } @Override public Object getBean(String name){ return beans.get(name); }}
通过JUnit,可以新建测试类
/ImitateSpring/test/yuki/spring/imitate/service/UserServiceTest.java
package yuki.spring.imitate.service;import org.junit.Test;import yuki.spring.imitate.pojo.User;import yuki.spring.imitate.spring.BeanFactory;import yuki.spring.imitate.spring.ClassPathXmlApplicationContext;public class UserServiceTest { @Test public void testAdd() throws Exception { BeanFactory factory = new ClassPathXmlApplicationContext(); UserService service = (UserService) factory.getBean("userService"); /*UserDAO userDAO = (UserDAO) factory.getBean("u"); service.setUserDAO(userDAO);*/ User u = new User(); service.add(u); }}
运行结果如下:
u : yuki.spring.imitate.dao.impl.UserDAOImpluserService : yuki.spring.imitate.service.UserServicemethod name = setUserDAOuser saved...
术语解释:
控制反转(IOC)、依赖注入(DI)
本来应该自己控制的,交给容器控制,可以实现随意装配
本文参考了[尚学堂马士兵_Spring_模拟Spring]的公开课程
更多好文请关注:http://www.cnblogs.com/kodoyang/
Spring依赖注入 --- 模拟实现