Spring 单例 bean 在代理时在每个方法调用上创建新的实例/bean



Bellow是代码。当你运行它并在浏览器中转到localhost:8080/hello时,你会看到序列"1,2","2,3"...,因为Spring CGLIB代理(实际上插入到原型字段中(在每个方法调用上都会创建新的bean。

我认为每个 http 调用应该只创建一次原型 bean,因此输出应该是"1,1"、"2,2"。

我可以用ObjectFactory解决这个问题,但是我失去了代理以及所有AOP spring功能。

这应该如何表现?我有错吗?这真的是春天的限制吗?可以通过基于 Java 的配置以某种方式解决吗?

这是整个代码,您只需要 2 个文件:

应用.java

@SpringBootApplication
@RestController
public class Application {
@Autowired  //one solution is ObjectFactory<PrototypeExample>
private PrototypeExample prototype;
@GetMapping("/hello")
public String hello() {
return (prototype.getCounter() + ", " + prototype.getCounter());
}
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
@Component
@Scope(value = SCOPE_PROTOTYPE, proxyMode = TARGET_CLASS)
class PrototypeExample {
private static AtomicInteger counter = new AtomicInteger();
public PrototypeExample() {
counter.getAndIncrement();
}
public int getCounter() {
return counter.get();
}
}

绒球.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.neco</groupId>
<artifactId>spring-core_IV</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.3.RELEASE</version>
<relativePath/>
</parent>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
</project>

您的 beanPrototypeExample具有SCOPE_PROTOTYPEscope 属性。

根据官方文件:

Bean 部署的非单例原型范围导致 每次请求该特定 Bean 实例时创建一个新的 Bean 实例 豆子被制成。也就是说,将豆子注入到另一个豆子中或您 通过容器上的 getBean(( 方法调用来请求它。作为一个 规则,对所有有状态 Bean 和单例使用原型作用域 无状态豆类的范围。

如果需要单例,只需删除@Scope注释或将其设置为singleton(这是默认注释(。此处列出了所有可用的范围。

最新更新