模拟Spring 的bean工厂模式与自动装配
来源:互联网 发布:iso9001 软件开发 编辑:程序博客网 时间:2024/06/07 11:18
使用过Spring框架进行开发的朋友都知道,Spring实例化各种JavaBean,可以通过基于配置文件的方式也可以通过基于注解的方式,让Spring帮我们实例化对应的Bean。
org.springframework.beans.factory.BeanFactory 是Spring IoC容器的实际代表者,IoC容器负责容纳此前所描述的bean,并对bean进行管理。
在Spring中,BeanFactory是IoC容器的核心接口。 它的职责包括:实例化、定位、配置应用程序中的对象及建立这些对象间的依赖。
Spring为我们提供了许多易用的BeanFactory实现, XmlBeanFactory就是最常用的一个。该实现将以XML方式描述组成应用的对象 以及对象间的依赖关系。XmlBeanFactory类将获取此XML配 置元数据,并用它来构建一个完全可配置的系统或应用。
从上图可以看到,Spring IoC容器将读取配置元数据; 并通过它对应用中各个对象进行实例化、配置以及组装。通常情况下我们使用简单直观 的XML来作为配置元数据的描述格式。在XML配置元数据中我们可以对那些我们希望通过 Spring IoC容器管理的bean进行定义。
Spring读取配置文件是用反射机制读的jvm的.class文件(采用classLoader调用类似的方法),用这种方法能取消类对象的创建与取出,依靠bean工厂就可以实现。
这里采用dom4j/jdom方式模拟Spring的工作原理。
查看Spring的API可以知道,Spring生产Bean的工厂为BeanFactory,所以我们首先创建一个模拟Spring的Bean工厂的BeanFactory接口:
1.BeanFactory接口
public interface BeanFactory { public Object getBean(String name);}
基于读取配置文件来实例化JavaBean,那自然少不了配置文件。这里自定义为beans.xml,没有用默认的applicationContext.xml命名。
2.beans.xml文件
<beans> <bean id="u" class="com.dao.impl.UserDaoImpl"></bean> <bean id="userService" class="com.service.UserService"> <property name="UserDao" bean="u"></property> </bean></beans>
property标签可以实现bean的自动装配,依据bean的id将属性注入。property指set方法,即UserService中有个方法setUserDao(),而该方法调用时应该将id名为“u”的bean传进来。
具体的实现方法是:
UserService service = (UserService) factory.getBean(“userService”);
UserDao dao = (UserDao) factory.getBean(“u”);
测试类从工厂里取出
Spring需要知道开发者写的是哪个配置文件,所以需要ClassPathXmlApplicationContext来读取配置文件,这里同样对ClassPathXmlApplicationContext进行模拟。
3.ClassPathXmlApplicationContext 类
//模拟Spring的ClassPathXmlApplicationContext,它实现了BeanFactory接口public class ClassPathXmlApplicationContext implements BeanFactory{ //模拟Spring装载bean实例的容器 private Map<String,Object> beans = new HashMap<String,Object>(); public ClassPathXmlApplicationContext() throws Exception{ //创建SAXBuilder组建器 SAXBuilder sb = new SAXBuilder(); //加载配置文件 Document doc = sb.build(this.getClass().getClassLoader().getResourceAsStream("beans.xml")); //解析配置文件 Element root = doc.getRootElement(); List list = root.getChildren("bean"); //遍历文件各个bean节点 for(int i=0;i<list.size();i++){ Element element = (Element) list.get(i); String id = element.getAttributeValue("id"); String clazz = element.getAttributeValue("class"); System.out.println(id+":"+clazz); //根据类路径clazz创建该类的对象,实例化bean Object o = Class.forName(clazz).newInstance(); //将实例化好的bean存入容器(map)中 beans.put(id, o); //遍历每个bean下的property节点 for(Element propertyElement:(List<Element>)element.getChildren("property")){ String name = propertyElement.getAttributeValue("name"); String bean = propertyElement.getAttributeValue("bean"); 根据property节点的bean名称,从容器map中取出实例化的bean Object beanObject = beans.get(bean); //取得name值对应的set方法 String methodName = "set"+name.substring(0, 1).toUpperCase()+name.substring(1); System.out.println("method name="+methodName); /** * 获取set方法所属的类所实现的接口数组。o为主bean,beanObject为需要装配的bean * beanObject对象为UserDaoImpl对象,获取其接口数组的第一个值(这里只实现了UserDao接口) */ Method m = o.getClass().getMethod(methodName,beanObject.getClass().getInterfaces()[0]); m.invoke(o, beanObject); } } } @Override public Object getBean(String name) { return beans.get(name); }}
4.建立测试类
BeanFactory factory = new ClassPathXmlApplicationContext(“beans.xml”);
- 模拟Spring 的bean工厂模式与自动装配
- 工厂模式---模拟Spring的Bean工厂
- Spring--IoC--Bean的装配--工厂方法设计模式
- spring的自动装配Bean与自动检测Bean
- spring的自动装配Bean与自动检测Bean
- Spring Bean的装配 -- 自动装配
- [Spring]Bean的自动装配
- # Spring Bean 的自动装配
- spring bean的自动装配
- spring bean的自动装配
- Spring的自动装配Bean
- Spring bean的自动装配
- 【Spring】Bean的自动装配
- Spring Bean的自动装配
- Spring bean的自动装配
- spring <bean>的自动装配
- Spring中Bean自动装配的五种模式
- 3,工厂模式--模拟spring的bean工厂beanFactory
- org.hibernate.exception.GenericJDBCException: Could not open connection解决思路 SSH框架
- /usr/bin/python^M: bad interpreter: No such file
- 中文字符编码标准+Unicode+Code Page
- Android 路径(Path)与剪裁(Clipping)详解
- LeetCode 53. Maximum Subarray Java
- 模拟Spring 的bean工厂模式与自动装配
- 05.流程控制
- 如何写出高效率的正则表达式
- pandas学习02
- Spirng 如何读取配置文件application.properties
- mybatis3的mapper文件报Referenced file contains errors (maven)
- Windows下配置nginx+php(wnmp)
- JavaScript权威指南——从笨鸟到菜鸟(四) 语法结构(下)— 可选的分号
- getResourceAsStream和getResource的用法及Demo实例