作为依赖的 Scope Bean
原文地址:https://springdoc.cn/spring/core.html#beans-factory-scopes-other-injection
这里的文章涉及了Bean的生存周期(scope)的问题,简单介绍了将短周期(session)的bean注入到长周期(singleton)的bean中出现的问题以及解决方案。
原文的翻译略显生硬,花了一定时间进行理解。
<bean id="userPreferences" class="com.something.UserPreferences" scope="session"/>
<bean id="userManager" class="com.something.UserManager">
<property name="userPreferences" ref="userPreferences"/>
</bean>
上面这段代码,将userPreferences注入到了userManager中,预期目标是每个userManager可以操纵不同的userPreferences,但是由于session被注入到了singleton中,每个singleton的userManager只会拥有一个userPreferences,也就是说每个userManager可以操纵的都是相同的userPreferences
解决方案是使用<aop:scoped-proxy/>对需要注入的短生命周期的userPreferences进行代理,如下:
<bean id="userPreferences" class="com.something.UserPreferences" scope="session">
<aop:scoped-proxy/>
</bean>
<bean id="userManager" class="com.something.UserManager">
<property name="userPreferences" ref="userPreferences"/>
</bean>
如此进行代理以后,userPreferences注入到了userManager中实际上注入了一个userPrefferences的代理,也就是每次usermManager操纵的都是不同的,基于userPreferences的代理。
也就因此实现了预期目标:每个userManager可以操纵不同的userPreferences。
还需注意:
默认情况下,当Spring容器为一个用 <aop:scoped-proxy/> 元素标记的bean创建代理时,会创建一个基于CGLIB(Code Generation Library)的类代理。
CGLIB代理只拦截public方法的调用!不要在这样的代理上调用非public的方法。它们不会被委托给实际scope内的目标对象。