`

Spring 单例Bean依赖多例Bean时,多例Bean始终是同一个

阅读更多
当单例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与单例模式的区别

    同一个容器中,某个Bean只能创建一个实例,但是如果有多个容器,即使是单例Bean,也一定会创建多个实例。 下面是一个简单的Spring单例Bean的配置文件示例: ```xml &lt;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 In Action-3.2@Scope单例、多例Bean

    Spring Bean创建初始化流程.docx

    在Spring框架中,Bean的创建和初始化是IoC(Inversion of Control)容器的核心功能,这一过程涉及到多个步骤。以下是对Spring Bean创建初始化流程的详细解释: 1. **初始化ApplicationContext**: 开始时,通过`...

    详解Spring 中如何控制2个bean中的初始化顺序

    在 Spring 框架中,控制多个 bean 的初始化顺序是一个常见的问题。本篇文章将详细介绍如何控制 2 个 bean 的初始化顺序,提供了多种实现方式,并分析了每种方式的优缺。 问题场景 在实际开发中,我们经常会遇到...

    spring bean的生命周期

    - **Singleton**:Spring容器中只会存在一个Bean实例,所有对Bean的请求都会返回同一个实例。 - **Prototype**:每次请求都会创建一个新的Bean实例。 - **Request**:在Web应用中,每个HTTP请求都会创建一个Bean...

    Spring Bean重复执行两次(实例被构造两次)问题分析

    如果一个BeanA依赖于另一个BeanB,同时BeanB也依赖于BeanA,那么Spring在处理依赖关系时可能会陷入循环引用,导致两个Bean都实例化两次。 3. **@PostConstruct与初始化回调**:Spring允许我们在Bean初始化后执行...

    spring依赖注入bean

    在 Java 应用中使用 Spring,我们需要创建一个 Spring 上下文(ApplicationContext)来加载 Bean 的定义。这个上下文将负责创建和管理 Bean,以及执行依赖注入。通常,我们可以使用 `ClassPathXmlApplicationContext...

    spring bean循环依赖时序图

    spring bean循环依赖时序图详细的描述了spring的循环依赖关系,帮我们快速了解spring是如何优雅的进行处理的

    Spring bean为什么默认是单例

    这意味着无论有多少次请求获取同一个Bean,Spring容器只会创建一个实例,并且在整个应用生命周期中重复使用这个实例。这种设计决策基于性能和资源管理的考虑。 首先,让我们深入理解Spring Bean的单例模式。当一个...

    spring bean XML配置入门

    在Spring中,一个Bean通常代表应用中的一个对象,这些对象由Spring容器创建、管理并提供给其他组件使用。Spring容器通过XML配置文件或注解来定义Bean及其相互关系。 3. **XML配置文件**: "spring-beans"是Spring...

    spring的bean加载顺序样例项目

    - 当Spring容器启动时,它首先读取配置文件,解析Bean的定义,并创建一个BeanDefinition对象,该对象包含了Bean的所有信息,如类名、属性、依赖等。 - 如果有`@Component`注解的类,Spring会通过组件扫描找到并...

    Spring Bean 加载顺序 .

    这个过程涉及到Bean定义的解析、实例化、初始化等多个步骤。让我们详细探讨Spring Bean加载顺序的各个环节。 1. **配置源解析**: Spring支持多种配置方式,包括XML、Java配置类(@Configuration)、注解(@...

    Spring5.0源码深度解析之SpringBean循环依赖问题解决方案.docx

    Spring5.0源码深度解析之SpringBean循环依赖问题解决方案 Spring5.0源码深度解析之SpringBean循环依赖问题解决方案是指在Spring框架中如何解决Bean的循环依赖问题。在Spring框架中,Bean的循环依赖指的是两个或多个...

    spring中的bean

    这些注解表明类是一个Spring Bean,同时可以配合`@Autowired`进行依赖注入。 ```java @Service public class MyService { @Autowired private MyRepository repository; } ``` 3. **Java配置类**:Spring 3.0引入...

    spring-bean 依赖的cglib jar包

    spring-bean 源码依赖的jar包,用于spring源码部署的时候使用

    Spring定义bean的三种方式和自动注入

    在配置类上使用`@Configuration`注解,然后使用`@Bean`注解来定义方法,该方法返回的对象会被Spring容器注册为一个Bean。 ```java @Configuration public class AppConfig { @Bean public Teacher teacher() {...

    Spring实例化Bean顺序

    在Spring框架中,Bean的实例化顺序是一个关键概念,它涉及到如何管理和协调多个Bean的创建与依赖关系。这里,我们主要探讨的是Spring如何通过其IoC(Inversion of Control)容器来实例化Bean,并理解其背后的逻辑。 ...

    Spring的Bean配置说明

    - **功能概述**:`&lt;beans&gt;`是Spring配置文件的根元素,用来包含一个或多个`&lt;bean&gt;`元素,用于定义Spring容器管理的各种Bean。 #### 二、`&lt;bean&gt;`元素详解 - **基础配置**: - **`class`属性**:表示JavaBean的全...

    spring bean life cycle

    1. **实例化**:Spring容器在遇到一个Bean定义时,会通过反射机制创建Bean实例。如果Bean定义中有`factory-method`属性,那么Spring会调用指定的方法来实例化Bean,而不是使用默认的构造器。 2. **属性注入**:实例...

Global site tag (gtag.js) - Google Analytics