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.UserDAOImpl userService : yuki.spring.imitate.service.UserService method name = setUserDAO user saved...
术语解释:
控制反转(IOC)、依赖注入(DI)
本来应该自己控制的,交给容器控制,可以实现随意装配
本文参考了[尚学堂马士兵_Spring_模拟Spring]的公开课程
更多好文请关注:http://www.cnblogs.com/kodoyang/
Spring依赖注入 --- 模拟实现的更多相关文章
- (转)编码剖析Spring依赖注入的原理
http://blog.csdn.net/yerenyuan_pku/article/details/52834561 Spring的依赖注入 前面我们就已经讲过所谓依赖注入就是指:在运行期,由外部容 ...
- Spring依赖注入(IOC)那些事
小菜使用Spring有几个月了,但是对于它的内部原理,却是一头雾水,这次借着工作中遇到的一个小问题,来总结一下Spring. Spring依赖注入的思想,就是把对象交由Spring容器管理,使用者只需 ...
- Spring依赖注入三种方式详解
在讲解Spring依赖注入之前的准备工作: 下载包含Spring的工具jar包的压缩包 解压缩下载下来的Spring压缩包文件 解压缩之后我们会看到libs文件夹下有许多jar包,而我们只需要其中的c ...
- Spring依赖注入:注解注入总结
更多11 spring 依赖注入 注解 java 注解注入顾名思义就是通过注解来实现注入,Spring和注入相关的常见注解有Autowired.Resource.Qualifier.S ...
- Spring 依赖注入,在Main方法中取得Spring控制的实例
Spring依赖注入机制,在Main方法中通过读取配置文件,获取Spring注入的bean实例.这种应用在实训的时候,老师曾经说过这种方法,而且学Spring入门的时候都会先学会使用如何在普通的jav ...
- Spring依赖注入 --- 简单使用说明
Spring依赖注入 --- 简单使用说明 本文将对spring依赖注入的使用做简单的说明,enjoy your time! 1.使用Spring提供的依赖注入 对spring依赖注入的实现方法感兴趣 ...
- Java Web系列:Spring依赖注入基础
一.Spring简介 1.Spring简化Java开发 Spring Framework是一个应用框架,框架一般是半成品,我们在框架的基础上可以不用每个项目自己实现架构.基础设施和常用功能性组件,而是 ...
- Spring依赖注入的三种方式
看过几篇关于Spring依赖注入的文章,自己简单总结了一下,大概有三种方式: 1.自动装配 通过配置applicationContext.xml中的标签的default-autowire属性,或者标签 ...
- spring依赖注入源码分析和mongodb自带连接本地mongodb服务逻辑分析
spring依赖注入本质是一个Map结构,key是beanId,value是bean对应的Object. autowired是怎么将定义的接口与对应的bean类建立联系? <bean name= ...
随机推荐
- 269. Alien Dictionary
题目: There is a new alien language which uses the latin alphabet. However, the order among letters ar ...
- CentOS7修改服务器主机名方法
CentOS7下修改主机名 第一种:hostname 主机名 01.hostname 主机名称 这种方式,只能修改临时的主机名,当重启机器后,主机名称又变回来了. 第二种:hostnamectl se ...
- PV UV
定义 PV: Page View 页面浏览量或点击量,用户每次刷新即被计算一次. UV: Unique Visitor 就是有多少个IP数量.就是指的有多少人在访问你的店.每个人用的电脑 ...
- Wordnet 与 Hownet 比较
近年来,随着计算机本身以及信息高速公路的飞速发展,人们开始更加重视语义的研究.各国都致力于可用于自然语言处理的大规模语义词典或大规模知识库的建设.例如:普林斯顿大学的英语Wordnet,微软的Mind ...
- 最短JS判断是否为IE6(IE的写法) (转)
常用的 JavaScript 检测浏览器为 IE 是哪个版本的代码,包括是否是最人极端厌恶的 ie6 识别与检测. 代码如下: var isIE = !!window.ActiveXObject; v ...
- 《c程序设计语言》读书笔记--闰年和字符输入不用 && ||
#include <stdio.h> #include <string.h> #define sta 1500 #define Num 1600 int main() { in ...
- Simple Factory vs. Factory Method vs. Abstract Factory【简单工厂,工厂方法以及抽象工厂的比较】
I ran into a question on stackoverflow the other day that sort of shocked me. It was a piece of code ...
- VS2013控制台一闪而过问题解决方法
1.修改项目配置,右键点击项目: 2.在右键菜单中选择属性,然后在弹出的对话框左侧列表中中选择 “配置属性”-->“链接器”-->“系统”然后在右侧的列表中,在第一项”子系统“的值中选择” ...
- oracle数据库导入导出命令!
Oracle数据导入导出imp/exp 功能:Oracle数据导入导出imp/exp就相当与oracle数据还原与备份. 大多情况都可以用Oracle数据导入导出完成数据的备份和还原(不会造成数据的丢 ...
- HeadFirst Jsp 07 (使用 jsp)
Jsp 变成 Servlet, 容器会查看你的JSP, 把它转换成java源代码, 再编译成完整的Java servlet类. Jsp 不需要你的编译, 容器会自动替换成servlet. 在 jsp中 ...