2017-08-24 1 views
1

Bellow est le code. Lorsque vous l'exécutez et allez dans le navigateur à localhost: 8080/hello vous verrez les séquences "1,2", "2,3" ..., car le proxy CGLIB Spring (qui est réellement inséré dans le champ prototype) crée un nouveau bean à chaque appel de méthode.Spring bean singleton crée une nouvelle instance/bean sur un chaque appel de méthode lorsqu'il est mandaté

Je pense que le haricot prototype devrait être créé qu'une seule fois par appel http de sorte que la sortie doit être « 1,1 », « 2,2 » ..

je peux résoudre ce avec ObjectFactory, mais je suis perte de proxy avec toutes les capacités de ressort AOP.

Comment cela est-il censé se comporter? Ai-je tort? Est-ce vraiment une limitation du printemps? Peut-il être résolu d'une manière ou d'une autre avec une configuration basée sur Java?

C'est tout le code, vous avez besoin seulement 2 fichiers:

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

Vous avez une portée prototype, et elle se comporte exactement comme il se doit: en créant un nouveau bean sur chaque requête. Essayez de supprimer le proxy ou d'utiliser une portée différente. –

Répondre

1

Votre haricot PrototypeExample a un attribut de portée SCOPE_PROTOTYPE.

Selon le official documentation:

Le non-singleton, la portée prototype des résultats de déploiement de haricots dans la création d'une nouvelle instance de haricots à chaque fois est fait une demande pour que le haricot spécifique. Autrement dit, le bean est injecté dans un autre bean ou vous le demandez via un appel de méthode getBean() sur le conteneur. En tant que règle , utilisez la portée prototype pour tous les beans avec état et l'étendue singleton pour les beans sans état.

Si vous avez besoin d'un singleton, il suffit de supprimer l'annotation @Scope ou le mettre à singleton (ce qui est le défaut). Toutes les étendues disponibles sont répertoriées here.