问题
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