深入探索spring技术内幕(二): 剖析spring管理Bean的原理与配置
来源:互联网 发布:如何随机生成一组数据 编辑:程序博客网 时间:2024/06/04 08:10
一、前言
spring是如何管理Bean的? 想必这是每一个初学spring的同学想弄清楚的问题, 好吧, 网上百度一下你会得到这样的答案:
服务启动时, 容器会解析配置文件, 并且会通过反射机制实例化配置中所有的类, 然后我们可以通过下面的方法获取Bean:
ApplicationContext ctx = new ClassPathXmlApplicationContext("spring.xml");
MyService myService = (MyService) ctx.getBean("myService");
二、模拟spring管理Bean
如果你只满足于此, 那就太没意思了, 要不咱自己模拟一下看看?
① 准备工作: 导Jar包
dom4j-1.6.1.jar 使用dom4j解析xml
jaxen-1.1-beta-6.jar 这是一个dom4j依赖包
② Bean对象定义封装
/** * Bean对象定义 * @author zhangjim */public class BeanDefinition {private String id;private String className;public BeanDefinition(String id, String className) {this.id = id;this.className = className;}public String getId() {return id;}public void setId(String id) {this.id = id;}public String getClassName() {return className;}public void setClassName(String className) {this.className = className;}}
③ Bean工厂
import java.net.URL;import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map;import org.dom4j.Document;import org.dom4j.Element;import org.dom4j.XPath;import org.dom4j.io.SAXReader;/** * Bean的工厂 * @author zhangjim */public class ClassPathXMLApplicationContext {private List<BeanDefinition> beanDefines = new ArrayList<BeanDefinition>();private Map<String, Object> sigletons = new HashMap<String, Object>();public ClassPathXMLApplicationContext(String filename) {this.readXML(filename);this.instanceBeans();}/** * 完成bean的实例化 */private void instanceBeans() {for (BeanDefinition beanDefinition : beanDefines) {try {if (beanDefinition.getClassName() != null && !"".equals(beanDefinition.getClassName().trim()))sigletons.put(beanDefinition.getId(), Class.forName(beanDefinition.getClassName()).newInstance());} catch (Exception e) {e.printStackTrace();}}}/** * dom4j读取xml配置文件 * @param filename */private void readXML(String filename) {SAXReader saxReader = new SAXReader();Document document = null;try {URL xmlpath = this.getClass().getClassLoader().getResource(filename);document = saxReader.read(xmlpath);Map<String, String> nsMap = new HashMap<String, String>();nsMap.put("ns", "http://www.springframework.org/schema/beans");// 加入命名空间XPath xsub = document.createXPath("//ns:beans/ns:bean");// 创建beans/bean查询路径xsub.setNamespaceURIs(nsMap);// 设置命名空间List<Element> beans = xsub.selectNodes(document);// 获取文档下所有bean节点for (Element element : beans) {String id = element.attributeValue("id");// 获取id属性值String clazz = element.attributeValue("class"); // 获取class属性值BeanDefinition beanDefine = new BeanDefinition(id, clazz);beanDefines.add(beanDefine);}} catch (Exception e) {e.printStackTrace();}}/** * 获取bean实例 * @param beanName * @return */public Object getBean(String beanName) {return this.sigletons.get(beanName);}}
1. 读取配置文件, 数据封装到BeanDefinition
2. 将BeanDefinition对象存入list
3. 遍历list, 通过反射产生对象并存入map
4. 调用getBean方法返回一个对象, 此对象为单例
④ 配置文件
<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"><bean id="helloService" class="com.zdp.service.HelloService"></bean></beans>
⑤ 测试一下
import com.zdp.myspring.ClassPathXMLApplicationContext;public class HelloService{public void sayHello() {System.out.println("say hello..."); }public static void main(String[] args) {ClassPathXMLApplicationContext ctx = new ClassPathXMLApplicationContext("beans.xml");HelloService helloService = (HelloService) ctx.getBean("helloService");helloService.sayHello();}}
三、spring三种实例化Bean的方式
① 使用类构造器实例化Bean, IoC容器使用默认空构造器
<bean id="helloBean1" class="com.zdp.service.impl.HelloBean"/>
② 使用静态工厂方法实例化Bean
<bean id="helloBean2" class="com.zdp.factory.HelloBeanStaticFactory" factory-method="createHelloBean"/>
public class HelloBeanStaticFactory {public static Hello createHelloBean() {return new HelloBean();}}
③ 使用实例工厂方法实例化Bean
<bean id="instanceFactory" class="com.zdp.factory.HelloBeanInstanceFactory"/>
<bean id="helloBean3" factory-bean="instanceFactory" factory-method="createHelloBean"/>
public class HelloBeanInstanceFactory {public Hello createHelloBean() {return new HelloBean();}}
四、配置spring管理Bean的作用域
① singleton
<bean id="xxx" class="xxx" scope="singleton" />
只有一个对象实例, 默认情况下回再容器启动时初始化Bean, 但我们可以配置延迟初始化Bean
② prototype
<bean id="xxx" class="xxx" scope="prototype" />
每次从容器中获取Bean都是新的对象.
③ request
<bean id="xxx" class="xxx" scope="request" />
作用域基于web下有效
④ session
<bean id="xxx" class="xxx" scope="session" />
作用域基于web下有效
五、spring管理Bean的生命周期
Bean默认是在容器初始化时就创建, 如果配置了延迟加载, 则会延迟Bean的实例化
<bean id="xxx" class="xxx" scope="singleton" lazy-init="true" /> <!-- 只有第一次获取Bean才会初始化Bean -->
<beans default-lazy-init="true"> <!-- 对所有Bean都应用延迟初始化 -->init和destory:
<bean id="xxx" class="xxx" scope="singleton" init-method="init" destroy-method="destory" />
public class HelloBeanTest {@Testpublic void testSayHello() {AbstractApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml"); Hello hello =(Hello) ctx.getBean("helloBean"); // 调用init hello.sayHello(); ctx.close(); // 调用destory}}
- 深入探索spring技术内幕(二): 剖析spring管理Bean的原理与配置
- 深入探索spring技术内幕(二): 剖析spring管理Bean的原理与配置
- 深入探索spring技术内幕(三): 剖析spring IoC工作原理和配置依赖注入
- 深入探索spring技术内幕(三): 剖析spring IoC工作原理和配置依赖注入
- 深入探索spring技术内幕(四): 剖析@Resource注解实现原理与注解注入
- 深入探索spring技术内幕(四): 剖析@Resource注解实现原理与注解注入
- 深入探索spring技术内幕(四): 剖析@Resource注解实现原理与注解注入
- 深入探索spring技术内幕(五): 剖析spring AOP工作原理
- 深入探索spring技术内幕(五): 剖析spring AOP工作原理
- 编码剖析Spring管理Bean的原理
- Spring技术内幕——深入解析Spring架构与设计原理(二)AOP
- Spring技术内幕——深入解析Spring架构与设计原理(二)AOP
- Spring技术内幕——深入解析Spring架构与设计原理(二)AOP
- Spring技术内幕——深入解析Spring架构与设计原理(二)AOP
- Spring、编码剖析Spring管理Bean的原理
- Spring技术内幕:Spring AOP的实现原理(二)
- 深入探索spring技术内幕(七): 配置Spring AOP面向切面编程
- 深入探索spring技术内幕(七): 配置Spring AOP面向切面编程
- android tabwidget 调整高度文字居中
- 《c++ primer》学习笔记 第六章 语句
- exe, dll 中资源提取工具
- 《c++primer(第四版)》习题11.9
- C#修改文件或文件夹的权限,为指定用户、用户组添加完全控制权限
- 深入探索spring技术内幕(二): 剖析spring管理Bean的原理与配置
- Effective Java 读书笔记( 2 创建和销毁对象)
- 11周------班长信息储存 学生类
- 自定义TabWidget
- 悔过,明志
- iOS处理JAVA的struts框架传递的JSON
- 【转】你是工具综合症和资料收集狂患者吗?
- LAMP网站架构方案分析
- 11周----项目2 职员和薪水