imarban
imarban

Reputation: 1027

Inject bean at runtime reading properties file

Suppose I have a class MailConsoleService and a class MailSMTPService, both implement the MailService interface. I have a class EmailJob which loads the users from a db and send an email through a MailService instance injected by Spring.

How could I read a properties and determine at runtime which implementation of MailService to inject? The properties could change at any time the app is running, obviously.

I've thought about to create a factory bean which returns the right instance from the spring container to EmailJob but I don't know how to implement this.

Note: All my beans are configured to Singleton scope, so I guess I'll have to change to Prototype EmailJob at least.

Note 2: In the factory bean how could I avoid to read the properties file each time?

Thanks!

Upvotes: 2

Views: 1144

Answers (2)

Naresh Vavilala
Naresh Vavilala

Reputation: 608

You can do something like this:

@Component
public class Factory {

@Autowired
private MailService mailConsoleService;

@Autowired
private MailService mailSmtpService;

@Value("${mailServiceProperty}")
private String mailServiceProperty;

public MailService getMailService() {
    switch (mailServiceProperty) {
    case "CONSOLE":
        return mailConsoleService;

    case "SMTP":
        return mailSmtpService;
    }       
    return null;
}

}

Also, you need to inject properties using PropertyPlaceholderConfigurer

Upvotes: 1

sethu
sethu

Reputation: 8411

I am not sure I fully understood your question. But based on what I understood, if you would like to get a bean at runtime from a properties file and the file could be changed at runtime, then the below is one way of doing this. You need a handle to the app context and get the bean name from the properties file.

The prototype scope has nothing to do with this. If you declare a bean of type prototype it means that you will get a new bean instance everytime you ask the app context for it.

@Component
public class EmailJob {  

    @Autowired
    private ApplicationContext appContext;

    public void sendEmail(){

        MailSender mailSender=(MailSender)appContext.getBean(<get bean name from properties file>);

        // do remaining things
    }


}

Upvotes: 0

Related Questions