nacos-spring使⽤时@PropertySource注解不⽣效问题
问题
写了⼀个nacos整合sprig的demo,依赖
<dependencies>
<dependency>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-spring-context</artifactId>
<version>1.0.0</version>
</dependency>
</dependencies>
代码
package com.zby;
import urrent.TimeUnit;
import t.ApplicationContext;
import t.annotation.AnnotationConfigApplicationContext;
import t.annotation.Configuration;
import t.annotation.PropertySource;
import com.alibaba.nacos.api.annotation.NacosProperties;
import com.alibaba.fig.annotation.NacosValue;
import com.alibaba.fig.EnableNacosConfig;
import com.alibaba.fig.NacosPropertySource;
@Configuration
@PropertySource("application.properties")
@EnableNacosConfig(globalProperties = @NacosProperties(serverAddr = "${nacos.server.addr}"))
@NacosPropertySource(dataId = "${nacos.server.dataId}", groupId = "${upId}", autoRefreshed = true, properties = @NacosProperties(namespace = "${nacos.server.namespace}"))
public class Application {
@NacosValue(value = "${key}", autoRefreshed = true)
public String value;
@SuppressWarnings("resource")
public static void main(String[] args) throws Exception {
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(Application.class);
Application bean = Bean(Application.class);
while (true) {
TimeUnit.SECONDS.sleep(1);
System.out.println(bean.value);
}
}
}
本地配置application.properties
nacos.server.addr=127.0.0.1:8848
nacos.server.namespace=dev
upId=zby
nacos.server.dataId=base.properties
nacos创建dev名称空间,创建配置
此时,运⾏main函数,报错:
⼆⽉ 02, 2021 7:59:33 下午 t.annotation.AnnotationConfigApplicationContext prepareRefresh
信息: Refreshing t.annotation.AnnotationConfigApplicationContext@6433a2: startup date [Tue Feb 02 19:59:33 CST 2021]; root of context hierarchy
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See /codes.html#StaticLoggerBinder for further details.
⼆⽉ 02, 2021 7:59:34 下午 org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons
信息: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@39fb3ab6: defining beans [t.annotation.internalConfigurationAnnotationProcessor, ⼆⽉ 02, 2021 7:59:34 下午 t.annotation.AnnotationConfigApplicationContext refresh
警告: Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'application': Injection of @NacosValue dependencies is failed; neste ⼆⽉ 02, 2021 7:59:34 下午 org.springframework.beans.factory.support.DefaultListableBeanFactory destroySingletons
信息: Destroying singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory
@39fb3ab6: defining beans [t.annotation.internalConfigurationAnnotationProcessor,t.ann ⼆⽉ 02, 2021 7:59:34 下午 com.alibaba.fig.NacosValueAnnotationBeanPostProcessor destroy
信息: class com.alibaba.fig.NacosValueAnnotationBeanPostProcessor was destroying!
⼆⽉ 02, 2021 7:59:34 下午 com.alibaba.nacos.spring.beans.factory.annotation.AnnotationNacosInjectedBeanPostProcessor destroy
信息: class com.alibaba.nacos.spring.beans.factory.annotation.AnnotationNacosInjectedBeanPostProcessor was destroying!
Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating
bean with name 'application': Injection of @NacosValue dependencies is failed; nested exception is java.lang.IllegalArgumentException: Could  at com.alibaba.spring.beans.factory.annotation.AbstractAnnotationBeanPostProcessor.postProcessPropertyValues(AbstractAnnotationBeanPostProcessor.java:183)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1148)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:517)
at org.springframework.beans.factory.ateBean(AbstractAutowireCapableBeanFactory.java:456)
at org.springframework.beans.factory.support.Object(AbstractBeanFactory.java:293)
at org.springframework.beans.factory.Singleton(DefaultSingletonBeanRegistry.java:223)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.j
ava:290)
at org.springframework.beans.factory.Bean(AbstractBeanFactory.java:191)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:638)
at t.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:942)
at t.fresh(AbstractApplicationContext.java:482)
at t.annotation.AnnotationConfigApplicationContext.<init>(AnnotationConfigApplicationContext.java:73)
at com.zby.Application.main(Application.java:26)
Caused by: java.lang.IllegalArgumentException: Could not resolve placeholder 'key' in string value "${key}"
at org.springframework.util.PropertyPlaceholderHelper.parseStringValue(PropertyPlaceholderHelper.java:173)
at org.springframework.placePlaceholders(PropertyPlaceholderHelper.java:125)
at nv.AbstractPropertyResolver.doResolvePlaceholders(AbstractPropertyResolver.java:190)
at solveRequiredPlaceholders(AbstractPropertyResolver.java:164)
at t.support.solveStringValue(PropertySourcesPlaceholderConfigurer.java:167)
at org.springframework.beans.factory.solveEmbeddedValue(AbstractBeanFactory.java:764)
at com.alibaba.fig.NacosValueAnnotationBeanPostProcessor.doGetInjectedBean(NacosValueAnnotationBeanPostProcessor.java:108)
at com.alibaba.spring.beans.factory.InjectedObject(AbstractAnnotationBeanPostProcessor.java:409)
at com.alibaba.spring.beans.factory.annotation.AbstractAnnotationBeanPostProcessor$AnnotatedFieldElement.inject(AbstractAnnotationBeanPostProcessor.java:626)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88)
at com.alibaba.spring.beans.factory.annotation.AbstractAnnotationBeanPostProcessor.postProcessPropertyValues(AbstractAnnotationBeanPostProcessor.java:179)
... 12 more
原因nacos-spring-contex:1.0.0依赖的spring是3.x的,3.x时Spring处理@PropertySource注解是等其他注解处理完了,才会把@PropertySource的配置放进enviroment
t.annotation.ConfigurationClassParser.processPropertySource(AnnotationAttributes)
/**
* Process the given <code>@PropertySource</code> annotation metadata.
* @param propertySource metadata for the <code>@PropertySource</code> annotation found
* @throws IOException if loading a property source failed
*/
springframework依赖
private void processPropertySource(AnnotationAttributes propertySource) throws IOException {
String name = String("name");
String[] locations = StringArray("value");
int locationCount = locations.length;
if (locationCount == 0) {
throw new IllegalArgumentException("At least one @PropertySource(value) location is required");
}
for (int i = 0; i < locationCount; i++) {
locations[i] = solveRequiredPlaceholders(locations[i]);
}
ClassLoader classLoader = ClassLoader();
if (!StringUtils.hasText(name)) {
for (String location : locations) {
this.propertySources.push(new ResourcePropertySource(location, classLoader));
}
}
else {
if (locationCount == 1) {
this.propertySources.push(new ResourcePropertySource(name, locations[0], classLoader));
}
else {
CompositePropertySource ps = new CompositePropertySource(name);
for (int i = locations.length - 1; i >= 0; i--) {
ps.addPropertySource(new ResourcePropertySource(locations[i], classLoader));
}
this.propertySources.push(ps);
}
}
}
t.annotation.ConfigurationClassPostProcessor.processConfigBeanDefinitions(BeanDefinitionRegistry)
/
/ Handle any @PropertySource annotations
Stack<PropertySource<?>> parsedPropertySources = PropertySources();
if (!parsedPropertySources.isEmpty()) {
if (!(vironment instanceof ConfigurableEnvironment)) {
logger.warn("Ignoring @PropertySource annotations. " +
"Reason: Environment must implement ConfigurableEnvironment");
}
else {
MutablePropertySources envPropertySources = ((vironment).getPropertySources();
while (!parsedPropertySources.isEmpty()) {
envPropertySources.addLast(parsedPropertySources.pop());
}
}
}
解决:spring使⽤5.x,因为5.x会直接⼀次性处理好@PropertySource
t.annotation.ConfigurationClassParser.processPropertySource(AnnotationAttributes)
/**
* Process the given <code>@PropertySource</code> annotation metadata.
* @param propertySource metadata for the <code>@PropertySource</code> annotation found
* @throws IOException if loading a property source failed
*/
private void processPropertySource(AnnotationAttributes propertySource) throws IOException {
String name = String("name");
if (!StringUtils.hasLength(name)) {
name = null;
}
String encoding = String("encoding");
if (!StringUtils.hasLength(encoding)) {
encoding = null;
}
String[] locations = StringArray("value");
Assert.isTrue(locations.length > 0, "At least one @PropertySource(value) location is required");
boolean ignoreResourceNotFound = Boolean("ignoreResourceNotFound");
Class<? extends PropertySourceFactory> factoryClass = Class("factory");
PropertySourceFactory factory = (factoryClass == PropertySourceFactory.class ?
DEFAULT_PROPERTY_SOURCE_FACTORY : BeanUtils.instantiateClass(factoryClass));
for (String location : locations) {
try {
String resolvedLocation = solveRequiredPlaceholders(location);
Resource resource = Resource(resolvedLocation);
//这⾥就加⼊到Environment了
atePropertySource(name, new EncodedResource(resource, encoding)));
}
catch (IllegalArgumentException | FileNotFoundException | UnknownHostException ex) {
// Placeholders not resolvable or resource not found when trying to open it
if (ignoreResourceNotFound) {
if (logger.isInfoEnabled()) {
logger.info("Properties location [" + location + "] not resolvable: " + ex.getMessage());
}
}
else {
throw ex;
}
}
}
}
然后,试试⾃动修改配置,发现没有⾃动刷新!
原因
@EnableNacosConfig(globalProperties = @NacosProperties(serverAddr = "${nacos.server.addr}"))
@NacosPropertySource(dataId = "${nacos.server.dataId}", groupId = "${upId}", autoRefreshed = true, properties = @NacosProperties(namespace = "${nacos.server.namespace}"))
名称空间配置在NacosPropertySource注解⾥,读配置没问题,⾃动刷新就不能⽤了
解决
@EnableNacosConfig(globalProperties = @NacosProperties(serverAddr = "${nacos.server.addr}", namespace = "${nacos.server.namespace}"))
@NacosPropertySource(dataId = "${nacos.server.dataId}", groupId = "${upId}", autoRefreshed = true)
⾄于为啥会有这么多坑

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。