在侦听器中读取 Spring 引导属性 [英] Read Spring boot property inside listener

查看:29
本文介绍了在侦听器中读取 Spring 引导属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的要求是,我需要在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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆