如果你打算将一个Http request范围的bean注入到另一个bean中,那么需要注入一个AOP代理来替代被注入的作用域bean。也就是说,你需要注入一个代理对象,该对象具有与被代理对象一样的公共接口,而容器则可以足够智能的从相关作用域中(比如一个HTTP request)获取到真实的目标对象,并把方法调用委派给实际的对象。
1.如何做:
<!-- a HTTP Session-scoped bean exposed as a proxy -->
<bean id="userPreferences" class="com.foo.UserPreferences" scope="session">
<!-- this next element effects the proxying of the surrounding bean -->
[u]<aop:scoped-proxy/>[/u]
</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>
注意
<aop:scoped-proxy/>不能和作用域为singleton或prototype的bean一起使用。为singleton bean创建一个scoped proxy将抛出BeanCreationException异常
2.为何做:
下面我们从去掉<aop:scoped-proxy/>元素的XML配置开始说起:
<bean id="userPreferences" class="com.foo.UserPreferences" scope="session"/>
<bean id="userManager" class="com.foo.UserManager">
<property name="userPreferences" ref="userPreferences"/>
</bean>
从上述配置中可以很明显的看到singleton bean userManager被注入了一个指向HTTP Session作用域bean userPreferences的引用。singleton userManager bean会被容器仅实例化一次,并且其依赖(userPreferences bean)也仅被注入一次。这意味着,userManager在理论上只会操作同一个userPreferences对象,即原先被注入的那个bean。而注入一个HTTP Session作用域的bean作为依赖,有违我们的初衷。因为我们想要的只是一个userManager对象,在它进入一个HTTP Session生命周期时,我们希望去使用一个HTTP Session的userPreferences对象。
当注入某种类型对象时,该对象实现了和UserPreferences类一样的公共接口(即UserPreferences实例)。并且不论我们底层选择了何种作用域机制(HTTP request、Session等等),容器都会足够智能的获取到真正的UserPreferences对象,因此我们需要将该对象的代理注入到userManager bean中, 而userManager bean并不会意识到它所持有的是一个指向UserPreferences引用的代理。在本例中,当UserManager实例调用了一个使用UserPreferences对象的方法时,实际调用的是代理对象的方法。随后代理对象会从HTTP Session获取真正的UserPreferences对象,并将方法调用委派给获取到的实际的UserPreferences对象。
这就是为什么当你将request、session以及globalSession作用域bean注入到协作对象中时需要如下正确而完整的配置:
<bean id="userPreferences" class="com.foo.UserPreferences" scope="session">
[u]<aop:scoped-proxy/>[/u]
</bean>
<bean id="userManager" class="com.foo.UserManager">
<property name="userPreferences" ref="userPreferences"/>
</bean>
分享到:
相关推荐
主要介绍了Spring实战之Bean的作用域request用法,结合实例形式分析了spring中Bean的request作用域相关使用技巧与操作注意事项,需要的朋友可以参考下
单例模式,在整个spring IOC容器中,单例模式作用域的Bean都将只生成一个实例。一般Spring容器默认Bean的作用域为singleton 2>prototype: 与singleton相反, 每次通过容器的getBean()方法获取该作用域下的Bean时都...
讲解了spring的6种作用域:singleton(单例)、non-singleton(也称 prototype),Spring2.0以后,增加了session、request、global session三种专用于Web应用程序上下文的Bean
13.5.3. 重定向(Rediret)到另一个视图 13.5.3.1. RedirectView 13.5.3.2. redirect:前缀 13.5.3.3. forward:前缀 13.6. 本地化解析器 13.6.1. AcceptHeaderLocaleResolver 13.6.2. CookieLocaleResolver 13.6.3. ...
首先定义一个简单的类 import lombok.Getter; import lombok.Setter; @Getter @Setter public class HelloMessageGenerator { private String message; @Override public String toString() { return getClass...
如果它们在SQL映射文件中定义过,则将它们动态定义为一个Spring Bean, 这样,我们在Service中就可以直接注入映射接口的bean 意思就是可以直接ref="dao类名",给你自动注册好了 2.7 写mybatis的配置文件,一个...
不用spring异常通知,另一种处理异常 96 4.2.2.2Aop注解形式(了解) 99 注解注入拓展: 103 5 Spring数据库 106 5.1 Spring+JDBC 106 5.1.1 Jdbc编程特点 106 5.1.2引入DataSource 106 5.1.3 核心类JdbcTemplate ...
系统Web层将来切换到另一种实现技术的可能性也微乎其微,所以笔者觉得没有必要为了这个业务层完全独立于调用层的过高目标而去搞一个额外的隔离层,浪费了原材料不说,还将系统搞得过于复杂,相比于其它原则,"简单...
spring框架技术+第2天+xmind思维导图:生命周期,介绍simple project,打印出构造方法...bean作用域request session globalSession:web项目获取核心配置文件要配置两个地方:spring监听器、spring作用域范围的监听。
Spring5 是一个重要的版本,距离SpringFramework4差不多四年。在此期间,大多数增强都是在 SpringBoot 项目中完成的。在本文中,我们将很快了解到Spring5发行版中的一些令人兴奋的特性。 1. 基准升级 要构建和运行...
基于 Spring 的 Web 应用程序接收到 http://localhost:8080/hello.do(事实上请求路径是 /hello.do) 的请求后, Spring 将这个请求交给一个名为 helloController 的程序进行处理, helloController 再调用 一个名为 ...
详细介绍了Spring Boot最常用的30个注解,包含概念、原理、示例 Spring Boot最常用的30个注解 一、 @SpringBootApplication 二、 Spring Bean 相关 1 @Controller 2 @Service 3 @Repository 4 @Component 5 @Bean 6 ...
<param-value>/WEB-INF/spring/*.bean.xml org.springframework.web.context.ContextLoaderListener <listener> <listener-class>org.springframework.web.context.request....
Getting started with Spring Framework is a hands-on guide to begin developing applications using Spring Framework. This book is meant for Java developers with little or no knowledge of Spring ...
那么spring的bean的默认scope为singleton,对于controller来说每次方法中均可以获得request还是比较有意思的。 对于方法参数上的request通过构建方法的参数可以获得最新的request public final Object ...
设置一个自定义的AuthenticationEntryPoint 64 6.4方法安全 64 6.4.1 元素 65 使用protect-pointcut添加安全性切入点 66 6.5默认AccessDecisionManager 67 6.5.1自定义AccessDecisionManager 67 6.6验证管理器和命名...
singleton:设定创建出的对象保存在spring容器中,是一个单例的对象(bean默认是单例) 单例的对象是在加载spring容器时就创建了,且此后你在同一个bean获取资源时,用getBean()方法得到的对象都是同一个地址值的...
@Bean注解在方法上,声明当前方法的返回值为一个Bean AOP @Aspect 声明是一个切面 拦截规则@After @Before @Around PointCut JoinPoint Spring常用配置 Bean的Scope Singleton ...
请注意,这里面有一个方法名 selectUserByID 必须与 User.xml 里面配置的 select 的id 对应() 重写测试代码 程序代码 程序代码 public static void main(String[] args) { SqlSession session = ...
RequestScope RequestToViewNameTranslator RequestUtils Required RequiredAnnotationBeanPostProcessor Resource ResourceAllocationException ResourceArrayPropertyEditor ResourceBundleEditor ...