spring prototype怎么注入到singleton 里面

本文通过具体示例探讨了Spring框架中如何通过容器而非注解方式来实例化对象,并对比了两种不同方法下实例化结果的差异。

经过测试之后用注解的方式 不行 所以只能采用容器取的方式。例子代码如下


package com.dragon.service.test;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

@Component("testBean")
@Scope("singleton")
public class TestBean {
<span style="white-space:pre">	</span>//@Autowired
<span style="white-space:pre">	</span>//private TestBean1 testBean1;
	public TestBean1 getTestBean1() {
		return (TestBean1) SpringBeanUtils.getBean("testBean1");
	}

}

package com.dragon.service.test;

import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

@Component("testBean1")
@Scope("prototype")
public class TestBean1 {

	private Integer num = 1;

	public Integer getNum() {
		num++;
		return num;
	}

}



package com.dragon.service.test;

import java.util.Map;

import org.slf4j.*;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Service;

@Service
public class SpringBeanUtils implements ApplicationContextAware {

	private static ApplicationContext appContext;
	private Logger logger = LoggerFactory.getLogger(getClass());

	public void setApplicationContext(ApplicationContext applicationContext)
			throws BeansException {
		SpringBeanUtils.appContext = applicationContext;
		logger.debug("初始化Spring上下文成功。");
	}

	/**
	 * 获取 ApplicationContext
	 */
	public static ApplicationContext getApplicationContext() {
		return appContext;
	}

	/**
	 * 获取 TestBean
	 * 
	 * @param beanName
	 *            bean 名称
	 * @return
	 */
	public static Object getBean(String beanName) {
		checkApplicationContext();
		return appContext.getBean(beanName);
	}

	/**
	 * 获取 TestBean
	 * 
	 * @param clazz
	 *            bean 类
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static <T> T getBean(Class<T> clazz) {
		checkApplicationContext();
		Map<?, ?> map = appContext.getBeansOfType(clazz);
		return map.isEmpty() ? null : (T) map.values().iterator().next();
	}

	/**
	 * 检查 ApplicationContext 是否注入
	 */
	private static void checkApplicationContext() {
		if (null == appContext) {
			throw new IllegalStateException("applicaitonContext未注入");
		}
	}

}

测试类如下


package com.dragon.test;

import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;

import com.dragon.service.test.TestBean;

public class TestBeanTest extends BaseTest {
	@Autowired
	private TestBean testBean1;
	@Autowired
	private TestBean testBean2;

	@Test
	public void testAdd() {
		System.out.println(testBean1.getTestBean1().getNum());
		System.out.println(testBean2.getTestBean1().getNum());
	}
}


这样子输出的结果是 2,2  也就说明了 每次取到的testbean1对象都是新的对象

如果testbean里面采用注入的方式 打印的结果是2,3

Spring框架里,SingletonPrototype这两种作用域分别适用于不同的场景。 Singleton作用域指整个应用中只有一个实例,并在第一次请求时创建实例,适用于绝大多数情况,具体如需要一个实例来处理所有任务的场景,像数据库连接,因为它需要全局共享,且性能高、内存占用低,实例被复用,避免了频繁创建和垃圾回收的开销,并且由Spring容器完整管理其生命周期,包括创建、初始化、依赖注入,直到容器关闭时执行销毁逻辑。同时,由于其全局共享的特性,必须是无状态的,不能持有与特定调用者相关的状态数据,否则会引发线程安全问题,它也是Spring的默认作用域 [^1][^3][^4]。 Prototype作用域指每次请求都会创建一个新的实例并返回,每个实例之间相互独立,适用于需要同时处理多个任务的场景。通常该作用域下的Bean是有状态的,每个实例都能安全地保存自己的状态,因为不会被共享。不过其性能和内存开销相对较高,每次都需要创建新对象,若对象复杂,开销会更明显。Spring容器只负责其创建、初始化和注入,将实例交给客户端后,就不再跟踪,也不会调用其销毁方法,且使用时需要用`@Scope("prototype")`显式声明 [^1][^3][^4]。 ### 代码示例 以下是定义一个 Singleton Bean 和一个 Prototype Bean 的示例: ```java import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Scope; @Configuration public class AppConfig { // 定义一个 Singleton Bean @Bean public SingletonBean singletonBean() { return new SingletonBean(); } // 定义一个 Prototype Bean @Bean @Scope("prototype") public PrototypeBean prototypeBean() { return new PrototypeBean(); } } class SingletonBean { // 单例 Bean 的逻辑 } class PrototypeBean { // 原型 Bean 的逻辑 } ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

white......

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值