当单例Bean依赖多例Bean时,单例Bean只有一次初始化的机会,它的依赖关系只有在初始化阶段被设置,而它所依赖的多例Bean会不断更新产生新的Bean实例,这将导致单例Bean所依赖的多例Bean得不到更新,每次都得到的是最开始时生成的Bean,这就违背了使用多例的初衷。
解决该问题有两种解决思路:
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
分享到:
相关推荐
主要介绍了浅谈Spring单例Bean与单例模式的区别,具有一定借鉴价值,需要的朋友可以参考下
Spring In Action-3.2@Scope单例、多例Bean,Spring In Action-3.2@Scope单例、多例Bean,Spring In Action-3.2@Scope单例、多例Bean,Spring In Action-3.2@Scope单例、多例Bean
spring bean循环依赖时序图详细的描述了spring的循环依赖关系,帮我们快速了解spring是如何优雅的进行处理的
spring-bean 源码依赖的jar包,用于spring源码部署的时候使用
主要介绍了Spring bean为什么默认是单例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
Spring bean 一般通过配置文件和注解进行加载,如果要实现jar或class文件,动态实现spring bean 的动态加载,并通过UrlClassLoader完成jar和class文件的加载。可以实现jar的热替换。spring的bean动态加载则需要对...
这是在网上下载的例子,平时我们用的ioc都是在web中,本例实现在java application中实现依赖注入
本篇文章主要介绍了Spring 中如何控制2个bean中的初始化顺序,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
spring bean配置 运行环境:eclipse 构建工具:maven 不提供maven构建,maven用来解决jar包的依赖
Spring Bean创建初始化流程
spring 获取bean spring 获取bean spring 获取bean spring 获取bean spring 获取bean spring 获取bean spring 获取bean spring 获取bean
bean加入spring容器管理的方式,bean加入applicationcontext容器的方式
bean文件 springbean文件
spring创建bean简单示例
spring动态向容器中添加bean和删除指定bean,不需要重启应用
spring bean 的生命周期,把运行结果的日志,用sublime打开对比查看,你会有比较清晰的认识
Spring是一个轻量级的控制反转(IoC)和面向切面(AOP)的容器框架,如何在程序中获取Spring配置的bean呢?下面通过本文给大家介绍Java中Spring获取bean方法小结,对spring获取bean方法相关知识感兴趣的朋友一起学习...
Spring 的bean的作用域总结,详细的总结了 Spring 的bean的作用域
Spring IOC和DI概述,Bean的配置形式,IOC容器BeanFactory和ApplicationContext概述,依赖注入的方式,属性注入,构造器注入等案例
一个Spring框架的bean工具,可以在多线程环境下手动创建bean。使用时请注意在spring配置文件下加入<bean id="springBeanUtils" class="com.hujin.common.util.SpringBeanUtils"/>