简体   繁体   中英

Spring - Dynamic Prototype Beans

I want to create Spring Prototype beans on the fly (which contain @Injects) and am not seeing how to do this. A simple example:

@Named
public class Foo{
    public void someMethod(){
        for(int x=0; x < 10; x++){
            MyObject obj = new MyObject(); // How would this work with Prototype
            obj.setSomeField("Hello");
        }
    }
}

@Named
@Scope("prototype")
public class MyObject{
  @Inject
  SomeDependency blah;

  public void setSomeField(String word){}
}

If I modified class Foo to look like the following, I would not be guaranteed a new instance:

@Named
public class Foo{
    @Inject MyObject obj;

    public void someMethod(){
        for(int x=0; x < 10; x++){
            obj.setSomeField("Hello");
        }
    }
}

If I make a Configuration class it also seems to stay as a Singleton

public class Configuration {

    @Bean
    public MyObject getMyObject(){
        return new MyObject();
    }
}

@Named
public class Foo{
    @Inject Configuration config;

    public void someMethod(){
        for(int x=0; x < 10; x++){
            MyObject obj = config.getMyObject();
            obj.setSomeField("Hello");
        }
    }
}

Am I missing something here?

UPDATE

I ended up making a hybrid of everything mentioned.

I marked the non-singletons with @Named and @Scope("prototype"), and I called them using a generic method:

@Named
public MyFileFactory implements ApplicationContextAware{
    private ApplicationContext context;

    @Override
    public void setApplicationContext(ApplicationContext ac) throws BeansException {
        context = ac;
    }

    public <T> T getNewInstance(final Class<T> type) {
       return context.getBean(type);
    }
}

Ex:

@Named
public class SomeClass{
    @Inject
    private MyFileFactory myFileFactory;

    public void foo(){
        final MyObject myObject = myFileFactory.getNewInstance(MyObject.class);
    }
}   

I would use a 'factory' to create instances of MyObject .

@Named
public class MyObjectFactory {
    public MyObject newInstance() {
        return new MyObject();
    }
}

Then, I would have this factory @Inject 'ed into my Foo object. There, whenever I needed one, I could ask for a new instance.

If you want the new instance to be configured via beans from Spring, you might have to have them injected into the Factory, and set on the object before being returned. Something like this:

@Named
public class MyObjectFactory {
    @Inject
    private MyOtherObject otherObject;

    public MyObject newInstance() {
        return new MyObject(otherObject);
    }
}

Maybe the @Configurable annotation is what you are looking for: documentation

@Configurable
public class MyObject {
   // ...
}

If you instantiate objects with the @Configurable annotation spring will perform dependency injection on these objects.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM