2017-08-24 70 views
1

Bellow是代碼。當你運行它並在瀏覽器中進入localhost:8080/hello時,你會看到序列「1,2」,「2,3」...,因爲Spring CGLIB代理(實際上插入到原型字段中)創建了新的bean在每個方法調用。Spring代碼單元bean在代理時在每個方法調用上創建新的實例/ bean

我覺得bean原型應該每個HTTP調用創建只有一次這樣的輸出應該是「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

您有原型範圍,它的行爲與它應該完全相同:通過在每個請求上創建新的bean。嘗試刪除代理或使用不同的範圍。 –

回答

1

你的bean PrototypeExampleSCOPE_PROTOTYPE scope屬性。

按照official documentation

非單身,在每一個爲特定 豆的請求時的時間 創建一個新的bean實例的豆部署結果的原型範圍。也就是說,這個bean被注入到另一個bean中,或者你通過容器上的getBean()方法調用來請求它。作爲 規則,使用所有有狀態bean的原型範圍和無狀態bean的單例 範圍。

如果你需要一個單身,只是刪除@Scope註解或將其設置爲singleton(這是默認的)。所有可用的示波器都列出了here