使用 spring-boot 以编程方式添加另一个属性资源配置器

Posted

技术标签:

【中文标题】使用 spring-boot 以编程方式添加另一个属性资源配置器【英文标题】:Add another PropertyResourceConfigurer programatically with spring-boot 【发布时间】:2014-12-31 09:51:47 【问题描述】:

我们正在使用 gradle、groovy 和 spring-boot 建立一个高级/复杂的多模块构建。

除了使用@EnableAutoConfiguration 自动获取 application*.yml 文件外,我们还想注册一个“自定义”PropertyResourceConfigurer 来处理放置在单独“config”模块中的公共属性,该模块可以在多个 spring-boot 中重用应用。

但是,当在 @Configuration 注释类中添加以下内容时,启动失败并出现异常

@Configuration
class CommonConfig 

    @Autowired
    Environment env;

 @Bean (name = 'geit')
    PropertyResourceConfigurer geitProperties() 
        PropertyResourceConfigurer configurer = new PropertyPlaceholderConfigurer();

        Resource[] resources = new Resource[env.activeProfiles.length];
        println "Environment2 : $env"
        env.activeProfiles.eachWithIndex() 
            env, i -> resources[i] = new UrlResource(getURL(String.format("classpath:environment/%s.properties", env)))
        

        configurer.setLocations(resources)
        return configurer
    


例外是

4fa8a851930816b4d09ecb1/springloaded-1.2.1.RELEASE.jar]
    at org.codehaus.groovy.runtime.NullObject.getProperty(NullObject.java:57)
2014-11-04 14:13:56.975 ERROR 48941 --- [           main] o.s.boot.SpringApplication               : Application startup failed
    at org.codehaus.groovy.runtime.InvokerHelper.getProperty(InvokerHelper.java:168)

    at org.codehaus.groovy.runtime.callsite.NullCallSite.getProperty(NullCallSite.java:44)
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'geit' defined in class path resource [geit/config/CommonConfig.class]: Instantiation of bean failed; nested exception is org.springframework.beans.factory.BeanDefinitionStoreException: Factory method [public org.springframework.beans.factory.config.PropertyResourceConfigurer geit.config.CommonConfig.geitProperties()] threw exception; nested exception is java.lang.NullPointerException: Cannot get property 'activeProfiles' on null object
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callGetProperty(AbstractCallSite.java:227)
    at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:601)
    at geit.config.CommonConfig.geitProperties(CommonConfig.groovy:55)
    at geit.config.CommonConfig$$EnhancerBySpringCGLIB$$c13414af.CGLIB$geitProperties$21(<generated>)
    at geit.config.CommonConfig$$EnhancerBySpringCGLIB$$c13414af$$FastClassBySpringCGLIB$$e7b06e5c.invoke(<generated>)
    at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1113)
    at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:312)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFaat geit.config.CommonConfig$$EnhancerBySpringCGLIB$$c13414af.geitProperties(<generated>)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
ry.java:1008)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:505)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476)
    at org.springsource.loaded.ri.ReflectiveInterceptor.jlrMethodInvoke(ReflectiveInterceptor.java:1270)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:302)
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:166)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:229)
    ... 22 more
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:298)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:198)
    at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:150)
    at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:606)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:462)
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:109)
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:692)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:322)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:962)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:951)
    at org.springframework.boot.SpringApplication$run.call(Unknown Source)
    at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:45)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:108)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:120)
    at geit.AdminApplication.main(AdminApplication.groovy:19)
Caused by: org.springframework.beans.factory.BeanDefinitionStoreException: Factory method [public org.springframework.beans.factory.config.PropertyResourceConfigurer geit.config.CommonConfig.geitProperties()] threw exception; nested exception is java.lang.NullPointerException: Cannot get property 'activeProfiles' on null object
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:188)
    at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:590)
    ... 21 common frames omitted
Caused by: java.lang.NullPointerException: Cannot get property 'activeProfiles' on null object
    at org.codehaus.groovy.runtime.NullObject.getProperty(NullObject.java:57)
    at org.codehaus.groovy.runtime.InvokerHelper.getProperty(InvokerHelper.java:168)
    at org.codehaus.groovy.runtime.callsite.NullCallSite.getProperty(NullCallSite.java:44)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callGetProperty(AbstractCallSite.java:227)
    at geit.config.CommonConfig.geitProperties(CommonConfig.groovy:55)
    at geit.config.CommonConfig$$EnhancerBySpringCGLIB$$c13414af.CGLIB$geitProperties$21(<generated>)
    at geit.config.CommonConfig$$EnhancerBySpringCGLIB$$c13414af$$FastClassBySpringCGLIB$$e7b06e5c.invoke(<generated>)
    at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228)
    at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:312)
    at geit.config.CommonConfig$$EnhancerBySpringCGLIB$$c13414af.geitProperties(<generated>)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.springsource.loaded.ri.ReflectiveInterceptor.jlrMethodInvoke(ReflectiveInterceptor.java:1270)
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.iate(SimpleInstantiationStrategy.java:166)
    ... 22 common frames omitted

但是,在 CommonConfig 中添加以下内容时

 @Bean
    public String profileConfigBean() 

        println "Environment : $env"

        env.activeProfiles.each 
            println it
        

        'devprofilebean'
    

这会正确打印所有活动的配置文件。

即使添加一个空的 PropertyResourceConfigurer 也会导致启动失败

【问题讨论】:

【参考方案1】:

找到一个可行的解决方案。

我为每个环境添加了一个带有 @PropertySource 注释的类,并为默认属性添加了一个。

例子: 一个用于 DEV

@Configuration
@Profile(Profiles.DEV)
@PropertySource("classpath:/environment/dev.properties")
class CommonDevConfig 


还有一个默认的

@Configuration
@PropertySource("classpath:/environment/default.properties")
class CommonConfig 


【讨论】:

以上是关于使用 spring-boot 以编程方式添加另一个属性资源配置器的主要内容,如果未能解决你的问题,请参考以下文章

在 iOS 中以编程方式在另一个文本字段下方添加文本字段

以编程方式将 UILabel 添加到集合单元,快速

在另一个以编程方式创建的视图下方布局视图

基于在 Storyboard 中使用自动布局创建的另一个视图,以编程方式使用框架创建视图

以编程方式添加约束会破坏自动布局约束

以编程方式添加约束以防止按钮重叠 SWIFT 4