在侦听器中读取 Spring 引导属性 [英] Read Spring boot property inside listener
问题描述
我的要求是,我需要在spring boot中启动服务器时初始化一些应用程序资源.为了初始化这些资源,我需要一堆属性.因此,我将这些属性保留在外部属性文件中,并且在 Spring Boot 启动时尝试读取自定义侦听器中的属性.问题是,我无法在侦听器中获得任何属性值.我可以在应用程序启动后阅读它们,没有任何问题.但是,当应用程序启动时,我需要它们在侦听器中.我遇到了以下例外情况......如何解决它.请帮帮我!
My requirement is, I need to initialize some application resources when server is started in spring boot. In order to initialize those resources, I need bunch of properties. So, I have kept those properties in external property file and I am trying to read the properties in my custom listener when spring boot is started. The problem is, I could not get any property values in the listener. I am able to read them after application started without any issues. But, I need them inside listener while application is starting. I am getting below exceptions...How to resolve it. help me pls!
2015-08-20 02:58:59.585 ERROR 9376 --- [ost-startStop-1] o.a.c.c.C.[.[localhost].[/shared] : Exception sending context initialized ev
ent to listener instance of class com.org.man.api.initializer.PropertyInitializerListener
java.lang.NoSuchMethodError: com.org.man.api.beans.property.ConfigProperties.getConfigNames()Ljava/util/List;
at com.org.man.api.beans.property.PropertyBeanParser.initializeConfigProperties(PropertyBeanParser.java:33)
at com.org.man.api.initializer.J2eeInitializer.getJ2eePresets(J2eeInitializer.java:79)
at com.org.man.api.initializer.J2eeInitializer.initialize(J2eeInitializer.java:36)
at com.org.man.api.initializer.PropertyInitializerListener.contextInitialized(PropertyInitializerListener.java:81)
at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4727)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5167)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1409)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1399)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
2015-08-20 02:58:59.592 ERROR 9376 --- [ost-startStop-1] o.apache.catalina.core.StandardContext : One or more listeners failed to start. F
ull details will be found in the appropriate container log file
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.web.servlet.HandlerMapping]: Fac
tory method 'viewControllerHandlerMapping' threw exception; nested exception is java.lang.IllegalStateException: The resources may not be ac
cessed if they are not currently started
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:189)
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:588)
... 23 common frames omitted
Caused by: java.lang.IllegalStateException: The resources may not be accessed if they are not currently started
at org.apache.catalina.webresources.StandardRoot.validate(StandardRoot.java:245)
at org.apache.catalina.webresources.StandardRoot.getResource(StandardRoot.java:212)
监听器代码
public class PropertyInitializerListener implements ServletContextListener {
private static final String INITIALIZED = PropertyInitializerListener.class.getName() + ".INITIALIZED";
private J2eeInitializer initializer;
@Autowired
PropertyBeanParser parser;
public void contextDestroyed(ServletContextEvent event) {
if (initializer != null) {
initializer.terminate();
}
ServletContext context = event.getServletContext();
context.removeAttribute(FileSearcher.CONFIG_FILE_PROP);
}
public void contextInitialized(ServletContextEvent event) {
ServletContext context = event.getServletContext();
if (context.getAttribute(INITIALIZED) != null) {
throw new IllegalStateException(
"Already initialized - " +
"check whether you have multiple <listener> definitions in your web.xml!");
}
ConfigBean presets = super.getPresets();
presets = parser.initializeConfigProperties();
SmapiDebug.setSaveMode(true);
SmapiDebug.info("contextInitialized");
PropertyBeanparser 代码
@Configuration
@EnableConfigurationProperties({ConfigProperties.class,LoggingProperties.class,
InstrumentationProperties.class,KeyeventProperties.class})
public class PropertyBeanParser {
@Autowired
private ConfigProperties configProperties;
@Autowired
private LoggingProperties loggingProperties;
@Autowired
private InstrumentationProperties instrumentationProperties;
@Autowired
private KeyeventProperties keyeventProperties;
public ConfigBean initializeConfigProperties(){
ConfigBean configBean = new ConfigBean();
try{
if(configProperties.getConfigNames()!=null && configProperties.getConfigValues()!=null) {
if(configProperties.getConfigNames().size()==configProperties.getConfigValues().size()){
for(int i=0;i<=configProperties.getConfigNames().size();i++){
ConfigVarDefinitionBean var = new ConfigVarDefinitionBean(configProperties.getConfigNames().get(i),
configProperties.getConfigValues().get(i));
configBean.addConfigVarDefinition(var);
}
}
else{
throw new Exception("number of names and values are not matching");
}
}
}
catch(Exception e){
e.getMessage();
}
return configBean;
}
}
ConfigProperties 类
@Configuration
@ConfigurationProperties(locations = "file:config.properties", prefix = "config")
public class ConfigProperties {
private List<String> configNames = new ArrayList<String>();
private List<String> configValues = new ArrayList<String>();
public List<String> getConfigNames() {
return configNames;
}
public void setConfigNames(List<String> configNames) {
this.configNames = configNames;
}
public List<String> getConfigValues() {
return configValues;
}
public void setConfigValues(List<String> configValues) {
this.configValues = configValues;
}
}
配置属性
config.configNames[0]=test1
config.configNames[1]=Testserver
config.configNames[2]=ResourceId
config.configNames[3]=AdaptorName
config.configNames[4]=runLevel
config.configValues[0]=ServiceComp
config.configValues[1]=Test
config.configValues[2]=instance2
config.configValues[3]=test
config.configValues[4]=localhost
推荐答案
问题是,在 Spring Boot 启动期间无法在侦听器中检索属性.因此,为了在启动时做一些初始化,我们可以通过实现 CommandLineRunner 在设置@SpringBootApplication 注解的类中添加 run 方法.如果你这样做,run 方法将在完成 SpringApplication 的 run 方法之前执行.这是我尝试的方法.
The issue is, properties can't be retrieved inside listener during spring boot start up. So, in order to do some initialization in the start up, we can add run method in the class where @SpringBootApplication annotation is set by implementing CommandLineRunner . If you do so, that run method will be executed just before finishing the SpringApplication's run method.This is how I tried.
@SpringBootApplication
public class SpringResource implements CommandLineRunner {
/**
* @param args
*/
@Autowired
PropertyTest test;
public void run(String... args){
test.print();
}
public static void main(String[] args) throws Exception {
SpringApplication.run(SpringResource.class, args);
}
}
PropertyTest 类
@Configuration
@EnableConfigurationProperties({ConfigProperties.class})
@Controller
public class PropertyTest {
@Autowired
ConfigProperties config;
@RequestMapping(value = "/dummy", method = RequestMethod.GET)
@ResponseBody
public void print() {
// TODO Auto-generated method stub
for(int i=0;i<config.getConfigNames().size();i++)
System.out.println("Im in Property test method. :)" +config.getConfigNames().get(i)+" "+config.getConfigValues().get(i));
}
}
这篇关于在侦听器中读取 Spring 引导属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!