贝娄是代码。当你运行它并在浏览器中进入localhost:8080 / hello时,你会看到序列“1,2”,“2,3”......,因为Spring CGLIB代理(实际插入到原型字段中)创建了新的bean在每个方法调用上。
我认为每个http调用只应创建一次原型bean,因此输出应为“1,1”,“2,2”..
我可以使用ObjectFactory来解决这个问题,但随后我将失去代理以及所有AOP弹簧功能。
这应该如何表现?我有错吗?这真的是Spring的限制吗?它可以通过基于Java的配置以某种方式解决吗?
这是整个代码,您只需要2个文件:
Application.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();
}
}
的pom.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>
答案 0 :(得分:1)
您的bean PrototypeExample
具有SCOPE_PROTOTYPE
范围属性。
非单例,bean部署的原型范围导致了 每次请求特定时,都会创建一个新的bean实例 豆是制作的。也就是说,bean被注入另一个bean或你 通过对容器的getBean()方法调用来请求它。作为一个 规则,使用所有有状态bean和单例的原型范围 无状态豆的范围。
如果您需要单身,只需删除@Scope
注释或将其设置为singleton
(这是默认值)。可用的所有范围都列在here。