简体   繁体   中英

How to inject a prototype bean in a Spring singleton Controller

I have a FactoryBean for prototype beans like this:

@Component
public class ApplicationConfigurationMergedPropertiesFactoryBean implements SmartFactoryBean<Properties>{

    @Autowired
    protected ApplicationConfigurationInitializer initializer;

    @Override
    public Properties getObject() throws Exception {
        return XXXXXXXXXX;
    }

    @Override
    public Class<?> getObjectType() {
        return Properties.class;
    }

    @Override
    public boolean isSingleton() {
        return false;
    }

    @Override
    public boolean isPrototype() {
        return true;
    }

I would like to autowire it in a Controller and, whenever I try to access a property (via p.get() , have a new prototype instance from ApplicationConfigurationMergedPropertiesFactoryBean.getObject() :

@Controller
@RequestMapping("/home")
public class HomeController {

  @Autowired
  @Qualifier("applicationConfig")
  private Properties p;

  @RequestMapping(method = { RequestMethod.GET, RequestMethod.POST })
  public String home() {
        System.out.println(p.get("something"));
  }

However this never calls getObject(). If I inject the ApplicationContext an access the bean directly, it works, providing a brand new Properties bean:

@Controller
@RequestMapping("/home")
public class HomeController {

    @Autowired
    @Qualifier("applicationConfig")
    private Properties p;

    @Autowired
    private ApplicationContext ac;

    @RequestMapping(method = { RequestMethod.GET, RequestMethod.POST })
    public String home() {
        System.out.println(p.get("something"));  //WRONG!!!!
        System.out.println(ac.getBean("applicationConfig", Properties.class).getProperty("something")); //OK!!!!

How can I achieve that directly with the @Autowired injection?

Inject the factory directly:

@Controller
@RequestMapping("/home")
public class HomeController {

    @Autowired
    @Qualifier("applicationConfig")
    private SmartFactoryBean p;

    @Autowired
    private ApplicationContext ac;

    @RequestMapping(method = { RequestMethod.GET, RequestMethod.POST })
    public String home() {
        System.out.println(p.getObject()); 
   ....
   }

Have you considered making your controller class prototype-scoped as well?

@Controller
@Scope("prototype")
@RequestMapping("/home")
public class HomeController {

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