Spring 有生命周期的bean的依赖注入
2013-02-28 17:40
489 查看
Spring 有生命周期的bean的依赖注入
Spring IoC容器不仅为你初始化对象,并且会为你关联那些互相协作的bean或者依赖,如果你想将一个生命周期为HTTP request的bean注入到另一bean中,你必须在这个bean中注入一个AOP代理,这个代理具有和这个bean相同的接口,当调用这些API的时候,实际会委托调用真实的对象。至于为什么要这么做,可以看下下面的例子。[html] view
plaincopy
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
<!-- an HTTP Session-scoped bean exposed as a proxy -->
<bean id="userPreferences" class="com.foo.UserPreferences" scope="session">
<!-- instructs the container to proxy the surrounding bean -->
<aop:scoped-proxy/>
</bean>
<!-- a singleton-scoped bean injected with a proxy to the above bean -->
<bean id="userService" class="com.foo.SimpleUserService">
<!-- a reference to the proxied userPreferences bean -->
<property name="userPreferences" ref="userPreferences"/>
</bean>
</beans>
为了创建这个代理,你在bean中插入了这么一个元素<aop:scoped-proxy/>,(如果你选择使用基于类的代理,你需要在你的CLASSPATH里加入CGLIB jar包,默认选择CGLIB),为什么除了singleton,和prototype生命周期的bean都需要<aop:scoped-proxy/>呢?那让我们回过头来看看prototype和前面提到的session的scope(注意:以下这段配置是不完整的,只作说明用)。
[html] view
plaincopy
<bean id="userPreferences" class="com.foo.UserPreferences" scope="session"/>
<bean id="userManager" class="com.foo.UserManager">
<property name="userPreferences" ref="userPreferences"/>
</bean>
这个例子中,userManager是一个scope为singleton的bean,并且为他注入一个Http session周期的bean: userPreferences,很明显,userManager在容器中是一个单例,他只会在容器中被实例化一次,他的依赖也只会被注入一次,也就是说实际上userManager每次都操作的都是相同的userPreferences对象。这样的话即违背你之前想要的结果,把一个短生命周期的bean注入到一个具有长生命周期的bean当中,但是为了考虑HttpSession的生命周期,所以你必须让userPreferences指明他的生命周期,因此容器创建一个和userPreferences具有相同接口的代理对象,他会去请求真正的userPreferences操作,容器将这个代理注入给userManager,但这一切对userManager却是透明的,当他调用userPreferences时,实际是在调用这个代理,代理再去取得实际的HttpSession中得userPreferences,委托调用userPreferences的方法。
因此,当你要注入的bean的scope是request,session或globalSession时,正确完整的写法应该是下面这样的:
[html] view
plaincopy
<bean id="userPreferences" class="com.foo.UserPreferences" scope="session">
<aop:scoped-proxy/>
</bean>
<bean id="userManager" class="com.foo.UserManager">
<property name="userPreferences" ref="userPreferences"/>
</bean>
到这就说完了,实际上以上内容是一个理解Proxy设计模式的极好例子!
相关文章推荐
- Spring 有生命周期的bean的依赖注入
- 11级_Java_曹建波 04.24 Spring的配置、生命周期、依赖注入bean的操作
- Spring的配置、生命周期、依赖注入bean的操作
- 采用Spring管理Bean和依赖注入
- 使用XPath解析xml实现简单的Spring IOC完成bean的依赖注入
- Spring循环依赖正确性及Bean注入的顺序关系详解
- 【Java.Spring.Core】【IoC】Bean依赖注入- Dependencies
- 一个和spring整合的依赖注入的servlet,子类可自动装配依赖Bean
- 使用dom4j:读取spring配置文件,实例化bean对象并注入依赖对象
- Spring实战2:装配bean—依赖注入的本质
- Spring笔记——模拟spring的bean管理原理以及依赖注入原理
- Spring - 装配Bean:即依赖注入
- spring依赖注入单元测试:expected single matching bean but found 2
- 采用Spring管理Bean和依赖注入
- (7)spring依赖注入引用其它Bean
- 开涛spring3(12.2) - 零配置 之 12.2 注解实现Bean依赖注入
- Spring-2:bean的两种依赖注入方式
- Spring注解开发-属性依赖注入指定名称的bean
- 7.9.1: 容器中Bean的生命周期---依赖关系注入之后的行为
- Spring IOC/BeanFactory/ApplicationContext的工作流程/实现原理/初始化/依赖注入源码详解