How to reload configuration bean with properties from database

烂漫一生 提交于 2019-12-11 08:36:56

问题


I need to create a spring javamail bean initialized with values from database for each mail sent. Based on this article, How to Load Application Properties from Database

I've configured my PropertyPlaceholderConfigurer to load values from both properties file and database. I have the following bean(mailSender) in my java configuration class for sending mail from my application which loads host, port, username and password from the database,

@Configuration
public class MailSenderConfig {
    @Bean
    public JavaMailSender mailSender() {
        JavaMailSenderImpl javaMailSender = new JavaMailSenderImpl();
        javaMailSender.setHost(PropertiesUtils.getProperty("mail.server.host"));
        javaMailSender.setPort(Integer.parseInt(PropertiesUtils.getProperty("mail.server.port")));
        javaMailSender.setUsername(PropertiesUtils.getProperty("mail.server.username"));
        javaMailSender.setPassword(PropertiesUtils.getProperty("mail.server.password"));
        return javaMailSender;
    }
}

But my problem is when the database values changes the mailSender bean has the old values which is provided while starting the application context. For any changes to take place to the bean I need to restart the server for updating the bean values.

I inject this bean in my controller where I need to send a mail like this,

@Autowired
private JavaMailSender mailSender;

Based on some suggestion, I tried to use @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) but it din't create a new bean definition(still has old values).

So what I need is, every time a mail is sent using this mailSender bean it should pick the values from database without restarting the context or server. Is it possible or how it can be done?

Any help is appreciated. Thanks.

Similar question: Spring: Refresh a bean created from code reading a database


回答1:


I've create a custom mail service implementation and removed the Mail sender bean as JB Nizet suggested. In the service implementation I'm reading properties from the database and creating a new instance everytime a mail is sent from the application. Like below

@Autowired
private MailSender mailSender;

JavaMailSenderImpl jms = mailService.createMailSender();
MimeMessage mimeMessage = new MimeMessage(mailService.getMailSession(jms));
MimeMessageHelper message = null;
message.setSubject("Test mail");
message.setTo("email@domain.com");
message.setText(htmlContent, true);
Transport.send(message);

where createMailSender() creates a new instance of JavaMailSenderImpl for every mail you send.




回答2:


Try this instead

public class CustomProperties extends Properties {

    private final AppLogger logger = AppLogger.getInstance();
    private static final long serialVersionUID = 1L;
    private static final String GET_QUERY = "select config_value from config_params where config_key = ?";
    private final JdbcTemplate jdbcTemplate;

    public CustomProperties(DataSource dataSource) {
        this.jdbcTemplate = new JdbcTemplate(dataSource);
    }

    @Override
    public String getProperty(String key) {
        return jdbcTemplate.queryForObject(GET_QUERY, new Object[]{key}, String.class);
    }
}


来源:https://stackoverflow.com/questions/43868299/how-to-reload-configuration-bean-with-properties-from-database

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!