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

时间:2017-08-24 08:44:11

标签: java spring proxy prototype scopes

贝娄是代码。当你运行它并在浏览器中进入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>

1 个答案:

答案 0 :(得分:1)

您的bean PrototypeExample具有SCOPE_PROTOTYPE范围属性。

根据official documentation

  

非单例,bean部署的原型范围导致了   每次请求特定时,都会创建一个新的bean实例   豆是制作的。也就是说,bean被注入另一个bean或你   通过对容器的getBean()方法调用来请求它。作为一个   规则,使用所有有状态bean和单例的原型范围   无状态豆的范围。

如果您需要单身,只需删除@Scope注释或将其设置为singleton(这是默认值)。可用的所有范围都列在here