2017-08-03 91 views
4

Spring有bean类型/示波器一样
-singleton豆(每个应用程序上下文只有一个豆)
-prototype豆(每个请求一个新的bean)春天 - 一个singleton bean

现在,如果里面的bean原型有是对singleton bean内的prototype bean的引用,有没有办法在每个对singleton bean的请求中获得一个新的prototype bean(它位于singleton bean中)。
如果是,那么配置会是什么样子?

+0

为什么你会需要这个? –

回答

2

在单例bean中注入ApplicationContext并使用getBean方法获取原型。

@Autowired 
private ApplicationContext ctx; 

public void request() { 
    MyProptotypeBean mpb = this.ctx.getBean(MyProptotypeBean.class);//new instance for evety call to the method 
} 
3

没有与这样的查找法的方式:

import org.springframework.beans.factory.annotation.Lookup; 
import org.springframework.beans.factory.config.BeanDefinition; 
import org.springframework.context.ApplicationContext; 
import org.springframework.context.annotation.AnnotationConfigApplicationContext; 
import org.springframework.context.annotation.Bean; 
import org.springframework.context.annotation.ComponentScan; 
import org.springframework.context.annotation.Configuration; 
import org.springframework.context.annotation.Scope; 
import org.springframework.stereotype.Component; 

public final class Main { 

    public static void main(String[] args) { 
     ApplicationContext applicationContext = new AnnotationConfigApplicationContext(Config.class); 
     for (int i = 0; i < 10; i++) { 
      System.out.println(i + ".- call: " + applicationContext.getBean(Singleton.class)); 
     } 
    } 

    @ComponentScan("foo") 
    @Configuration 
    public static class Config { 

    // It's important to define SingletonBase component with @Component annotation and not here, If you define SingletonBase initialization here, It'll not work! 

     @Bean 
     @Scope(BeanDefinition.SCOPE_PROTOTYPE) 
     public Prototype prototype() { 
      return new PrototypeBase(); 
     } 
    } 

    public interface Prototype { 

     public long getInstanceId(); 
    } 

    public interface Singleton { 

     public Prototype getPrototype(); 
    } 

    // It's important define SingletonBase component as this, If you define SingletonBase initialization inside a factory it'll not work! 
    @Component 
    public static class SingletonBase implements Singleton { 

     private static long instanceIdGenerator = 1L; 
     private long instanceId = generateId(); 

     private static synchronized long generateId() { 
      return instanceIdGenerator++; 
     } 

     public SingletonBase() { 
      System.out.println("Singleton initialized!"); 
     } 

     @Override 
     public String toString() { 
      return "SingletonBase{" + "instanceId=" + instanceId + ", prototypeId=" + getPrototype().getInstanceId() + '}'; 
     } 

     @Override 
     @Lookup 
     public Prototype getPrototype() { 
      return null; 
     } 
    } 

    public static class PrototypeBase implements Prototype { 

     private static long instanceIdGenerator = 1L; 
     private long instanceId = generateId(); 

     private static synchronized long generateId() { 
      return instanceIdGenerator++; 
     } 

     public PrototypeBase() { 
      System.out.println("Prototype initialized!"); 
     } 

     public long getInstanceId() { 
      return instanceId; 
     } 
    } 
} 

它打印:

Singleton initialized! 
Prototype initialized! 
0.- call: SingletonBase{instanceId=1, prototypeId=1} 
Prototype initialized! 
1.- call: SingletonBase{instanceId=1, prototypeId=2} 
Prototype initialized! 
2.- call: SingletonBase{instanceId=1, prototypeId=3} 
Prototype initialized! 
3.- call: SingletonBase{instanceId=1, prototypeId=4} 
Prototype initialized! 
4.- call: SingletonBase{instanceId=1, prototypeId=5} 
Prototype initialized! 
5.- call: SingletonBase{instanceId=1, prototypeId=6} 
Prototype initialized! 
6.- call: SingletonBase{instanceId=1, prototypeId=7} 
Prototype initialized! 
7.- call: SingletonBase{instanceId=1, prototypeId=8} 
Prototype initialized! 
8.- call: SingletonBase{instanceId=1, prototypeId=9} 
Prototype initialized! 
9.- call: SingletonBase{instanceId=1, prototypeId=10} 
+0

不错,这比我的回答好。 –