当单例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
分享到:
相关推荐
同一个容器中,某个Bean只能创建一个实例,但是如果有多个容器,即使是单例Bean,也一定会创建多个实例。 下面是一个简单的Spring单例Bean的配置文件示例: ```xml <bean id="yiifaa" class=...
标准只有一个:当对象含有可改变的状态时(更精确的说就是在实际应用中该状态会改变),则多例,否则单例。例如,在Struts2中,action必须用多例,因为action本身含有请求参数的值,即可改变的状态。而在Struts1中,...
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的创建和初始化是IoC(Inversion of Control)容器的核心功能,这一过程涉及到多个步骤。以下是对Spring Bean创建初始化流程的详细解释: 1. **初始化ApplicationContext**: 开始时,通过`...
在 Spring 框架中,控制多个 bean 的初始化顺序是一个常见的问题。本篇文章将详细介绍如何控制 2 个 bean 的初始化顺序,提供了多种实现方式,并分析了每种方式的优缺。 问题场景 在实际开发中,我们经常会遇到...
- **Singleton**:Spring容器中只会存在一个Bean实例,所有对Bean的请求都会返回同一个实例。 - **Prototype**:每次请求都会创建一个新的Bean实例。 - **Request**:在Web应用中,每个HTTP请求都会创建一个Bean...
如果一个BeanA依赖于另一个BeanB,同时BeanB也依赖于BeanA,那么Spring在处理依赖关系时可能会陷入循环引用,导致两个Bean都实例化两次。 3. **@PostConstruct与初始化回调**:Spring允许我们在Bean初始化后执行...
在 Java 应用中使用 Spring,我们需要创建一个 Spring 上下文(ApplicationContext)来加载 Bean 的定义。这个上下文将负责创建和管理 Bean,以及执行依赖注入。通常,我们可以使用 `ClassPathXmlApplicationContext...
spring bean循环依赖时序图详细的描述了spring的循环依赖关系,帮我们快速了解spring是如何优雅的进行处理的
这意味着无论有多少次请求获取同一个Bean,Spring容器只会创建一个实例,并且在整个应用生命周期中重复使用这个实例。这种设计决策基于性能和资源管理的考虑。 首先,让我们深入理解Spring Bean的单例模式。当一个...
在Spring中,一个Bean通常代表应用中的一个对象,这些对象由Spring容器创建、管理并提供给其他组件使用。Spring容器通过XML配置文件或注解来定义Bean及其相互关系。 3. **XML配置文件**: "spring-beans"是Spring...
- 当Spring容器启动时,它首先读取配置文件,解析Bean的定义,并创建一个BeanDefinition对象,该对象包含了Bean的所有信息,如类名、属性、依赖等。 - 如果有`@Component`注解的类,Spring会通过组件扫描找到并...
这个过程涉及到Bean定义的解析、实例化、初始化等多个步骤。让我们详细探讨Spring Bean加载顺序的各个环节。 1. **配置源解析**: Spring支持多种配置方式,包括XML、Java配置类(@Configuration)、注解(@...
Spring5.0源码深度解析之SpringBean循环依赖问题解决方案 Spring5.0源码深度解析之SpringBean循环依赖问题解决方案是指在Spring框架中如何解决Bean的循环依赖问题。在Spring框架中,Bean的循环依赖指的是两个或多个...
这些注解表明类是一个Spring Bean,同时可以配合`@Autowired`进行依赖注入。 ```java @Service public class MyService { @Autowired private MyRepository repository; } ``` 3. **Java配置类**:Spring 3.0引入...
spring-bean 源码依赖的jar包,用于spring源码部署的时候使用
在配置类上使用`@Configuration`注解,然后使用`@Bean`注解来定义方法,该方法返回的对象会被Spring容器注册为一个Bean。 ```java @Configuration public class AppConfig { @Bean public Teacher teacher() {...
在Spring框架中,Bean的实例化顺序是一个关键概念,它涉及到如何管理和协调多个Bean的创建与依赖关系。这里,我们主要探讨的是Spring如何通过其IoC(Inversion of Control)容器来实例化Bean,并理解其背后的逻辑。 ...
- **功能概述**:`<beans>`是Spring配置文件的根元素,用来包含一个或多个`<bean>`元素,用于定义Spring容器管理的各种Bean。 #### 二、`<bean>`元素详解 - **基础配置**: - **`class`属性**:表示JavaBean的全...
1. **实例化**:Spring容器在遇到一个Bean定义时,会通过反射机制创建Bean实例。如果Bean定义中有`factory-method`属性,那么Spring会调用指定的方法来实例化Bean,而不是使用默认的构造器。 2. **属性注入**:实例...