当单例Bean依赖多例Bean时,单例Bean只有一次初始化的机会,它的依赖关系只有在初始化阶段被设置,而它所依赖的多例Bean会不断更新产生新的Bean实例,这将导致单例Bean所依赖的多例Bean得不到更新,每次都得到的是最开始时生成的Bean,这就违背了使用多例的初衷。
解决该问题有两种解决思路:
1.放弃依赖注入:主动向容器获取多例,可以实现ApplicationContextAware接口来获取ApplicationContext实例,通过ApplicationContext获取多例对象。
2.利用方法注入:方法注入是让Spring容器重写Bean中的抽象方法,该方法返回多例,Spring通过CGLIb修改客户端的二进制代码来实现。
没有使用方法注入时:
使用方法注入时:
解决该问题有两种解决思路:
1.放弃依赖注入:主动向容器获取多例,可以实现ApplicationContextAware接口来获取ApplicationContext实例,通过ApplicationContext获取多例对象。
2.利用方法注入:方法注入是让Spring容器重写Bean中的抽象方法,该方法返回多例,Spring通过CGLIb修改客户端的二进制代码来实现。
没有使用方法注入时:
- @Controller
- public class MyController {
- @Autowired
- public UserService userService;
- @RequestMapping("/showView")
- public String showView(HttpServletRequest request) {
- userService.deleteUser("1");
- request.setAttribute("name", "张三");
- return "showView";
- }
- }
- public class UnitServiceImpl implements UnitService {
- }
- public class UserServiceImpl implements UserService {
- private UnitService unitService;
- public void setUnitService(UnitService unitService) {
- this.unitService = unitService;
- }
- public void deleteUser(String id) {
- System.out.println(unitService);
- }
- }
- <bean id="unitService"
- class="com.it.springbiz.user.service.impl.UnitServiceImpl" scope="prototype">
- </bean>
- <bean id="userService"
- class="com.it.springbiz.user.service.impl.UserServiceImpl">
- <property name="unitService" ref="unitService"></property>
- </bean>
- 两次请求http://localhost:8080/springWeb/showView.action,得到的内存地址是一样的。
- com.it.springbiz.user.service.impl.UnitServiceImpl@7a4076
- com.it.springbiz.user.service.impl.UnitServiceImpl@7a4076
使用方法注入时:
- @Controller
- public class MyController {
- @Autowired
- public UserService userService;
- @RequestMapping("/showView")
- public String showView(HttpServletRequest request) {
- userService.deleteUser("1");
- request.setAttribute("name", "张三");
- return "showView";
- }
- }
- public class UnitServiceImpl implements UnitService {
- }
- public abstract class UserServiceImpl implements UserService {
- // 此方法由Spring来实现,每次调用返回最新的UnitService
- public abstract UnitService getUnitService();
- public void deleteUser(String id) {
- UnitService unitService=getUnitService();
- System.out.println(unitService);
- }
- }
- <bean id="unitService"
- class="com.it.springbiz.user.service.impl.UnitServiceImpl" scope="prototype">
- </bean>
- <bean id="userService"
- class="com.it.springbiz.user.service.impl.UserServiceImpl">
- <lookup-method name="getUnitService" bean="unitService"></lookup-method>
- </bean>
- 两次请求http://localhost:8080/springWeb/showView.action,得到的内存地址是一样的。
- com.it.springbiz.user.service.impl.UnitServiceImpl@7a4076
- com.it.springbiz.user.service.impl.UnitServiceImpl@7a4076