我试图在上下文启动之前找到一种方法来记录我的应用程序属性(通过@ConfigurationProperties注入我的bean),这样我就可以在初始化所有bean之前看到确切的属性。< / p>
我试图在ApplicationEnvironmentPreparedEvent上创建一个Listener,但是没有办法检索所有定义的属性,而不是一次检索一个属性。
有一种简单的方法吗?有些方法首先初始化Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
BackgroundWorker1.RunWorkerAsync()
End Sub
Private Sub BackgroundWorker1_DoWork(sender As Object, e As DoWorkEventArgs) Handles BackgroundWorker1.DoWork
While True
System.Threading.Thread.Sleep(250)
Dim selection As String = Me.Invoke(Function()
If Not IsNothing(ComboBox1.SelectedItem) Then
Return ComboBox1.SelectedItem.ToString
Else
Return String.Empty
End If
End Function).ToString
If selection = "1" Then
Me.Invoke(Sub()
Label1.Text = ComboBox1.SelectedItem.ToString
End Sub)
Else
Me.Invoke(Sub()
Label1.Text = "something else"
End Sub)
End If
End While
End Sub
并记录其内容,或者在创建上下文之前检索所有应用程序启动属性?
答案 0 :(得分:5)
您可以在实现ApplicationListener的自定义类的帮助下简单地查看应用程序属性,并将其定义为spring-factories条目中的启动类之一,以便它们在应用程序加载之前执行。步骤如下: -
a)在资源类路径中创建一个名为spring.factories的文件,即带有内容的src \ main \ resources \ META-INF \ spring.factories -
# Application Listeners
org.springframework.context.ApplicationListener=demo.CustomConfigListener
b)在你的项目中创建一个自定义监听器类,就像这里的CustomConfigListener
一样package demo;
import org.springframework.boot.context.event.ApplicationEnvironmentPreparedEvent;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.core.env.EnumerablePropertySource;
import org.springframework.core.env.PropertySource;
public class CustomConfigListener implements ApplicationListener<ApplicationEvent> {
@Override
public void onApplicationEvent(ApplicationEvent event) {
if (event instanceof ApplicationEnvironmentPreparedEvent) {
for(PropertySource<?> source : ((ApplicationEnvironmentPreparedEvent) event).getEnvironment().getPropertySources()){
if(source.getName().equals("applicationConfigurationProperties")){
if (source instanceof EnumerablePropertySource) {
for(String name : ((EnumerablePropertySource) source).getPropertyNames()){
System.out.println(name+" :: "+ ((EnumerablePropertySource) source).getProperty(name));
}
}
}
}
}
}
}
c)您的自定义ConfigurationProperties类
package demo;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@Component
@ConfigurationProperties(ignoreUnknownFields = false, prefix = "mail")
public class MailProperties {
private String host;
private int port;
private Smtp smtp;
//Getters & Setters
public static class Smtp {
private boolean auth;
private boolean starttlsEnable;
//Getters & Setters
}
}
d)最后你的application.properties
mail.host=localhost
mail.port=25
mail.smtp.auth=false
mail.smtp.starttls-enable=false
答案 1 :(得分:3)
作为@Avis回答的后续内容,我意识到该片段不包含任何命令行参数等,所以我稍微更新了他的概念。我正在附加我的记录器类,以防它对将来登陆这个问题的任何人都有价值。
import schedule
import datetime
import time
# Obtain current time
start = datetime.datetime.now()
# Simple callable for example
class DummyClock:
def __call__(self):
print datetime.datetime.now()
schedule.every(1).seconds.do(DummyClock())
while True:
schedule.run_pending()
# 5 minutes == 300 seconds
if (datetime.datetime.now() - start).seconds >= 300:
break
# And here we halt execution for a second
time.sleep(1)
监听器在SpringApplication主类中初始化:
public class ConfigurationLogger implements ApplicationListener<ApplicationEvent> {
// slf4j logger
private static final Logger logger = LoggerFactory.getLogger(ConfigurationLogger.class);
// used to sanitize any password sensitive keys (copied from Spring Boot's Sanitizer() class
private Sanitizer sanitizer = new Sanitizer();
// store the config keys in a sorted map
private Map<String, Object> configurationProperties = new TreeMap<>();
/**
* Trigger upon all events during startup. Both ApplicatoinEnvironmentPrepareEvent and
* ApplicationPreparedEvent need access to the same configurationProperties object. Could
* have done this through separate events, both extending an abstract base class with a static
* hash map, but not worth the effort. Instead have the same class listen for all events, and
* delegate to the appropriate method.
*/
@Override
public void onApplicationEvent(ApplicationEvent event) {
if (event instanceof ApplicationEnvironmentPreparedEvent) {
// store the values
onApplicationEnvironmentPreparedEvent((ApplicationEnvironmentPreparedEvent) event);
}else if( event instanceof ApplicationPreparedEvent){
// display the values
logConfigurationProperties( (ApplicationPreparedEvent)event);
}
}
/**
* Store the properties in the hash map for logging once all property sources have been read
*
* @param event
*/
private void onApplicationEnvironmentPreparedEvent(ApplicationEnvironmentPreparedEvent event) {
for (PropertySource<?> source : event.getEnvironment().getPropertySources()) {
if (source instanceof EnumerablePropertySource) {
for (String key : ((EnumerablePropertySource) source).getPropertyNames()) {
Object value = ((EnumerablePropertySource) source).getProperty(key);
if (!configurationProperties.containsKey(key)) {
configurationProperties.put(key, sanitizer.sanitize(key, value));
}
}
}
}
}
/**
* Print all the config properties to the logger
*/
private void logConfigurationProperties( ApplicationPreparedEvent event) {
logger.debug("Application started with following parameters: ");
for( Map.Entry<String, Object> entry : configurationProperties.entrySet()){
logger.debug("{} :: {}", entry.getKey(), entry.getValue());
}
}
}