Spring IOC的简单实现
简单的说,Spring就是通过工厂+反射将我们的bean放到它的容器中的,当我们想用某个bean的时候,只需要调用getBean("beanID")方法即可。
原理简单说明:
Spring容器的原理,其实就是通过解析xml文件,通过反射创建出我们所需要的bean,再将这些bean挨个放到集合中,然后对外提供一个getBean()方法,以便我们获得这bean。
下面我们来简单实现一个demo
beans.xml
- <?xml version="1.0" encoding="UTF-8"?>
- <beans>
- <bean id="user" class="com.yyb.model.User" />
- <bean id="userDAO" class="com.yyb.dao.impl.UserDAOImpl" />
- <bean id="userService" class="com.yyb.service.UserService">
- <property name="userDAO" bean="userDAO" />
- </bean>
- </beans>
BeanFactory
- public interface BeanFactory {
- Object getBean(String name);
- }
ClassPathXmlApplicationContext:读取xml文件内容,并创建对象及对象关系(使用setter方式)
- package com.yyb.spring;
- import java.io.IOException;
- import java.lang.reflect.InvocationTargetException;
- import java.lang.reflect.Method;
- import java.util.HashMap;
- import java.util.List;
- import java.util.Map;
- import org.jdom.Document;
- import org.jdom.Element;
- import org.jdom.JDOMException;
- import org.jdom.input.SAXBuilder;
- public class ClassPathXmlApplicationContext implements BeanFactory
- {
- private Map<String, Object> beans = new HashMap<String, Object>();
- public ClassPathXmlApplicationContext() throws JDOMException, IOException,
- InstantiationException, IllegalAccessException,
- ClassNotFoundException, SecurityException, NoSuchMethodException,
- IllegalArgumentException, InvocationTargetException
- {
- SAXBuilder sb = new SAXBuilder();
- // 构造文档对象
- Document doc = sb.build(ClassPathXmlApplicationContext.class
- .getClassLoader().getResourceAsStream("beans.xml"));
- // 获取根元素
- Element root = doc.getRootElement();
- // 取到根元素所有元素
- List list = root.getChildren();
- for (int i = 0; i < list.size(); i++)
- {
- Element element = (Element) list.get(i);
- // 取id子元素
- String beanid = element.getAttributeValue("id");
- // 取class子元素
- String clzss = element.getAttributeValue("class");
- // 实例化
- Object o = Class.forName(clzss).newInstance();
- // 将所有bean放入map中
- beans.put(beanid, o);
- // 获取property 进行依赖注入
- for (Element propertyElement : (List<Element>) element
- .getChildren("property"))
- {
- String name = propertyElement.getAttributeValue("name");
- System.out.println(name);//userDAO
- String bean = propertyElement.getAttributeValue("bean");
- System.out.println(bean);//userDAO
- // 从beans.xml中根据id取到类的对象
- //Object beanObj = this.getBean(name);
- // 从beans.xml中根据id取到类的对象
- Object beanObj = this.getBean(bean);
- System.out.println(beanObj);//com.yyb.dao.impl.UserDAOImpl@a09ee92
- // 形成setXXX方法名
- String methodName = "set" + name.substring(0, 1).toUpperCase()
- + name.substring(1);
- System.out.println(name.substring(0, 1).toUpperCase());//U
- System.out.println(name.substring(1));//serDAO
- System.out.println(methodName);//setUserDAO
- // 反射机制对方法进行调用,将对象在加载bean时就注入到环境上下文中
- Method m = o.getClass().getMethod(methodName,
- beanObj.getClass().getInterfaces()[0]);
- System.out.println(o.getClass());//class com.yyb.service.UserService
- System.out.println(beanObj.getClass().getInterfaces()[0]);//interface com.yyb.dao.UserDAO
- System.out.println(m);//public void com.yyb.service.UserService.setUserDAO(com.yyb.dao.UserDAO)
- // 执行注入,相当于执行了一个setXXX(args..)的方法
- m.invoke(o, beanObj);
- }
- }
- }
- @Override
- public Object getBean(String name)
- {
- return beans.get(name);
- }
- }
对于以上这段代码实现的效果为:
Service service=(Service)beans.get("userService");
Dao dao = (Dao)beans.get("userDAO");
//依赖注入,Service实现依赖dao的实现
service.setDao(dao);
User:实体类
- public class User {
- private String userName;
- private String password;
- /**
- * @return the userName
- */
- public String getUserName()
- {
- return userName;
- }
- /**
- * @param userName
- * the userName to set
- */
- public void setUserName(String userName)
- {
- this.userName = userName;
- }
- /**
- * @return the password
- */
- public String getPassword()
- {
- return password;
- }
- /**
- * @param password
- * the password to set
- */
- public void setPassword(String password)
- {
- this.password = password;
- }
- public String toString()
- {
- StringBuffer sb = new StringBuffer();
- sb.append(this.userName);
- sb.append(this.password);
- return sb.toString();
- }
- }
UserDAO
- public interface UserDAO {
- void save(User u);
- void delete();
- }
UserDAOImpl
- public class UserDAOImpl implements UserDAO {
- @Override
- public void save(User u) {
- System.out.println("User:" + u.toString());
- }
- @Override
- public void delete() {
- System.out.println("delete User");
- }
- }
UserService
- public class UserService {
- private UserDAO userDAO;
- public void addUser(User u)
- {
- this.userDAO.save(u);
- }
- /**
- * @return the userDAO
- */
- public UserDAO getUserDAO()
- {
- return userDAO;
- }
- /**
- * @param userDAO
- * the userDAO to set
- */
- public void setUserDAO(UserDAO userDAO)
- {
- this.userDAO = userDAO;
- }
- }
下面我们来简单测试一下实现的效果:
Client
- public class client {
- public static void main(String[] args) throws InstantiationException, IllegalAccessException, ClassNotFoundException, SecurityException, NoSuchMethodException, IllegalArgumentException, InvocationTargetException, JDOMException, IOException {
- BeanFactory factory = new ClassPathXmlApplicationContext();
- //通过工厂直接获取
- UserService userService = (UserService) factory.getBean("userService");
- //其实User也可以从工厂中获得
- User u=(User)factory.getBean("user");
- //User u = new User();
- u.setUserName("yyb");
- u.setPassword("1234");
- userService.addUser(u);//打印结果yyb1234
- }
- }
当然以上我们是通过setter方法注入,还可以使用构造器注入,也就是在建立对象的时候建立关系(即在UserService的构造函数中添加对userDAO的赋值操作)
总结:
以上通过IOC的一个简要实现实例,模拟了Spring中IOC的实现,虽然只是完成了Spring中依赖注入的一小部分工作,但是很好的展现了Java反射机制在Spring中的应用,能使我们能更好的从原理上了解IOC的实现,也能为我们实现自己的Spring框架提供了方案。
Spring IOC实现原理demo:IOC
Spring IOC的简单实现的更多相关文章
- Spring IOC 的简单使用
Spring IOC (Inversion Of Control反转控制容器 一.对于IOC容器的简单理解 在java开发中将程序中的对象交给容器管理,而不是在对象的内部管理. 那么两个简单的问题去分 ...
- Spring IOC 方式结合TESTGN测试用例,测试简单java的命令模式
java命令模式: 可以命令("请求")封装成一个对象,一个命令对象通过在特定的接收着上绑定一组动作来封装一个请求.命令对象直接把执行动作和接收者包进对象中,只对外暴露出执行方法的 ...
- 1.Spring IoC简单例子
Spring IoC简单例子 1.IHelloMessage.java package com.tony.spring.chapter01; public interface IHelloMessag ...
- Spring容器的简单实现(IOC原理)
引言:容器是什么?什么是容器?Spring容器又是啥东西?我给Spring容器一个对象名字,为啥能给我创建一个对象呢? 一.容器是装东西的,就像你家的水缸,你吃饭的碗等等. java中能作为容器的有很 ...
- Spring IOC 源码简单分析 03 - 循环引用
### 准备 ## 目标 了解 Spring 如何处理循环引用 ##测试代码 gordon.study.spring.ioc.IOC03_CircularReference.java ioc03. ...
- Spring IOC 源码简单分析 02 - Bean Reference
### 准备 ## 目标 了解 bean reference 装配的流程 ##测试代码 gordon.study.spring.ioc.IOC02_BeanReference.java ioc02 ...
- (反射+内省机制的运用)简单模拟spring IoC容器的操作
简单模拟spring IoC容器的操作[管理对象的创建.管理对象的依赖关系,例如属性设置] 实体类Hello package com.shan.hello; public class Hello { ...
- spring IOC简单分析
Spring IOC 体系结构 BeanFactory(BeanFactory 里只对 IOC 容器的基本行为作了定义,根本不关心你的 bean 是如何定义怎样加载的.正如我们只关心工厂里得到什么的产 ...
- Spring IOC 源码简单分析 04 - bean的初始化
### 准备 ## 目标 了解 Spring 如何初始化 bean 实例 ##测试代码 gordon.study.spring.ioc.IOC04_Initialization.java publ ...
随机推荐
- 理解JVM
1.JVM运行时数据区 2.方法区 方法区垃圾回收的条件:该类的所有实例(堆内存中)被回收:加载该类字节码的类加载器被回收:所有的类对象(如Student.class)的引用被回收 一般采用可达性分析 ...
- LC 357. Count Numbers with Unique Digits
Given a non-negative integer n, count all numbers with unique digits, x, where 0 ≤ x < 10n. Examp ...
- 算法 - 插入排序交换次数 - Binary Indexed Tree
场景:快速得到一段数组元素的和 题目:Insertion Sort Advanced Analysis | HackerRank 算法:binary-indexed-tree :: HackerRan ...
- JNI知识扩展
JNI(Java Native Interface,JAVA原生接口) 使用JNI可以使Java代码和其他语言写的代码(如C/C++代码)进行交互. 问:为什么要进行交互? |- 首先,Java语言提 ...
- idea将springboot打包成jar或者war
1.首先在pom.xml中添加下面配置 <groupId>com.melo</groupId> <artifactId>focus</artifactId&g ...
- 科学论文写作 Tips
感觉还是课程中给的英文描述会比较好,所以笔记大多数还是以老师的原英文 PPT 为主 1 Steps in the Writing Process 如何开展论文写作以及各个步骤的时间分配 1-1 Pre ...
- Elasticsearch mapping映射文件设置没有生效
Elasticsearch mapping映射文件设置没有生效 问题背景 我们一般会预先创建 Elasticsearch index的 mapping.properties 文件(类似于MySQL中的 ...
- java源码-ReentrantLock源码分析-2
继续上篇ReentrantLock分析如何唤醒线程: 当调用lock.unlock()方法最终调用AQS类中的release方法,开始释放锁 tryRelease(1)方法在Sync对象中实现,首先会 ...
- FSCalendar使用和注意事项
相信大家项目中或多或少都有日历这一块的内容吧,公司作为教育行业的软件公司,当然也是一定有的. 最近被日历这一块的内容弄得很头疼啊,改来改去的,不过还是学到了很多东西,至少FSCalendar的使用基本 ...
- 怎么在 localhost 下访问多个 Laravel 项目,通过一个IP访问多个项目(不仅仅是改变端口哦)
server { listen 80; server_name blog.sweetsunnyflower.com; index index.html index.htm index.php; cha ...