Compare commits
73 Commits
Author | SHA1 | Date |
---|---|---|
|
ce41f4d407 | |
|
bede11a7e2 | |
|
9388aa7f65 | |
|
4b106fb992 | |
|
9b61ef68d2 | |
|
0a75c0b8c0 | |
|
eb8b10f3f3 | |
|
b209b291c2 | |
|
fcf008405b | |
|
1ada9f4e88 | |
|
b1351d7f88 | |
|
96d08e679d | |
|
5f0eb0b0d9 | |
|
0e660eb3ab | |
|
d4543ecb97 | |
|
e8cae2c501 | |
|
9591915028 | |
|
4a99227a88 | |
|
13f14239ea | |
|
1118b4bf2c | |
|
4854adbe89 | |
|
00072db454 | |
|
26fee8ca46 | |
|
31507dbf3f | |
|
72f20b8f91 | |
|
3f0a06d6db | |
|
88741f1750 | |
|
bd3b9652f3 | |
|
8bfd91ff28 | |
|
01308b6b1b | |
|
f906491e0a | |
|
458517f414 | |
|
6a72c2966f | |
|
400b3480f8 | |
|
f791545562 | |
|
d61ba1761b | |
|
478e043739 | |
|
cddc2a329a | |
|
a320f02179 | |
|
0126b26cc8 | |
|
c6dba51cf3 | |
|
ec35969e68 | |
|
cc2f2ca276 | |
|
8265710c77 | |
|
c060f8631e | |
|
c24e721fe5 | |
|
bfe6d58d9b | |
|
ca3f04e0fe | |
|
b90ab50ac0 | |
|
20897e41c8 | |
|
466852c25f | |
|
12883bbd2a | |
|
6d88d451df | |
|
4d26367bda | |
|
42203532ca | |
|
21f0ad8c02 | |
|
7e73ba6228 | |
|
3e52fa8341 | |
|
542a5d433e | |
|
190225477d | |
|
a36e45ba0c | |
|
81da8f6d94 | |
|
b55a0c86d4 | |
|
72f0aa4104 | |
|
b10a9603ed | |
|
811a83e8b0 | |
|
5bf4d37470 | |
|
fd3d649d03 | |
|
19809b04d1 | |
|
684c2e446a | |
|
38f80c37c5 | |
|
f41de89b52 | |
|
0e0f603ca0 |
|
@ -35,4 +35,5 @@ classes
|
|||
/bin/
|
||||
*.prefs
|
||||
*~
|
||||
.extract
|
||||
.extract
|
||||
.flattened-pom.xml
|
||||
|
|
34
README.md
34
README.md
|
@ -41,6 +41,7 @@ Content
|
|||
- [4.1.1. Enable Nacos](#411-enable-nacos)
|
||||
- [4.1.2. Configure Change Listener method](#412-configure-change-listener-method)
|
||||
- [4.1.2.1. Type Conversion](#4121-type-conversion)
|
||||
- [4.1.2.1.1. Type Conversion during YAML Parsing](#41211-Type Conversion during YAML Parsing)
|
||||
- [4.1.2.2. Timeout of Execution](#4122-timeout-of-execution)
|
||||
- [4.1.3. Global and Special Nacos Properties](#413-global-and-special-nacos-properties)
|
||||
- [4.1.4. `@NacosProperties`](#414-nacosproperties)
|
||||
|
@ -95,7 +96,7 @@ The following table shows the dependencies and compatabilities of Nacos Spring P
|
|||
|
||||
| Dependencies | Compatibility |
|
||||
| -------------- | ------------- |
|
||||
| Java | 1.6+ |
|
||||
| Java | 1.8+ |
|
||||
| Spring Context | 3.2+ |
|
||||
| [Alibaba Spring Context Support](https://github.com/alibaba/spring-context-support) | 1.0.1+ |
|
||||
| [Alibaba Nacos](https://github.com/alibaba/nacos) | 1.1.1+ |
|
||||
|
@ -123,14 +124,14 @@ Complete the following steps to enable Nacos for your Spring project.
|
|||
<dependency>
|
||||
<groupId>com.alibaba.nacos</groupId>
|
||||
<artifactId>nacos-spring-context</artifactId>
|
||||
<version>0.3.1</version>
|
||||
<version>1.1.0</version>
|
||||
</dependency>
|
||||
|
||||
...
|
||||
</dependencies>
|
||||
```
|
||||
|
||||
**Note:** Support Spring 5 from version 0.2.3-RC1.
|
||||
**Note:** Support Spring 5 from version 0.2.3-RC1, support Spring 6 from version 2.1.0.
|
||||
|
||||
2. Add the `@EnableNacos` annotation in the `@Configuration` class of Spring and specify "\${host}:${port}" of your Nacos server in the `serverAddr` attribute:
|
||||
|
||||
|
@ -315,8 +316,33 @@ The `UserNacosConfigConverter` class binds the `@NacosConfigListener.converter()
|
|||
}
|
||||
```
|
||||
|
||||
##### 4.1.2.1.1. Type Conversion during YAML Parsing
|
||||
|
||||
By default, starting from version 1.1.2, this library uses `SafeConstructor` for type conversion during YAML parsing. This is done to ensure that potentially unsafe code is not executed during the parsing process. `SafeConstructor` provides a secure construction logic for mapping YAML structures to Java objects.
|
||||
|
||||
**System Property Toggle**
|
||||
|
||||
To maintain compatibility with versions prior to 1.1.2, we have introduced a system property toggle named `yamlAllowComplexObject`. Prior to version 1.1.2, the library defaulted to using `Constructor`, another constructor in the SnakeYAML library that supports more complex object mapping. Starting from version 1.1.2, the default is switched to `SafeConstructor`.
|
||||
|
||||
**Potential Risks**
|
||||
|
||||
It's important to note that enabling `Constructor` introduces some potential risks, particularly the risk of Remote Code Execution (`RCE`). This is because `Constructor` allows more flexible object construction, but it also increases the risk of handling malicious YAML input.
|
||||
|
||||
**Recommendations**
|
||||
|
||||
- We recommend using the `NacosConfigConverter` for custom conversions.
|
||||
|
||||
**If You Must Use `Constructor`**
|
||||
|
||||
- Ensure that the source of the YAML data is secure.
|
||||
|
||||
**How to Disable `SafeConstructor`**
|
||||
|
||||
You can set the toggle by adding a JVM system property when starting your application. For example, in the command line:
|
||||
|
||||
```bash
|
||||
java -DyamlAllowComplexObject=true -jar your-application.jar
|
||||
```
|
||||
|
||||
- See [Type Conversion Sample of `@NacosConfigListener`](https://github.com/nacos-group/nacos-spring-project/blob/master/nacos-spring-samples/nacos-spring-webmvc-sample/src/main/java/com/alibaba/nacos/samples/spring/listener/PojoNacosConfigListener.java)
|
||||
|
||||
|
@ -401,7 +427,7 @@ try to retrieve properities from `@EnableNacosConfig.globalProperties()` or `@En
|
|||
|
||||
|
||||
|
||||
### 4.1.4. `@NacosProperties`
|
||||
### 4.1.4. `Nacos Properties`
|
||||
|
||||
`@NacosProperties` is a uniform annotation for global and special Nacos properties. It serves as a mediator between Java `Properties` and `NacosFactory` class. `NacosFactory` is responsible for creating `ConfigService` or `NamingService` instances.
|
||||
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>com.alibaba.nacos</groupId>
|
||||
<artifactId>nacos-spring-parent</artifactId>
|
||||
<version>${revision}</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
<groupId>com.alibaba.nacos</groupId>
|
||||
<artifactId>nacos-spring-context-aot</artifactId>
|
||||
<version>${revision}</version>
|
||||
<name>Alibaba Nacos :: Spring :: Context :: Aot</name>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-beans</artifactId>
|
||||
<version>${spring6.framework.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-core</artifactId>
|
||||
<version>${spring6.framework.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.alibaba.nacos</groupId>
|
||||
<artifactId>nacos-spring-context</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
*
|
||||
* * Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* * contributor license agreements. See the NOTICE file distributed with
|
||||
* * this work for additional information regarding copyright ownership.
|
||||
* * The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* * (the "License"); you may not use this file except in compliance with
|
||||
* * the License. You may obtain a copy of the License at
|
||||
* *
|
||||
* * http://www.apache.org/licenses/LICENSE-2.0
|
||||
* *
|
||||
* * Unless required by applicable law or agreed to in writing, software
|
||||
* * distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* * See the License for the specific language governing permissions and
|
||||
* * limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.spring.aot;
|
||||
|
||||
import com.alibaba.nacos.api.annotation.NacosInjected;
|
||||
import com.alibaba.nacos.api.config.annotation.NacosValue;
|
||||
import org.springframework.aot.generate.GenerationContext;
|
||||
import org.springframework.beans.factory.aot.BeanRegistrationAotContribution;
|
||||
import org.springframework.beans.factory.aot.BeanRegistrationAotProcessor;
|
||||
import org.springframework.beans.factory.aot.BeanRegistrationCode;
|
||||
import org.springframework.beans.factory.support.RegisteredBean;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* {@link NacosInjected} and {@link NacosValue} AotProcessor
|
||||
* The fields annotated with {@link NacosInjected} or {@link NacosValue} must be added to the reflect-config.json
|
||||
* @author SuperZ1999
|
||||
*/
|
||||
public class NacosAnnotationBeanRegistrationAotProcessor implements BeanRegistrationAotProcessor {
|
||||
@Override
|
||||
public BeanRegistrationAotContribution processAheadOfTime(RegisteredBean registeredBean) {
|
||||
Class<?> beanClass = registeredBean.getBeanClass();
|
||||
List<Field> fields = new ArrayList<>();
|
||||
ReflectionUtils.doWithFields(beanClass, field -> {
|
||||
NacosInjected injectedAnnotation = field.getDeclaredAnnotation(NacosInjected.class);
|
||||
NacosValue nacosValueAnnotation = field.getDeclaredAnnotation(NacosValue.class);
|
||||
if (injectedAnnotation != null || nacosValueAnnotation != null) {
|
||||
fields.add(field);
|
||||
}
|
||||
});
|
||||
if (fields.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
return new AotContribution(fields);
|
||||
}
|
||||
|
||||
private static class AotContribution implements BeanRegistrationAotContribution {
|
||||
private final List<Field> fields;
|
||||
|
||||
public AotContribution() {
|
||||
this.fields = new ArrayList<>();
|
||||
}
|
||||
|
||||
public AotContribution(List<Field> fields) {
|
||||
this.fields = fields;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applyTo(GenerationContext generationContext, BeanRegistrationCode beanRegistrationCode) {
|
||||
for (Field field : fields) {
|
||||
generationContext.getRuntimeHints().reflection().registerField(field);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
"resources": {
|
||||
"includes": [
|
||||
{
|
||||
"pattern": "\\QMETA-INF/spring.handlers\\E"
|
||||
},
|
||||
{
|
||||
"pattern": "\\QMETA-INF/spring.schemas\\E"
|
||||
},
|
||||
{
|
||||
"pattern": "\\QMETA-INF/schemas/nacos.xsd\\E"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
org.springframework.beans.factory.aot.BeanRegistrationAotProcessor=\
|
||||
com.alibaba.nacos.spring.aot.NacosAnnotationBeanRegistrationAotProcessor
|
|
@ -1,57 +1,66 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>nacos-spring-parent</artifactId>
|
||||
<groupId>com.alibaba.nacos</groupId>
|
||||
<version>0.3.6</version>
|
||||
<version>${revision}</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>com.alibaba.nacos</groupId>
|
||||
<artifactId>nacos-spring-context</artifactId>
|
||||
<version>0.3.6</version>
|
||||
<version>${revision}</version>
|
||||
<name>Alibaba Nacos :: Spring :: Context</name>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<dependencies>
|
||||
|
||||
<!-- java-->
|
||||
<dependency>
|
||||
<groupId>javax.annotation</groupId>
|
||||
<artifactId>javax.annotation-api</artifactId>
|
||||
<version>${javax.annotation-api.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Nacos -->
|
||||
<dependency>
|
||||
<groupId>com.alibaba.nacos</groupId>
|
||||
<artifactId>nacos-client</artifactId>
|
||||
<version>${nacos.version}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.yaml</groupId>
|
||||
<artifactId>snakeyaml</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-core</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-core</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!--yaml-->
|
||||
<dependency>
|
||||
<groupId>org.yaml</groupId>
|
||||
<artifactId>snakeyaml</artifactId>
|
||||
<version>${snake.yaml.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Spring Framework -->
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-context</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- Spring Context Extras -->
|
||||
<dependency>
|
||||
<groupId>com.alibaba.spring</groupId>
|
||||
<artifactId>spring-context-support</artifactId>
|
||||
<version>1.0.1</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Testing -->
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
|
@ -59,21 +68,27 @@
|
|||
<version>${project.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ch.qos.logback</groupId>
|
||||
<artifactId>logback-classic</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-core</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
|
@ -0,0 +1,644 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.spring.beans.factory.annotation;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.PropertyValues;
|
||||
import org.springframework.beans.factory.BeanClassLoaderAware;
|
||||
import org.springframework.beans.factory.BeanCreationException;
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.BeanFactoryAware;
|
||||
import org.springframework.beans.factory.DisposableBean;
|
||||
import org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor;
|
||||
import org.springframework.beans.factory.annotation.InjectionMetadata;
|
||||
import org.springframework.beans.factory.config.BeanPostProcessor;
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor;
|
||||
import org.springframework.beans.factory.support.MergedBeanDefinitionPostProcessor;
|
||||
import org.springframework.beans.factory.support.RootBeanDefinition;
|
||||
import org.springframework.context.EnvironmentAware;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.core.PriorityOrdered;
|
||||
import org.springframework.core.annotation.AnnotationAttributes;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import java.beans.PropertyDescriptor;
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.AnnotatedElement;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
|
||||
import static com.alibaba.spring.util.AnnotationUtils.getAnnotationAttributes;
|
||||
import static java.util.Collections.unmodifiableMap;
|
||||
import static org.springframework.aop.support.AopUtils.getTargetClass;
|
||||
import static org.springframework.core.BridgeMethodResolver.findBridgedMethod;
|
||||
import static org.springframework.core.BridgeMethodResolver.isVisibilityBridgeMethodPair;
|
||||
import static org.springframework.core.GenericTypeResolver.resolveTypeArgument;
|
||||
|
||||
/**
|
||||
* Abstract common {@link BeanPostProcessor} implementation for customized annotation that annotated injected-object.
|
||||
*
|
||||
* @author <a href="mailto:mercyblitz@gmail.com">Mercy</a>
|
||||
* @since 1.0.3
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public abstract class AbstractAnnotationBeanPostProcessor implements InstantiationAwareBeanPostProcessor, MergedBeanDefinitionPostProcessor, PriorityOrdered,
|
||||
BeanFactoryAware, BeanClassLoaderAware, EnvironmentAware, DisposableBean {
|
||||
|
||||
private final static int CACHE_SIZE = Integer.getInteger("", 32);
|
||||
|
||||
private final Log logger = LogFactory.getLog(getClass());
|
||||
|
||||
private final Class<? extends Annotation>[] annotationTypes;
|
||||
|
||||
private final ConcurrentMap<String, AnnotatedInjectionMetadata> injectionMetadataCache =
|
||||
new ConcurrentHashMap<String, AnnotatedInjectionMetadata>(CACHE_SIZE);
|
||||
|
||||
private final ConcurrentMap<String, Object> injectedObjectsCache = new ConcurrentHashMap<String, Object>(CACHE_SIZE);
|
||||
|
||||
private ConfigurableListableBeanFactory beanFactory;
|
||||
|
||||
private Environment environment;
|
||||
|
||||
private ClassLoader classLoader;
|
||||
|
||||
/**
|
||||
* make sure higher priority than {@link AutowiredAnnotationBeanPostProcessor}
|
||||
*/
|
||||
private int order = Ordered.LOWEST_PRECEDENCE - 3;
|
||||
|
||||
/**
|
||||
* whether to turn Class references into Strings (for
|
||||
* compatibility with {@link org.springframework.core.type.AnnotationMetadata} or to
|
||||
* preserve them as Class references
|
||||
*
|
||||
* @since 1.0.11
|
||||
*/
|
||||
private boolean classValuesAsString = true;
|
||||
|
||||
/**
|
||||
* whether to turn nested Annotation instances into
|
||||
* {@link AnnotationAttributes} maps (for compatibility with
|
||||
* {@link org.springframework.core.type.AnnotationMetadata} or to preserve them as
|
||||
* Annotation instances
|
||||
*
|
||||
* @since 1.0.11
|
||||
*/
|
||||
private boolean nestedAnnotationsAsMap = true;
|
||||
|
||||
/**
|
||||
* whether ignore default value or not
|
||||
*
|
||||
* @since 1.0.11
|
||||
*/
|
||||
private boolean ignoreDefaultValue = true;
|
||||
|
||||
/**
|
||||
* whether try merged annotation or not
|
||||
*
|
||||
* @since 1.0.11
|
||||
*/
|
||||
private boolean tryMergedAnnotation = true;
|
||||
|
||||
/**
|
||||
* @param annotationTypes the multiple types of {@link Annotation annotations}
|
||||
*/
|
||||
public AbstractAnnotationBeanPostProcessor(Class<? extends Annotation>... annotationTypes) {
|
||||
Assert.notEmpty(annotationTypes, "The argument of annotations' types must not empty");
|
||||
this.annotationTypes = annotationTypes;
|
||||
}
|
||||
|
||||
private static <T> Collection<T> combine(Collection<? extends T>... elements) {
|
||||
List<T> allElements = new ArrayList<T>();
|
||||
for (Collection<? extends T> e : elements) {
|
||||
allElements.addAll(e);
|
||||
}
|
||||
return allElements;
|
||||
}
|
||||
|
||||
/**
|
||||
* Annotation type
|
||||
*
|
||||
* @return non-null
|
||||
* @deprecated 2.7.3, uses {@link #getAnnotationTypes()}
|
||||
*/
|
||||
@Deprecated
|
||||
public final Class<? extends Annotation> getAnnotationType() {
|
||||
return annotationTypes[0];
|
||||
}
|
||||
|
||||
protected final Class<? extends Annotation>[] getAnnotationTypes() {
|
||||
return annotationTypes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
|
||||
Assert.isInstanceOf(ConfigurableListableBeanFactory.class, beanFactory,
|
||||
"AnnotationInjectedBeanPostProcessor requires a ConfigurableListableBeanFactory");
|
||||
this.beanFactory = (ConfigurableListableBeanFactory) beanFactory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeanCreationException {
|
||||
|
||||
InjectionMetadata metadata = findInjectionMetadata(beanName, bean.getClass(), pvs);
|
||||
try {
|
||||
metadata.inject(bean, beanName, pvs);
|
||||
} catch (BeanCreationException ex) {
|
||||
throw ex;
|
||||
} catch (Throwable ex) {
|
||||
throw new BeanCreationException(beanName, "Injection of @" + getAnnotationType().getSimpleName()
|
||||
+ " dependencies is failed", ex);
|
||||
}
|
||||
return pvs;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Finds {@link InjectionMetadata.InjectedElement} Metadata from annotated fields
|
||||
*
|
||||
* @param beanClass The {@link Class} of Bean
|
||||
* @return non-null {@link List}
|
||||
*/
|
||||
private List<AnnotatedFieldElement> findFieldAnnotationMetadata(final Class<?> beanClass) {
|
||||
|
||||
final List<AnnotatedFieldElement> elements = new LinkedList<AnnotatedFieldElement>();
|
||||
|
||||
ReflectionUtils.doWithFields(beanClass, new ReflectionUtils.FieldCallback() {
|
||||
@Override
|
||||
public void doWith(Field field) throws IllegalArgumentException, IllegalAccessException {
|
||||
|
||||
for (Class<? extends Annotation> annotationType : getAnnotationTypes()) {
|
||||
|
||||
AnnotationAttributes attributes = doGetAnnotationAttributes(field, annotationType);
|
||||
|
||||
if (attributes != null) {
|
||||
|
||||
if (Modifier.isStatic(field.getModifiers())) {
|
||||
if (logger.isWarnEnabled()) {
|
||||
logger.warn("@" + annotationType.getName() + " is not supported on static fields: " + field);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
elements.add(new AnnotatedFieldElement(field, attributes));
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return elements;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds {@link InjectionMetadata.InjectedElement} Metadata from annotated methods
|
||||
*
|
||||
* @param beanClass The {@link Class} of Bean
|
||||
* @return non-null {@link List}
|
||||
*/
|
||||
private List<AnnotatedMethodElement> findAnnotatedMethodMetadata(final Class<?> beanClass) {
|
||||
|
||||
final List<AnnotatedMethodElement> elements = new LinkedList<AnnotatedMethodElement>();
|
||||
|
||||
ReflectionUtils.doWithMethods(beanClass, new ReflectionUtils.MethodCallback() {
|
||||
@Override
|
||||
public void doWith(Method method) throws IllegalArgumentException, IllegalAccessException {
|
||||
|
||||
Method bridgedMethod = findBridgedMethod(method);
|
||||
|
||||
if (!isVisibilityBridgeMethodPair(method, bridgedMethod)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
for (Class<? extends Annotation> annotationType : getAnnotationTypes()) {
|
||||
|
||||
AnnotationAttributes attributes = doGetAnnotationAttributes(bridgedMethod, annotationType);
|
||||
|
||||
if (attributes != null && method.equals(ClassUtils.getMostSpecificMethod(method, beanClass))) {
|
||||
if (Modifier.isStatic(method.getModifiers())) {
|
||||
if (logger.isWarnEnabled()) {
|
||||
logger.warn("@" + annotationType.getName() + " annotation is not supported on static methods: " + method);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (method.getParameterTypes().length == 0) {
|
||||
if (logger.isWarnEnabled()) {
|
||||
logger.warn("@" + annotationType.getName() + " annotation should only be used on methods with parameters: " +
|
||||
method);
|
||||
}
|
||||
}
|
||||
PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, beanClass);
|
||||
elements.add(new AnnotatedMethodElement(method, pd, attributes));
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return elements;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get {@link AnnotationAttributes}
|
||||
*
|
||||
* @param annotatedElement {@link AnnotatedElement the annotated element}
|
||||
* @param annotationType the {@link Class tyoe} pf {@link Annotation annotation}
|
||||
* @return if <code>annotatedElement</code> can't be found in <code>annotatedElement</code>, return <code>null</code>
|
||||
* @since 1.0.11
|
||||
*/
|
||||
protected AnnotationAttributes doGetAnnotationAttributes(AnnotatedElement annotatedElement,
|
||||
Class<? extends Annotation> annotationType) {
|
||||
return getAnnotationAttributes(annotatedElement, annotationType, getEnvironment(),
|
||||
classValuesAsString, nestedAnnotationsAsMap, ignoreDefaultValue, tryMergedAnnotation);
|
||||
}
|
||||
|
||||
private AnnotatedInjectionMetadata buildAnnotatedMetadata(final Class<?> beanClass) {
|
||||
Collection<AnnotatedFieldElement> fieldElements = findFieldAnnotationMetadata(beanClass);
|
||||
Collection<AnnotatedMethodElement> methodElements = findAnnotatedMethodMetadata(beanClass);
|
||||
return new AnnotatedInjectionMetadata(beanClass, fieldElements, methodElements);
|
||||
}
|
||||
|
||||
private InjectionMetadata findInjectionMetadata(String beanName, Class<?> clazz, PropertyValues pvs) {
|
||||
// Fall back to class name as cache key, for backwards compatibility with custom callers.
|
||||
String cacheKey = (StringUtils.hasLength(beanName) ? beanName : clazz.getName());
|
||||
// Quick check on the concurrent map first, with minimal locking.
|
||||
AnnotatedInjectionMetadata metadata = this.injectionMetadataCache.get(cacheKey);
|
||||
if (InjectionMetadata.needsRefresh(metadata, clazz)) {
|
||||
synchronized (this.injectionMetadataCache) {
|
||||
metadata = this.injectionMetadataCache.get(cacheKey);
|
||||
if (InjectionMetadata.needsRefresh(metadata, clazz)) {
|
||||
if (metadata != null) {
|
||||
metadata.clear(pvs);
|
||||
}
|
||||
try {
|
||||
metadata = buildAnnotatedMetadata(clazz);
|
||||
this.injectionMetadataCache.put(cacheKey, metadata);
|
||||
} catch (NoClassDefFoundError err) {
|
||||
throw new IllegalStateException("Failed to introspect object class [" + clazz.getName() +
|
||||
"] for annotation metadata: could not find class that it depends on", err);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return metadata;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
|
||||
if (beanType != null) {
|
||||
InjectionMetadata metadata = findInjectionMetadata(beanName, beanType, null);
|
||||
metadata.checkConfigMembers(beanDefinition);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return order;
|
||||
}
|
||||
|
||||
public void setOrder(int order) {
|
||||
this.order = order;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy() throws Exception {
|
||||
|
||||
for (Object object : injectedObjectsCache.values()) {
|
||||
if (logger.isInfoEnabled()) {
|
||||
logger.info(object + " was destroying!");
|
||||
}
|
||||
|
||||
if (object instanceof DisposableBean) {
|
||||
((DisposableBean) object).destroy();
|
||||
}
|
||||
}
|
||||
|
||||
injectionMetadataCache.clear();
|
||||
injectedObjectsCache.clear();
|
||||
|
||||
if (logger.isInfoEnabled()) {
|
||||
logger.info(getClass() + " was destroying!");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBeanClassLoader(ClassLoader classLoader) {
|
||||
this.classLoader = classLoader;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setEnvironment(Environment environment) {
|
||||
this.environment = environment;
|
||||
}
|
||||
|
||||
protected Environment getEnvironment() {
|
||||
return environment;
|
||||
}
|
||||
|
||||
protected ClassLoader getClassLoader() {
|
||||
return classLoader;
|
||||
}
|
||||
|
||||
protected ConfigurableListableBeanFactory getBeanFactory() {
|
||||
return beanFactory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all injected-objects.
|
||||
*
|
||||
* @return non-null {@link Collection}
|
||||
*/
|
||||
protected Collection<Object> getInjectedObjects() {
|
||||
return this.injectedObjectsCache.values();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get injected-object from specified {@link AnnotationAttributes annotation attributes} and Bean Class
|
||||
*
|
||||
* @param attributes {@link AnnotationAttributes the annotation attributes}
|
||||
* @param bean Current bean that will be injected
|
||||
* @param beanName Current bean name that will be injected
|
||||
* @param injectedType the type of injected-object
|
||||
* @param injectedElement {@link InjectionMetadata.InjectedElement}
|
||||
* @return An injected object
|
||||
* @throws Exception If getting is failed
|
||||
*/
|
||||
protected Object getInjectedObject(AnnotationAttributes attributes, Object bean, String beanName, Class<?> injectedType,
|
||||
InjectionMetadata.InjectedElement injectedElement) throws Exception {
|
||||
|
||||
String cacheKey = buildInjectedObjectCacheKey(attributes, bean, beanName, injectedType, injectedElement);
|
||||
|
||||
Object injectedObject = injectedObjectsCache.get(cacheKey);
|
||||
|
||||
if (injectedObject == null) {
|
||||
injectedObject = doGetInjectedBean(attributes, bean, beanName, injectedType, injectedElement);
|
||||
if (injectedObject != null) {
|
||||
// Customized inject-object if necessary
|
||||
injectedObjectsCache.putIfAbsent(cacheKey, injectedObject);
|
||||
}
|
||||
}
|
||||
|
||||
return injectedObject;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Subclass must implement this method to get injected-object. The context objects could help this method if
|
||||
* necessary :
|
||||
* <ul>
|
||||
* <li>{@link #getBeanFactory() BeanFactory}</li>
|
||||
* <li>{@link #getClassLoader() ClassLoader}</li>
|
||||
* <li>{@link #getEnvironment() Environment}</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param attributes {@link AnnotationAttributes the annotation attributes}
|
||||
* @param bean Current bean that will be injected
|
||||
* @param beanName Current bean name that will be injected
|
||||
* @param injectedType the type of injected-object
|
||||
* @param injectedElement {@link InjectionMetadata.InjectedElement}
|
||||
* @return The injected object
|
||||
* @throws Exception If resolving an injected object is failed.
|
||||
*/
|
||||
protected abstract Object doGetInjectedBean(AnnotationAttributes attributes, Object bean, String beanName, Class<?> injectedType,
|
||||
InjectionMetadata.InjectedElement injectedElement) throws Exception;
|
||||
|
||||
/**
|
||||
* Build a cache key for injected-object. The context objects could help this method if
|
||||
* necessary :
|
||||
* <ul>
|
||||
* <li>{@link #getBeanFactory() BeanFactory}</li>
|
||||
* <li>{@link #getClassLoader() ClassLoader}</li>
|
||||
* <li>{@link #getEnvironment() Environment}</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param attributes {@link AnnotationAttributes the annotation attributes}
|
||||
* @param bean Current bean that will be injected
|
||||
* @param beanName Current bean name that will be injected
|
||||
* @param injectedType the type of injected-object
|
||||
* @param injectedElement {@link InjectionMetadata.InjectedElement}
|
||||
* @return Bean cache key
|
||||
*/
|
||||
protected abstract String buildInjectedObjectCacheKey(AnnotationAttributes attributes, Object bean, String beanName,
|
||||
Class<?> injectedType,
|
||||
InjectionMetadata.InjectedElement injectedElement);
|
||||
|
||||
/**
|
||||
* Get {@link Map} in injected field.
|
||||
*
|
||||
* @return non-null ready-only {@link Map}
|
||||
*/
|
||||
protected Map<InjectionMetadata.InjectedElement, Object> getInjectedFieldObjectsMap() {
|
||||
|
||||
Map<InjectionMetadata.InjectedElement, Object> injectedElementBeanMap =
|
||||
new LinkedHashMap<InjectionMetadata.InjectedElement, Object>();
|
||||
|
||||
for (AnnotatedInjectionMetadata metadata : injectionMetadataCache.values()) {
|
||||
|
||||
Collection<AnnotatedFieldElement> fieldElements = metadata.getFieldElements();
|
||||
|
||||
for (AnnotatedFieldElement fieldElement : fieldElements) {
|
||||
|
||||
injectedElementBeanMap.put(fieldElement, fieldElement.bean);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return unmodifiableMap(injectedElementBeanMap);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get {@link Map} in injected method.
|
||||
*
|
||||
* @return non-null {@link Map}
|
||||
*/
|
||||
protected Map<InjectionMetadata.InjectedElement, Object> getInjectedMethodObjectsMap() {
|
||||
|
||||
Map<InjectionMetadata.InjectedElement, Object> injectedElementBeanMap =
|
||||
new LinkedHashMap<InjectionMetadata.InjectedElement, Object>();
|
||||
|
||||
for (AnnotatedInjectionMetadata metadata : injectionMetadataCache.values()) {
|
||||
|
||||
Collection<AnnotatedMethodElement> methodElements = metadata.getMethodElements();
|
||||
|
||||
for (AnnotatedMethodElement methodElement : methodElements) {
|
||||
|
||||
injectedElementBeanMap.put(methodElement, methodElement.object);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return unmodifiableMap(injectedElementBeanMap);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param classValuesAsString whether to turn Class references into Strings (for
|
||||
* compatibility with {@link org.springframework.core.type.AnnotationMetadata} or to
|
||||
* preserve them as Class references
|
||||
* @since 1.0.11
|
||||
*/
|
||||
public void setClassValuesAsString(boolean classValuesAsString) {
|
||||
this.classValuesAsString = classValuesAsString;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param nestedAnnotationsAsMap whether to turn nested Annotation instances into
|
||||
* {@link AnnotationAttributes} maps (for compatibility with
|
||||
* {@link org.springframework.core.type.AnnotationMetadata} or to preserve them as
|
||||
* Annotation instances
|
||||
* @since 1.0.11
|
||||
*/
|
||||
public void setNestedAnnotationsAsMap(boolean nestedAnnotationsAsMap) {
|
||||
this.nestedAnnotationsAsMap = nestedAnnotationsAsMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ignoreDefaultValue whether ignore default value or not
|
||||
* @since 1.0.11
|
||||
*/
|
||||
public void setIgnoreDefaultValue(boolean ignoreDefaultValue) {
|
||||
this.ignoreDefaultValue = ignoreDefaultValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param tryMergedAnnotation whether try merged annotation or not
|
||||
* @since 1.0.11
|
||||
*/
|
||||
public void setTryMergedAnnotation(boolean tryMergedAnnotation) {
|
||||
this.tryMergedAnnotation = tryMergedAnnotation;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link Annotation Annotated} {@link InjectionMetadata} implementation
|
||||
*/
|
||||
private class AnnotatedInjectionMetadata extends InjectionMetadata {
|
||||
|
||||
private final Collection<AnnotatedFieldElement> fieldElements;
|
||||
|
||||
private final Collection<AnnotatedMethodElement> methodElements;
|
||||
|
||||
public AnnotatedInjectionMetadata(Class<?> targetClass, Collection<AnnotatedFieldElement> fieldElements,
|
||||
Collection<AnnotatedMethodElement> methodElements) {
|
||||
super(targetClass, combine(fieldElements, methodElements));
|
||||
this.fieldElements = fieldElements;
|
||||
this.methodElements = methodElements;
|
||||
}
|
||||
|
||||
public Collection<AnnotatedFieldElement> getFieldElements() {
|
||||
return fieldElements;
|
||||
}
|
||||
|
||||
public Collection<AnnotatedMethodElement> getMethodElements() {
|
||||
return methodElements;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link Annotation Annotated} {@link Method} {@link InjectionMetadata.InjectedElement}
|
||||
*/
|
||||
private class AnnotatedMethodElement extends InjectionMetadata.InjectedElement {
|
||||
|
||||
private final Method method;
|
||||
|
||||
private final AnnotationAttributes attributes;
|
||||
|
||||
private volatile Object object;
|
||||
|
||||
protected AnnotatedMethodElement(Method method, PropertyDescriptor pd, AnnotationAttributes attributes) {
|
||||
super(method, pd);
|
||||
this.method = method;
|
||||
this.attributes = attributes;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void inject(Object bean, String beanName, PropertyValues pvs) throws Throwable {
|
||||
|
||||
Class<?> injectedType = pd.getPropertyType();
|
||||
|
||||
Object injectedObject = getInjectedObject(attributes, bean, beanName, injectedType, this);
|
||||
|
||||
ReflectionUtils.makeAccessible(method);
|
||||
|
||||
method.invoke(bean, injectedObject);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link Annotation Annotated} {@link Field} {@link InjectionMetadata.InjectedElement}
|
||||
*/
|
||||
public class AnnotatedFieldElement extends InjectionMetadata.InjectedElement {
|
||||
|
||||
private final Field field;
|
||||
|
||||
private final AnnotationAttributes attributes;
|
||||
|
||||
private volatile Object bean;
|
||||
|
||||
protected AnnotatedFieldElement(Field field, AnnotationAttributes attributes) {
|
||||
super(field, null);
|
||||
this.field = field;
|
||||
this.attributes = attributes;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void inject(Object bean, String beanName, PropertyValues pvs) throws Throwable {
|
||||
|
||||
Class<?> injectedType = resolveInjectedType(bean, field);
|
||||
|
||||
Object injectedObject = getInjectedObject(attributes, bean, beanName, injectedType, this);
|
||||
|
||||
ReflectionUtils.makeAccessible(field);
|
||||
|
||||
field.set(bean, injectedObject);
|
||||
|
||||
}
|
||||
|
||||
private Class<?> resolveInjectedType(Object bean, Field field) {
|
||||
Type genericType = field.getGenericType();
|
||||
if (genericType instanceof Class) { // Just a normal Class
|
||||
return field.getType();
|
||||
} else { // GenericType
|
||||
return resolveTypeArgument(getTargetClass(bean), field.getDeclaringClass());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -16,25 +16,25 @@
|
|||
*/
|
||||
package com.alibaba.nacos.spring.beans.factory.annotation;
|
||||
|
||||
import static com.alibaba.nacos.spring.util.NacosBeanUtils.getNacosServiceFactoryBean;
|
||||
import static com.alibaba.spring.util.ClassUtils.resolveGenericType;
|
||||
import static java.lang.String.format;
|
||||
import static org.springframework.core.annotation.AnnotationUtils.getAnnotationAttributes;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
import com.alibaba.nacos.api.annotation.NacosProperties;
|
||||
import com.alibaba.nacos.api.exception.NacosException;
|
||||
import com.alibaba.nacos.spring.factory.NacosServiceFactory;
|
||||
import com.alibaba.nacos.spring.util.GlobalNacosPropertiesSource;
|
||||
import com.alibaba.nacos.spring.util.NacosUtils;
|
||||
|
||||
import org.springframework.beans.factory.BeanCreationException;
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.BeanFactoryAware;
|
||||
import org.springframework.context.EnvironmentAware;
|
||||
import org.springframework.core.env.Environment;
|
||||
|
||||
import static com.alibaba.nacos.spring.util.NacosBeanUtils.getNacosServiceFactoryBean;
|
||||
import static com.alibaba.spring.util.ClassUtils.resolveGenericType;
|
||||
import static java.lang.String.format;
|
||||
import static org.springframework.core.annotation.AnnotationUtils.getAnnotationAttributes;
|
||||
import com.alibaba.nacos.api.annotation.NacosProperties;
|
||||
import com.alibaba.nacos.api.exception.NacosException;
|
||||
import com.alibaba.nacos.spring.factory.NacosServiceFactory;
|
||||
import com.alibaba.nacos.spring.util.GlobalNacosPropertiesSource;
|
||||
import com.alibaba.nacos.spring.util.NacosUtils;
|
||||
|
||||
/**
|
||||
* Abstract Nacos Service Bean Builder
|
||||
|
@ -46,13 +46,10 @@ import static org.springframework.core.annotation.AnnotationUtils.getAnnotationA
|
|||
public abstract class AbstractNacosServiceBeanBuilder<S>
|
||||
implements BeanFactoryAware, EnvironmentAware {
|
||||
|
||||
private BeanFactory beanFactory;
|
||||
|
||||
private Environment environment;
|
||||
|
||||
private final Class<?> type;
|
||||
|
||||
private final GlobalNacosPropertiesSource source;
|
||||
private BeanFactory beanFactory;
|
||||
private Environment environment;
|
||||
|
||||
protected AbstractNacosServiceBeanBuilder(GlobalNacosPropertiesSource source) {
|
||||
type = resolveGenericType(getClass());
|
||||
|
|
|
@ -16,26 +16,27 @@
|
|||
*/
|
||||
package com.alibaba.nacos.spring.beans.factory.annotation;
|
||||
|
||||
import static java.lang.String.format;
|
||||
import static java.util.Collections.unmodifiableMap;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
||||
import org.springframework.beans.factory.annotation.InjectionMetadata;
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.core.annotation.AnnotationAttributes;
|
||||
|
||||
import com.alibaba.nacos.api.annotation.NacosInjected;
|
||||
import com.alibaba.nacos.api.config.ConfigService;
|
||||
import com.alibaba.nacos.api.naming.NamingService;
|
||||
import com.alibaba.spring.beans.factory.annotation.AnnotationInjectedBeanPostProcessor;
|
||||
import com.alibaba.spring.util.BeanUtils;
|
||||
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
||||
import org.springframework.beans.factory.annotation.InjectionMetadata;
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
|
||||
import static java.lang.String.format;
|
||||
import static java.util.Collections.unmodifiableMap;
|
||||
|
||||
/**
|
||||
* {@link AnnotationInjectedBeanPostProcessor} implementation is used to inject
|
||||
* {@link ConfigService} or {@link NamingService} instance into a Spring Bean If it's
|
||||
|
@ -44,8 +45,8 @@ import static java.util.Collections.unmodifiableMap;
|
|||
* @author <a href="mailto:mercyblitz@gmail.com">Mercy</a>
|
||||
* @since 0.1.0
|
||||
*/
|
||||
public class AnnotationNacosInjectedBeanPostProcessor extends
|
||||
AnnotationInjectedBeanPostProcessor<NacosInjected> implements InitializingBean {
|
||||
public class AnnotationNacosInjectedBeanPostProcessor
|
||||
extends AbstractAnnotationBeanPostProcessor implements InitializingBean {
|
||||
|
||||
/**
|
||||
* The name of {@link AnnotationNacosInjectedBeanPostProcessor}
|
||||
|
@ -54,6 +55,10 @@ public class AnnotationNacosInjectedBeanPostProcessor extends
|
|||
|
||||
private Map<Class<?>, AbstractNacosServiceBeanBuilder> nacosServiceBeanBuilderMap;
|
||||
|
||||
public AnnotationNacosInjectedBeanPostProcessor() {
|
||||
super(NacosInjected.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void afterPropertiesSet() {
|
||||
// Get beanFactory from super
|
||||
|
@ -99,22 +104,21 @@ public class AnnotationNacosInjectedBeanPostProcessor extends
|
|||
}
|
||||
|
||||
@Override
|
||||
protected Object doGetInjectedBean(NacosInjected annotation, Object bean,
|
||||
protected Object doGetInjectedBean(AnnotationAttributes attributes, Object bean,
|
||||
String beanName, Class<?> injectedType,
|
||||
InjectionMetadata.InjectedElement injectedElement) {
|
||||
|
||||
InjectionMetadata.InjectedElement injectedElement) throws Exception {
|
||||
AbstractNacosServiceBeanBuilder serviceBeanBuilder = nacosServiceBeanBuilderMap
|
||||
.get(injectedType);
|
||||
|
||||
return serviceBeanBuilder.build(annotation.properties());
|
||||
Map<String, Object> nacosProperties = getNacosProperties(attributes);
|
||||
|
||||
return serviceBeanBuilder.build(nacosProperties);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String buildInjectedObjectCacheKey(NacosInjected annotation, Object bean,
|
||||
String beanName, Class<?> injectedType,
|
||||
protected String buildInjectedObjectCacheKey(AnnotationAttributes attributes,
|
||||
Object bean, String beanName, Class<?> injectedType,
|
||||
InjectionMetadata.InjectedElement injectedElement) {
|
||||
|
||||
StringBuilder keyBuilder = new StringBuilder(injectedType.getSimpleName());
|
||||
|
||||
AbstractNacosServiceBeanBuilder serviceBeanBuilder = nacosServiceBeanBuilderMap
|
||||
|
@ -127,12 +131,16 @@ public class AnnotationNacosInjectedBeanPostProcessor extends
|
|||
injectedElement.getMember()));
|
||||
}
|
||||
|
||||
Properties properties = serviceBeanBuilder
|
||||
.resolveProperties(annotation.properties());
|
||||
Map<String, Object> nacosProperties = getNacosProperties(attributes);
|
||||
|
||||
Properties properties = serviceBeanBuilder.resolveProperties(nacosProperties);
|
||||
|
||||
keyBuilder.append(properties);
|
||||
|
||||
return keyBuilder.toString();
|
||||
}
|
||||
|
||||
private Map<String, Object> getNacosProperties(AnnotationAttributes attributes) {
|
||||
return (Map<String, Object>) attributes.get("properties");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,7 +25,6 @@ import com.alibaba.nacos.spring.util.GlobalNacosPropertiesSource;
|
|||
|
||||
/**
|
||||
* @author <a href="mailto:liaochunyhm@live.com">liaochuntao</a>
|
||||
* @since
|
||||
*/
|
||||
public class NamingMaintainServiceBeanBuilder
|
||||
extends AbstractNacosServiceBeanBuilder<NamingMaintainService> {
|
||||
|
|
|
@ -22,13 +22,13 @@ import java.lang.annotation.Retention;
|
|||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
import com.alibaba.nacos.api.annotation.NacosInjected;
|
||||
import com.alibaba.nacos.api.annotation.NacosProperties;
|
||||
import com.alibaba.nacos.api.config.annotation.NacosConfigListener;
|
||||
import com.alibaba.nacos.api.config.annotation.NacosConfigurationProperties;
|
||||
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
/**
|
||||
* Annotation for enabling Nacos features.
|
||||
*
|
||||
|
@ -39,7 +39,7 @@ import org.springframework.context.annotation.Import;
|
|||
@Target({ ElementType.TYPE, ElementType.ANNOTATION_TYPE })
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@Import(NacosBeanDefinitionRegistrar.class)
|
||||
@Import({NacosBeanDefinitionRegistrar.class, EnableNacosAotProcessor.class})
|
||||
public @interface EnableNacos {
|
||||
|
||||
/**
|
||||
|
|
|
@ -0,0 +1,96 @@
|
|||
/*
|
||||
*
|
||||
* * Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* * contributor license agreements. See the NOTICE file distributed with
|
||||
* * this work for additional information regarding copyright ownership.
|
||||
* * The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* * (the "License"); you may not use this file except in compliance with
|
||||
* * the License. You may obtain a copy of the License at
|
||||
* *
|
||||
* * http://www.apache.org/licenses/LICENSE-2.0
|
||||
* *
|
||||
* * Unless required by applicable law or agreed to in writing, software
|
||||
* * distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* * See the License for the specific language governing permissions and
|
||||
* * limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.spring.context.annotation;
|
||||
|
||||
import com.alibaba.nacos.spring.util.aot.AotDetector;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.BeanFactoryAware;
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
|
||||
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
|
||||
import org.springframework.context.EnvironmentAware;
|
||||
import org.springframework.core.annotation.AnnotationAttributes;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.core.type.AnnotationMetadata;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
|
||||
import static com.alibaba.nacos.spring.util.NacosBeanUtils.*;
|
||||
|
||||
/**
|
||||
* {@link EnableNacos} AotProcessor
|
||||
* Except for the operation of registering BeanDefinition, all other operations in {@link NacosBeanDefinitionRegistrar} must be done here
|
||||
* because spring will not call {@link NacosBeanDefinitionRegistrar#registerBeanDefinitions} in AOT.
|
||||
* @author SuperZ1999
|
||||
*/
|
||||
public class EnableNacosAotProcessor implements BeanDefinitionRegistryPostProcessor, EnvironmentAware, BeanFactoryAware {
|
||||
private Environment environment;
|
||||
|
||||
private BeanFactory beanFactory;
|
||||
|
||||
@Override
|
||||
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
|
||||
if (!AotDetector.useGeneratedArtifacts()) {
|
||||
return;
|
||||
}
|
||||
DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) this.beanFactory;
|
||||
Map<String, Object> beansWithAnnotation = beanFactory.getBeansWithAnnotation(EnableNacos.class);
|
||||
Object[] beans = beansWithAnnotation.values().toArray();
|
||||
if (beans.length != 0) {
|
||||
// only handle the first one
|
||||
Class<?> aClass = beans[0].getClass();
|
||||
if (aClass.getAnnotation(EnableNacos.class) == null) {
|
||||
// cglib proxy object
|
||||
aClass = aClass.getSuperclass();
|
||||
}
|
||||
AnnotationMetadata annotationMetadata = AnnotationMetadata.introspect(aClass);
|
||||
AnnotationAttributes attributes = AnnotationAttributes
|
||||
.fromMap(annotationMetadata
|
||||
.getAnnotationAttributes(EnableNacos.class.getName()));
|
||||
|
||||
// Register Global Nacos Properties Bean
|
||||
registerGlobalNacosProperties(attributes, registry, environment,
|
||||
GLOBAL_NACOS_PROPERTIES_BEAN_NAME);
|
||||
}
|
||||
|
||||
registerNacosConfigListenerExecutor(registry, environment);
|
||||
// Invoke NacosPropertySourcePostProcessor immediately
|
||||
// in order to enhance the precedence of @NacosPropertySource process
|
||||
invokeNacosPropertySourcePostProcessor(this.beanFactory);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setEnvironment(Environment environment) {
|
||||
this.environment = environment;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
|
||||
this.beanFactory = beanFactory;
|
||||
}
|
||||
}
|
|
@ -16,6 +16,13 @@
|
|||
*/
|
||||
package com.alibaba.nacos.spring.context.annotation;
|
||||
|
||||
import static com.alibaba.nacos.spring.util.NacosBeanUtils.GLOBAL_NACOS_PROPERTIES_BEAN_NAME;
|
||||
import static com.alibaba.nacos.spring.util.NacosBeanUtils.invokeNacosPropertySourcePostProcessor;
|
||||
import static com.alibaba.nacos.spring.util.NacosBeanUtils.registerGlobalNacosProperties;
|
||||
import static com.alibaba.nacos.spring.util.NacosBeanUtils.registerNacosCommonBeans;
|
||||
import static com.alibaba.nacos.spring.util.NacosBeanUtils.registerNacosConfigBeans;
|
||||
import static com.alibaba.nacos.spring.util.NacosBeanUtils.registerNacosDiscoveryBeans;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.BeanFactoryAware;
|
||||
|
@ -29,13 +36,6 @@ import org.springframework.core.annotation.AnnotationAttributes;
|
|||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.core.type.AnnotationMetadata;
|
||||
|
||||
import static com.alibaba.nacos.spring.util.NacosBeanUtils.GLOBAL_NACOS_PROPERTIES_BEAN_NAME;
|
||||
import static com.alibaba.nacos.spring.util.NacosBeanUtils.invokeNacosPropertySourcePostProcessor;
|
||||
import static com.alibaba.nacos.spring.util.NacosBeanUtils.registerGlobalNacosProperties;
|
||||
import static com.alibaba.nacos.spring.util.NacosBeanUtils.registerNacosCommonBeans;
|
||||
import static com.alibaba.nacos.spring.util.NacosBeanUtils.registerNacosConfigBeans;
|
||||
import static com.alibaba.nacos.spring.util.NacosBeanUtils.registerNacosDiscoveryBeans;
|
||||
|
||||
/**
|
||||
* Nacos Properties {@link ImportBeanDefinitionRegistrar BeanDefinition Registrar}
|
||||
*
|
||||
|
|
|
@ -16,20 +16,6 @@
|
|||
*/
|
||||
package com.alibaba.nacos.spring.context.annotation.config;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import com.alibaba.nacos.api.annotation.NacosInjected;
|
||||
import com.alibaba.nacos.api.annotation.NacosProperties;
|
||||
import com.alibaba.nacos.api.config.annotation.NacosConfigListener;
|
||||
import com.alibaba.nacos.api.config.annotation.NacosConfigurationProperties;
|
||||
import com.alibaba.nacos.spring.context.annotation.NacosBeanDefinitionRegistrar;
|
||||
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
import static com.alibaba.nacos.api.annotation.NacosProperties.ACCESS_KEY;
|
||||
import static com.alibaba.nacos.api.annotation.NacosProperties.CLUSTER_NAME;
|
||||
import static com.alibaba.nacos.api.annotation.NacosProperties.CONFIG_LONG_POLL_TIMEOUT;
|
||||
|
@ -44,6 +30,20 @@ import static com.alibaba.nacos.api.annotation.NacosProperties.SECRET_KEY;
|
|||
import static com.alibaba.nacos.api.annotation.NacosProperties.SERVER_ADDR;
|
||||
import static com.alibaba.nacos.api.annotation.NacosProperties.USERNAME;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
import com.alibaba.nacos.api.annotation.NacosInjected;
|
||||
import com.alibaba.nacos.api.annotation.NacosProperties;
|
||||
import com.alibaba.nacos.api.config.annotation.NacosConfigListener;
|
||||
import com.alibaba.nacos.api.config.annotation.NacosConfigurationProperties;
|
||||
import com.alibaba.nacos.spring.context.annotation.NacosBeanDefinitionRegistrar;
|
||||
|
||||
/**
|
||||
* Annotation for enabling Nacos Config features.
|
||||
*
|
||||
|
@ -54,99 +54,86 @@ import static com.alibaba.nacos.api.annotation.NacosProperties.USERNAME;
|
|||
@Target({ ElementType.TYPE, ElementType.ANNOTATION_TYPE })
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@Import(NacosConfigBeanDefinitionRegistrar.class)
|
||||
@Import({NacosConfigBeanDefinitionRegistrar.class, EnableNacosConfigAotProcessor.class})
|
||||
public @interface EnableNacosConfig {
|
||||
|
||||
/**
|
||||
* The prefix of property name of Nacos Config
|
||||
*/
|
||||
String CONFIG_PREFIX = NacosProperties.PREFIX + "config.";
|
||||
|
||||
/**
|
||||
* The placeholder of endpoint, the value is
|
||||
* <code>"${nacos.config.endpoint:${nacos.endpoint:}}"</code>
|
||||
*/
|
||||
String ENDPOINT_PLACEHOLDER = "${" + CONFIG_PREFIX + ENDPOINT + ":"
|
||||
+ NacosProperties.ENDPOINT_PLACEHOLDER + "}";
|
||||
|
||||
/**
|
||||
* The placeholder of endpoint, the value is
|
||||
* <code>"${nacos.config.namespace:${nacos.namespace:}}"</code>
|
||||
*/
|
||||
String NAMESPACE_PLACEHOLDER = "${" + CONFIG_PREFIX + NAMESPACE + ":"
|
||||
+ NacosProperties.NAMESPACE_PLACEHOLDER + "}";
|
||||
|
||||
/**
|
||||
* The placeholder of endpoint, the value is
|
||||
* <code>"${nacos.config.access-key:${nacos.access-key:}}"</code>
|
||||
*/
|
||||
String ACCESS_KEY_PLACEHOLDER = "${" + CONFIG_PREFIX + ACCESS_KEY + ":"
|
||||
+ NacosProperties.ACCESS_KEY_PLACEHOLDER + "}";
|
||||
|
||||
/**
|
||||
* The placeholder of endpoint, the value is
|
||||
* <code>"${nacos.config.secret-key:${nacos.secret-key:}}"</code>
|
||||
*/
|
||||
String SECRET_KEY_PLACEHOLDER = "${" + CONFIG_PREFIX + SECRET_KEY + ":"
|
||||
+ NacosProperties.SECRET_KEY_PLACEHOLDER + "}";
|
||||
|
||||
/**
|
||||
* The placeholder of endpoint, the value is
|
||||
* <code>"${nacos.config.server-addr:${nacos.server-addr:}}"</code>
|
||||
*/
|
||||
String SERVER_ADDR_PLACEHOLDER = "${" + CONFIG_PREFIX + SERVER_ADDR + ":"
|
||||
+ NacosProperties.SERVER_ADDR_PLACEHOLDER + "}";
|
||||
|
||||
/**
|
||||
* The placeholder of endpoint, the value is
|
||||
* <code>"${nacos.config.context-path:${nacos.context-path:}}"</code>
|
||||
*/
|
||||
String CONTEXT_PATH_PLACEHOLDER = "${" + CONFIG_PREFIX + CONTEXT_PATH + ":"
|
||||
+ NacosProperties.CONTEXT_PATH_PLACEHOLDER + "}";
|
||||
|
||||
/**
|
||||
* The placeholder of endpoint, the value is
|
||||
* <code>"${nacos.config.cluster-name:${nacos.cluster-name:}}"</code>
|
||||
*/
|
||||
String CLUSTER_NAME_PLACEHOLDER = "${" + CONFIG_PREFIX + CLUSTER_NAME + ":"
|
||||
+ NacosProperties.CLUSTER_NAME_PLACEHOLDER + "}";
|
||||
|
||||
/**
|
||||
* The placeholder of {@link NacosProperties#ENCODE encode}, the value is
|
||||
* <code>"${nacos.config.encode:${nacos.encode:UTF-8}}"</code>
|
||||
*/
|
||||
String ENCODE_PLACEHOLDER = "${" + CONFIG_PREFIX + ENCODE + ":"
|
||||
+ NacosProperties.ENCODE_PLACEHOLDER + "}";
|
||||
|
||||
/**
|
||||
* The placeholder of {@link NacosProperties#CONFIG_LONG_POLL_TIMEOUT
|
||||
* configLongPollTimeout}, the value is <code>"${nacos.configLongPollTimeout:}"</code>
|
||||
*/
|
||||
String CONFIG_LONG_POLL_TIMEOUT_PLACEHOLDER = "${" + CONFIG_PREFIX
|
||||
+ CONFIG_LONG_POLL_TIMEOUT
|
||||
+ CONFIG_LONG_POLL_TIMEOUT + ":"
|
||||
+ NacosProperties.CONFIG_LONG_POLL_TIMEOUT_PLACEHOLDER + "}";
|
||||
|
||||
/**
|
||||
* The placeholder of {@link NacosProperties#CONFIG_RETRY_TIME configRetryTime}, the
|
||||
* value is <code>"${nacos.configRetryTime:}"</code>
|
||||
*/
|
||||
String CONFIG_RETRY_TIME_PLACEHOLDER = "${" + CONFIG_PREFIX + CONFIG_RETRY_TIME
|
||||
String CONFIG_RETRY_TIME_PLACEHOLDER = "${" + CONFIG_PREFIX + CONFIG_RETRY_TIME + ":"
|
||||
+ NacosProperties.CONFIG_RETRY_TIME_PLACEHOLDER + "}";
|
||||
|
||||
/**
|
||||
* The placeholder of {@link NacosProperties#MAX_RETRY maxRetry}, the value is
|
||||
* <code>"${nacos.maxRetry:}"</code>
|
||||
*/
|
||||
String MAX_RETRY_PLACEHOLDER = "${" + CONFIG_PREFIX + MAX_RETRY
|
||||
String MAX_RETRY_PLACEHOLDER = "${" + CONFIG_PREFIX + MAX_RETRY + ":"
|
||||
+ NacosProperties.MAX_RETRY_PLACEHOLDER + "}";
|
||||
|
||||
/**
|
||||
* The placeholder of endpoint, the value is
|
||||
* <code>"${nacos.config.username:${nacos.username:}}"</code>
|
||||
*/
|
||||
String USERNAME_PLACEHOLDER = "${" + CONFIG_PREFIX + USERNAME + ":"
|
||||
+ NacosProperties.USERNAME_PLACEHOLDER + "}";
|
||||
|
||||
/**
|
||||
* The placeholder of endpoint, the value is
|
||||
* <code>"${nacos.config.password:${nacos.password:}}"</code>
|
||||
|
|
|
@ -0,0 +1,95 @@
|
|||
/*
|
||||
*
|
||||
* * Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* * contributor license agreements. See the NOTICE file distributed with
|
||||
* * this work for additional information regarding copyright ownership.
|
||||
* * The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* * (the "License"); you may not use this file except in compliance with
|
||||
* * the License. You may obtain a copy of the License at
|
||||
* *
|
||||
* * http://www.apache.org/licenses/LICENSE-2.0
|
||||
* *
|
||||
* * Unless required by applicable law or agreed to in writing, software
|
||||
* * distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* * See the License for the specific language governing permissions and
|
||||
* * limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.spring.context.annotation.config;
|
||||
|
||||
import com.alibaba.nacos.spring.util.aot.AotDetector;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.BeanFactoryAware;
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
|
||||
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
|
||||
import org.springframework.context.EnvironmentAware;
|
||||
import org.springframework.core.annotation.AnnotationAttributes;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.core.type.AnnotationMetadata;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import static com.alibaba.nacos.spring.util.NacosBeanUtils.*;
|
||||
|
||||
/**
|
||||
* {@link EnableNacosConfig} AotProcessor
|
||||
* Except for the operation of registering BeanDefinition, all other operations in {@link NacosConfigBeanDefinitionRegistrar} must be done here
|
||||
* because spring will not call {@link NacosConfigBeanDefinitionRegistrar#registerBeanDefinitions} in AOT.
|
||||
* @author SuperZ1999
|
||||
*/
|
||||
public class EnableNacosConfigAotProcessor implements BeanDefinitionRegistryPostProcessor, EnvironmentAware, BeanFactoryAware {
|
||||
private Environment environment;
|
||||
|
||||
private BeanFactory beanFactory;
|
||||
|
||||
@Override
|
||||
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
|
||||
if (!AotDetector.useGeneratedArtifacts()) {
|
||||
return;
|
||||
}
|
||||
DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) this.beanFactory;
|
||||
Map<String, Object> beansWithAnnotation = beanFactory.getBeansWithAnnotation(EnableNacosConfig.class);
|
||||
Object[] beans = beansWithAnnotation.values().toArray();
|
||||
if (beans.length != 0) {
|
||||
// only handle the first one
|
||||
Class<?> aClass = beans[0].getClass();
|
||||
if (aClass.getAnnotation(EnableNacosConfig.class) == null) {
|
||||
// cglib proxy object
|
||||
aClass = aClass.getSuperclass();
|
||||
}
|
||||
AnnotationMetadata annotationMetadata = AnnotationMetadata.introspect(aClass);
|
||||
AnnotationAttributes attributes = AnnotationAttributes
|
||||
.fromMap(annotationMetadata
|
||||
.getAnnotationAttributes(EnableNacosConfig.class.getName()));
|
||||
|
||||
// Register Global Nacos Properties Bean
|
||||
registerGlobalNacosProperties(attributes, registry, environment,
|
||||
CONFIG_GLOBAL_NACOS_PROPERTIES_BEAN_NAME);
|
||||
}
|
||||
|
||||
registerNacosConfigListenerExecutor(registry, environment);
|
||||
// Invoke NacosPropertySourcePostProcessor immediately
|
||||
// in order to enhance the precedence of @NacosPropertySource process
|
||||
invokeNacosPropertySourcePostProcessor(this.beanFactory);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setEnvironment(Environment environment) {
|
||||
this.environment = environment;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
|
||||
this.beanFactory = beanFactory;
|
||||
}
|
||||
}
|
|
@ -16,7 +16,12 @@
|
|||
*/
|
||||
package com.alibaba.nacos.spring.context.annotation.config;
|
||||
|
||||
import com.alibaba.nacos.spring.util.NacosBeanUtils;
|
||||
import static com.alibaba.nacos.spring.util.NacosBeanUtils.CONFIG_GLOBAL_NACOS_PROPERTIES_BEAN_NAME;
|
||||
import static com.alibaba.nacos.spring.util.NacosBeanUtils.invokeNacosPropertySourcePostProcessor;
|
||||
import static com.alibaba.nacos.spring.util.NacosBeanUtils.registerGlobalNacosProperties;
|
||||
import static com.alibaba.nacos.spring.util.NacosBeanUtils.registerNacosCommonBeans;
|
||||
import static com.alibaba.nacos.spring.util.NacosBeanUtils.registerNacosConfigBeans;
|
||||
import static org.springframework.core.annotation.AnnotationAttributes.fromMap;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
|
@ -29,12 +34,7 @@ import org.springframework.core.env.Environment;
|
|||
import org.springframework.core.env.PropertyResolver;
|
||||
import org.springframework.core.type.AnnotationMetadata;
|
||||
|
||||
import static com.alibaba.nacos.spring.util.NacosBeanUtils.CONFIG_GLOBAL_NACOS_PROPERTIES_BEAN_NAME;
|
||||
import static com.alibaba.nacos.spring.util.NacosBeanUtils.invokeNacosPropertySourcePostProcessor;
|
||||
import static com.alibaba.nacos.spring.util.NacosBeanUtils.registerGlobalNacosProperties;
|
||||
import static com.alibaba.nacos.spring.util.NacosBeanUtils.registerNacosCommonBeans;
|
||||
import static com.alibaba.nacos.spring.util.NacosBeanUtils.registerNacosConfigBeans;
|
||||
import static org.springframework.core.annotation.AnnotationAttributes.fromMap;
|
||||
import com.alibaba.nacos.spring.util.NacosBeanUtils;
|
||||
|
||||
/**
|
||||
* Nacos Config {@link ImportBeanDefinitionRegistrar BeanDefinition Registrar}
|
||||
|
@ -60,6 +60,7 @@ public class NacosConfigBeanDefinitionRegistrar
|
|||
BeanDefinitionRegistry registry) {
|
||||
AnnotationAttributes attributes = fromMap(
|
||||
metadata.getAnnotationAttributes(EnableNacosConfig.class.getName()));
|
||||
|
||||
// Register Global Nacos Properties Bean
|
||||
registerGlobalNacosProperties(attributes, registry, environment,
|
||||
CONFIG_GLOBAL_NACOS_PROPERTIES_BEAN_NAME);
|
||||
|
|
|
@ -16,23 +16,17 @@
|
|||
*/
|
||||
package com.alibaba.nacos.spring.context.annotation.config;
|
||||
|
||||
import static com.alibaba.nacos.spring.util.GlobalNacosPropertiesSource.CONFIG;
|
||||
import static com.alibaba.nacos.spring.util.NacosBeanUtils.getConfigServiceBeanBuilder;
|
||||
import static com.alibaba.nacos.spring.util.NacosBeanUtils.getNacosServiceFactoryBean;
|
||||
import static org.springframework.beans.BeanUtils.instantiateClass;
|
||||
import static org.springframework.core.annotation.AnnotationUtils.getAnnotationAttributes;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
import com.alibaba.nacos.api.annotation.NacosProperties;
|
||||
import com.alibaba.nacos.api.config.ConfigService;
|
||||
import com.alibaba.nacos.api.config.annotation.NacosConfigListener;
|
||||
import com.alibaba.nacos.api.config.convert.NacosConfigConverter;
|
||||
import com.alibaba.nacos.api.exception.NacosException;
|
||||
import com.alibaba.nacos.spring.beans.factory.annotation.ConfigServiceBeanBuilder;
|
||||
import com.alibaba.nacos.spring.context.event.AnnotationListenerMethodProcessor;
|
||||
import com.alibaba.nacos.spring.context.event.config.NacosConfigMetadataEvent;
|
||||
import com.alibaba.nacos.spring.context.event.config.TimeoutNacosConfigListener;
|
||||
import com.alibaba.nacos.spring.convert.converter.config.DefaultNacosConfigConverter;
|
||||
import com.alibaba.nacos.spring.factory.NacosServiceFactory;
|
||||
import com.alibaba.nacos.spring.util.NacosUtils;
|
||||
|
||||
import com.alibaba.nacos.api.config.ConfigType;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.BeanCreationException;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
|
@ -47,11 +41,18 @@ import org.springframework.util.Assert;
|
|||
import org.springframework.util.ReflectionUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import static com.alibaba.nacos.spring.util.GlobalNacosPropertiesSource.CONFIG;
|
||||
import static com.alibaba.nacos.spring.util.NacosBeanUtils.getConfigServiceBeanBuilder;
|
||||
import static com.alibaba.nacos.spring.util.NacosBeanUtils.getNacosServiceFactoryBean;
|
||||
import static org.springframework.beans.BeanUtils.instantiateClass;
|
||||
import static org.springframework.core.annotation.AnnotationUtils.getAnnotationAttributes;
|
||||
import com.alibaba.nacos.api.annotation.NacosProperties;
|
||||
import com.alibaba.nacos.api.config.ConfigService;
|
||||
import com.alibaba.nacos.api.config.annotation.NacosConfigListener;
|
||||
import com.alibaba.nacos.api.config.convert.NacosConfigConverter;
|
||||
import com.alibaba.nacos.api.exception.NacosException;
|
||||
import com.alibaba.nacos.spring.beans.factory.annotation.ConfigServiceBeanBuilder;
|
||||
import com.alibaba.nacos.spring.context.event.AnnotationListenerMethodProcessor;
|
||||
import com.alibaba.nacos.spring.context.event.config.NacosConfigMetadataEvent;
|
||||
import com.alibaba.nacos.spring.context.event.config.TimeoutNacosConfigListener;
|
||||
import com.alibaba.nacos.spring.convert.converter.config.DefaultNacosConfigConverter;
|
||||
import com.alibaba.nacos.spring.factory.NacosServiceFactory;
|
||||
import com.alibaba.nacos.spring.util.NacosUtils;
|
||||
|
||||
/**
|
||||
* {@link NacosConfigListener @NacosConfigListener} {@link Method method} Processor
|
||||
|
@ -97,9 +98,16 @@ public class NacosConfigListenerMethodProcessor
|
|||
environment);
|
||||
final String groupId = NacosUtils.readFromEnvironment(listener.groupId(),
|
||||
environment);
|
||||
final String type = StringUtils.isEmpty(NacosUtils.readTypeFromDataId(dataId))
|
||||
? listener.type().getType()
|
||||
: NacosUtils.readTypeFromDataId(dataId);
|
||||
final String type;
|
||||
|
||||
ConfigType typeEnum = listener.type();
|
||||
if (ConfigType.UNSET.equals(typeEnum)) {
|
||||
type = NacosUtils.readFileExtension(dataId);
|
||||
}
|
||||
else {
|
||||
type = typeEnum.getType();
|
||||
}
|
||||
|
||||
long timeout = listener.timeout();
|
||||
|
||||
Assert.isTrue(StringUtils.hasText(dataId), "dataId must have content");
|
||||
|
@ -163,21 +171,6 @@ public class NacosConfigListenerMethodProcessor
|
|||
applicationEventPublisher.publishEvent(metadataEvent);
|
||||
}
|
||||
|
||||
private ConfigService resolveConfigService(Properties nacosProperties,
|
||||
ApplicationContext applicationContext) throws BeansException {
|
||||
|
||||
ConfigService configService = null;
|
||||
|
||||
try {
|
||||
configService = nacosServiceFactory.createConfigService(nacosProperties);
|
||||
}
|
||||
catch (NacosException e) {
|
||||
throw new BeanCreationException(e.getErrMsg(), e);
|
||||
}
|
||||
|
||||
return configService;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isCandidateMethod(Object bean, Class<?> beanClass,
|
||||
NacosConfigListener listener, Method method,
|
||||
|
|
|
@ -16,6 +16,10 @@
|
|||
*/
|
||||
package com.alibaba.nacos.spring.context.annotation.config;
|
||||
|
||||
import static com.alibaba.nacos.api.common.Constants.DEFAULT_GROUP;
|
||||
import static com.alibaba.nacos.spring.util.NacosUtils.DEFAULT_BOOLEAN_ATTRIBUTE_VALUE;
|
||||
import static com.alibaba.nacos.spring.util.NacosUtils.DEFAULT_STRING_ATTRIBUTE_VALUE;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Repeatable;
|
||||
|
@ -24,18 +28,14 @@ import java.lang.annotation.RetentionPolicy;
|
|||
import java.lang.annotation.Target;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.core.env.PropertySource;
|
||||
|
||||
import com.alibaba.nacos.api.annotation.NacosProperties;
|
||||
import com.alibaba.nacos.api.common.Constants;
|
||||
import com.alibaba.nacos.api.config.ConfigType;
|
||||
import com.alibaba.nacos.spring.context.annotation.EnableNacos;
|
||||
import com.alibaba.nacos.spring.util.NacosUtils;
|
||||
|
||||
import org.springframework.core.env.PropertySource;
|
||||
|
||||
import static com.alibaba.nacos.api.common.Constants.DEFAULT_GROUP;
|
||||
import static com.alibaba.nacos.spring.util.NacosUtils.DEFAULT_BOOLEAN_ATTRIBUTE_VALUE;
|
||||
import static com.alibaba.nacos.spring.util.NacosUtils.DEFAULT_STRING_ATTRIBUTE_VALUE;
|
||||
|
||||
/**
|
||||
* An annotation for Nacos {@link PropertySource}
|
||||
*
|
||||
|
@ -162,7 +162,7 @@ public @interface NacosPropertySource {
|
|||
*
|
||||
* @return the type of config
|
||||
*/
|
||||
ConfigType type() default ConfigType.PROPERTIES;
|
||||
ConfigType type() default ConfigType.UNSET;
|
||||
|
||||
/**
|
||||
* The {@link NacosProperties} attribute, If not specified, it will use
|
||||
|
|
|
@ -16,24 +16,25 @@
|
|||
*/
|
||||
package com.alibaba.nacos.spring.context.annotation.config;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
import com.alibaba.nacos.spring.factory.NacosServiceFactory;
|
||||
import com.alibaba.nacos.spring.util.config.NacosConfigLoader;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.core.env.ConfigurableEnvironment;
|
||||
import org.springframework.core.env.PropertiesPropertySource;
|
||||
import org.springframework.core.env.PropertySource;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import static com.alibaba.nacos.spring.util.NacosBeanUtils.getNacosServiceFactoryBean;
|
||||
import static com.alibaba.nacos.spring.util.NacosUtils.buildDefaultPropertySourceName;
|
||||
import static com.alibaba.nacos.spring.util.NacosUtils.toProperties;
|
||||
import static java.lang.String.format;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.core.env.ConfigurableEnvironment;
|
||||
import org.springframework.core.env.MapPropertySource;
|
||||
import org.springframework.core.env.PropertySource;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import com.alibaba.nacos.spring.factory.NacosServiceFactory;
|
||||
import com.alibaba.nacos.spring.util.config.NacosConfigLoader;
|
||||
|
||||
/**
|
||||
* Nacos {@link PropertySource} Builder
|
||||
*
|
||||
|
@ -120,13 +121,13 @@ class NacosPropertySourceBuilder {
|
|||
return null;
|
||||
}
|
||||
|
||||
Properties properties = toProperties(dataId, groupId, config, type);
|
||||
Map<String, Object> properties = toProperties(dataId, groupId, config, type);
|
||||
|
||||
if (!StringUtils.hasText(name)) {
|
||||
name = buildDefaultPropertySourceName(dataId, groupId, properties);
|
||||
}
|
||||
|
||||
return new PropertiesPropertySource(name, properties);
|
||||
return new MapPropertySource(name, properties);
|
||||
}
|
||||
|
||||
public NacosConfigLoader getNacosConfigLoader() {
|
||||
|
|
|
@ -14,25 +14,10 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.spring.context.annotation.config;
|
||||
|
||||
import com.alibaba.nacos.api.config.annotation.NacosValue;
|
||||
import com.alibaba.nacos.client.config.utils.MD5;
|
||||
import com.alibaba.nacos.spring.context.event.config.NacosConfigReceivedEvent;
|
||||
import com.alibaba.spring.beans.factory.annotation.AnnotationInjectedBeanPostProcessor;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.TypeConverter;
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.BeanFactoryAware;
|
||||
import org.springframework.beans.factory.annotation.InjectionMetadata;
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.context.ApplicationListener;
|
||||
import org.springframework.context.EnvironmentAware;
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
import static org.springframework.core.annotation.AnnotationUtils.getAnnotation;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Member;
|
||||
|
@ -43,48 +28,99 @@ import java.util.HashMap;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.springframework.core.annotation.AnnotationUtils.getAnnotation;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import com.alibaba.nacos.spring.beans.factory.annotation.AbstractAnnotationBeanPostProcessor;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.TypeConverter;
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.BeanFactoryAware;
|
||||
import org.springframework.beans.factory.annotation.InjectionMetadata;
|
||||
import org.springframework.beans.factory.config.BeanExpressionContext;
|
||||
import org.springframework.beans.factory.config.BeanExpressionResolver;
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.context.ApplicationListener;
|
||||
import org.springframework.context.EnvironmentAware;
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.core.annotation.AnnotationAttributes;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
|
||||
import com.alibaba.nacos.api.config.annotation.NacosValue;
|
||||
import com.alibaba.nacos.common.utils.MD5Utils;
|
||||
import com.alibaba.nacos.spring.context.event.config.NacosConfigReceivedEvent;
|
||||
|
||||
/**
|
||||
* {@link org.springframework.beans.factory.config.BeanPostProcessor} implementation
|
||||
* Injected {@link NacosValue}
|
||||
* {@link org.springframework.beans.factory.config.BeanPostProcessor} implementation.
|
||||
*
|
||||
* @author <a href="mailto:huangxiaoyu1018@gmail.com">hxy1991</a>
|
||||
* @see NacosValue
|
||||
* @since 0.1.0
|
||||
*/
|
||||
public class NacosValueAnnotationBeanPostProcessor extends AnnotationInjectedBeanPostProcessor<NacosValue>
|
||||
implements BeanFactoryAware, EnvironmentAware, ApplicationListener<NacosConfigReceivedEvent> {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(getClass());
|
||||
public class NacosValueAnnotationBeanPostProcessor
|
||||
extends AbstractAnnotationBeanPostProcessor implements BeanFactoryAware,
|
||||
EnvironmentAware, ApplicationListener<NacosConfigReceivedEvent> {
|
||||
|
||||
/**
|
||||
* The name of {@link NacosValueAnnotationBeanPostProcessor} bean
|
||||
* The name of {@link NacosValueAnnotationBeanPostProcessor} bean.
|
||||
*/
|
||||
public static final String BEAN_NAME = "nacosValueAnnotationBeanPostProcessor";
|
||||
|
||||
private static final String SPEL_PREFIX = "#{";
|
||||
|
||||
private static final String PLACEHOLDER_PREFIX = "${";
|
||||
|
||||
private static final String PLACEHOLDER_SUFFIX = "}";
|
||||
|
||||
private static final char PLACEHOLDER_MATCH_PREFIX = '{';
|
||||
|
||||
private static final char PLACEHOLDER_MATCH_SUFFIX = '}';
|
||||
|
||||
private static final String VALUE_SEPARATOR = ":";
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(getClass());
|
||||
|
||||
/**
|
||||
* placeholder, nacosValueTarget
|
||||
* placeholder, nacosValueTarget.
|
||||
*/
|
||||
private Map<String, List<NacosValueTarget>> placeholderNacosValueTargetMap
|
||||
= new HashMap<String, List<NacosValueTarget>>();
|
||||
private Map<String, List<NacosValueTarget>> placeholderNacosValueTargetMap = new HashMap<String, List<NacosValueTarget>>();
|
||||
|
||||
private ConfigurableListableBeanFactory beanFactory;
|
||||
|
||||
private Environment environment;
|
||||
|
||||
@Override
|
||||
protected Object doGetInjectedBean(NacosValue annotation, Object bean, String beanName, Class<?> injectedType,
|
||||
InjectionMetadata.InjectedElement injectedElement) {
|
||||
String annotationValue = annotation.value();
|
||||
String value = beanFactory.resolveEmbeddedValue(annotationValue);
|
||||
private BeanExpressionResolver exprResolver;
|
||||
|
||||
Member member = injectedElement.getMember();
|
||||
private BeanExpressionContext exprContext;
|
||||
|
||||
public NacosValueAnnotationBeanPostProcessor() {
|
||||
super(NacosValue.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
|
||||
if (!(beanFactory instanceof ConfigurableListableBeanFactory)) {
|
||||
throw new IllegalArgumentException(
|
||||
"NacosValueAnnotationBeanPostProcessor requires a ConfigurableListableBeanFactory");
|
||||
}
|
||||
this.beanFactory = (ConfigurableListableBeanFactory) beanFactory;
|
||||
this.exprResolver = ((ConfigurableListableBeanFactory) beanFactory).getBeanExpressionResolver();
|
||||
this.exprContext = new BeanExpressionContext((ConfigurableListableBeanFactory) beanFactory, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setEnvironment(Environment environment) {
|
||||
this.environment = environment;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object doGetInjectedBean(AnnotationAttributes attributes, Object bean,
|
||||
String beanName, Class<?> injectedType,
|
||||
InjectionMetadata.InjectedElement injectedElement) throws Exception {
|
||||
Object value = resolveStringValue(attributes.getString("value"));
|
||||
Member member = injectedElement.getMember();
|
||||
if (member instanceof Field) {
|
||||
return convertIfNecessary((Field) member, value);
|
||||
}
|
||||
|
@ -97,24 +133,10 @@ public class NacosValueAnnotationBeanPostProcessor extends AnnotationInjectedBea
|
|||
}
|
||||
|
||||
@Override
|
||||
protected String buildInjectedObjectCacheKey(NacosValue annotation, Object bean, String beanName,
|
||||
Class<?> injectedType,
|
||||
InjectionMetadata.InjectedElement injectedElement) {
|
||||
return bean.getClass().getName() + annotation;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
|
||||
if (!(beanFactory instanceof ConfigurableListableBeanFactory)) {
|
||||
throw new IllegalArgumentException(
|
||||
"NacosValueAnnotationBeanPostProcessor requires a ConfigurableListableBeanFactory");
|
||||
}
|
||||
this.beanFactory = (ConfigurableListableBeanFactory) beanFactory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setEnvironment(Environment environment) {
|
||||
this.environment = environment;
|
||||
protected String buildInjectedObjectCacheKey(AnnotationAttributes attributes,
|
||||
Object bean, String beanName, Class<?> injectedType,
|
||||
InjectionMetadata.InjectedElement injectedElement) {
|
||||
return bean.getClass().getName() + attributes;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -133,28 +155,45 @@ public class NacosValueAnnotationBeanPostProcessor extends AnnotationInjectedBea
|
|||
// In to this event receiver, the environment has been updated the
|
||||
// latest configuration information, pull directly from the environment
|
||||
// fix issue #142
|
||||
for (Map.Entry<String, List<NacosValueTarget>> entry : placeholderNacosValueTargetMap.entrySet()) {
|
||||
for (Map.Entry<String, List<NacosValueTarget>> entry : placeholderNacosValueTargetMap
|
||||
.entrySet()) {
|
||||
String key = environment.resolvePlaceholders(entry.getKey());
|
||||
String newValue = environment.getProperty(key);
|
||||
|
||||
if (newValue == null) {
|
||||
continue;
|
||||
}
|
||||
List<NacosValueTarget> beanPropertyList = entry.getValue();
|
||||
for (NacosValueTarget target : beanPropertyList) {
|
||||
String md5String = MD5.getInstance().getMD5String(newValue);
|
||||
String md5String = MD5Utils.md5Hex(newValue, "UTF-8");
|
||||
boolean isUpdate = !target.lastMD5.equals(md5String);
|
||||
if (isUpdate) {
|
||||
target.updateLastMD5(md5String);
|
||||
Object evaluatedValue = resolveNotifyValue(target.nacosValueExpr, key, newValue);
|
||||
if (target.method == null) {
|
||||
setField(target, newValue);
|
||||
} else {
|
||||
setMethod(target, newValue);
|
||||
setField(target, evaluatedValue);
|
||||
}
|
||||
else {
|
||||
setMethod(target, evaluatedValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Object resolveNotifyValue(String nacosValueExpr, String key, String newValue) {
|
||||
String spelExpr = StringUtils.replace(nacosValueExpr, PLACEHOLDER_PREFIX + key + PLACEHOLDER_SUFFIX, newValue);
|
||||
return resolveStringValue(spelExpr);
|
||||
}
|
||||
|
||||
private Object resolveStringValue(String strVal) {
|
||||
String value = beanFactory.resolveEmbeddedValue(strVal);
|
||||
if (exprResolver != null && value != null) {
|
||||
return exprResolver.evaluate(value, exprContext);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
private Object convertIfNecessary(Field field, Object value) {
|
||||
TypeConverter converter = beanFactory.getTypeConverter();
|
||||
return converter.convertIfNecessary(value, field.getType(), field);
|
||||
|
@ -167,38 +206,44 @@ public class NacosValueAnnotationBeanPostProcessor extends AnnotationInjectedBea
|
|||
TypeConverter converter = beanFactory.getTypeConverter();
|
||||
|
||||
if (arguments.length == 1) {
|
||||
return converter.convertIfNecessary(value, paramTypes[0], new MethodParameter(method, 0));
|
||||
return converter.convertIfNecessary(value, paramTypes[0],
|
||||
new MethodParameter(method, 0));
|
||||
}
|
||||
|
||||
for (int i = 0; i < arguments.length; i++) {
|
||||
arguments[i] = converter.convertIfNecessary(value, paramTypes[i], new MethodParameter(method, i));
|
||||
arguments[i] = converter.convertIfNecessary(value, paramTypes[i],
|
||||
new MethodParameter(method, i));
|
||||
}
|
||||
|
||||
return arguments;
|
||||
}
|
||||
|
||||
private void doWithFields(final Object bean, final String beanName) {
|
||||
ReflectionUtils.doWithFields(bean.getClass(), new ReflectionUtils.FieldCallback() {
|
||||
@Override
|
||||
public void doWith(Field field) throws IllegalArgumentException {
|
||||
NacosValue annotation = getAnnotation(field, NacosValue.class);
|
||||
doWithAnnotation(beanName, bean, annotation, field.getModifiers(), null, field);
|
||||
}
|
||||
});
|
||||
ReflectionUtils.doWithFields(bean.getClass(),
|
||||
new ReflectionUtils.FieldCallback() {
|
||||
@Override
|
||||
public void doWith(Field field) throws IllegalArgumentException {
|
||||
NacosValue annotation = getAnnotation(field, NacosValue.class);
|
||||
doWithAnnotation(beanName, bean, annotation, field.getModifiers(),
|
||||
null, field);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void doWithMethods(final Object bean, final String beanName) {
|
||||
ReflectionUtils.doWithMethods(bean.getClass(), new ReflectionUtils.MethodCallback() {
|
||||
@Override
|
||||
public void doWith(Method method) throws IllegalArgumentException {
|
||||
NacosValue annotation = getAnnotation(method, NacosValue.class);
|
||||
doWithAnnotation(beanName, bean, annotation, method.getModifiers(), method, null);
|
||||
}
|
||||
});
|
||||
ReflectionUtils.doWithMethods(bean.getClass(),
|
||||
new ReflectionUtils.MethodCallback() {
|
||||
@Override
|
||||
public void doWith(Method method) throws IllegalArgumentException {
|
||||
NacosValue annotation = getAnnotation(method, NacosValue.class);
|
||||
doWithAnnotation(beanName, bean, annotation,
|
||||
method.getModifiers(), method, null);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void doWithAnnotation(String beanName, Object bean, NacosValue annotation, int modifiers, Method method,
|
||||
Field field) {
|
||||
private void doWithAnnotation(String beanName, Object bean, NacosValue annotation,
|
||||
int modifiers, Method method, Field field) {
|
||||
if (annotation != null) {
|
||||
if (Modifier.isStatic(modifiers)) {
|
||||
return;
|
||||
|
@ -211,14 +256,16 @@ public class NacosValueAnnotationBeanPostProcessor extends AnnotationInjectedBea
|
|||
return;
|
||||
}
|
||||
|
||||
NacosValueTarget nacosValueTarget = new NacosValueTarget(bean, beanName, method, field);
|
||||
put2ListMap(placeholderNacosValueTargetMap, placeholder, nacosValueTarget);
|
||||
NacosValueTarget nacosValueTarget = new NacosValueTarget(bean, beanName,
|
||||
method, field, annotation.value());
|
||||
put2ListMap(placeholderNacosValueTargetMap, placeholder,
|
||||
nacosValueTarget);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private String resolvePlaceholder(String placeholder) {
|
||||
if (!placeholder.startsWith(PLACEHOLDER_PREFIX)) {
|
||||
if (!placeholder.startsWith(PLACEHOLDER_PREFIX) && !placeholder.startsWith(SPEL_PREFIX)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -226,12 +273,19 @@ public class NacosValueAnnotationBeanPostProcessor extends AnnotationInjectedBea
|
|||
return null;
|
||||
}
|
||||
|
||||
if (placeholder.length() <= PLACEHOLDER_PREFIX.length() + PLACEHOLDER_SUFFIX.length()) {
|
||||
if (placeholder.length() <= PLACEHOLDER_PREFIX.length()
|
||||
+ PLACEHOLDER_SUFFIX.length()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
int beginIndex = PLACEHOLDER_PREFIX.length();
|
||||
int endIndex = placeholder.length() - PLACEHOLDER_PREFIX.length() + 1;
|
||||
int beginIndex = placeholder.indexOf(PLACEHOLDER_PREFIX);
|
||||
if (beginIndex == -1) {
|
||||
return null;
|
||||
}
|
||||
beginIndex = beginIndex + PLACEHOLDER_PREFIX.length();
|
||||
int endIndex = placeholder.indexOf(PLACEHOLDER_SUFFIX, beginIndex);
|
||||
if (endIndex == -1) {
|
||||
return null;
|
||||
}
|
||||
placeholder = placeholder.substring(beginIndex, endIndex);
|
||||
|
||||
int separatorIndex = placeholder.indexOf(VALUE_SEPARATOR);
|
||||
|
@ -251,26 +305,28 @@ public class NacosValueAnnotationBeanPostProcessor extends AnnotationInjectedBea
|
|||
map.put(key, valueList);
|
||||
}
|
||||
|
||||
private void setMethod(NacosValueTarget nacosValueTarget, String propertyValue) {
|
||||
private void setMethod(NacosValueTarget nacosValueTarget, Object propertyValue) {
|
||||
Method method = nacosValueTarget.method;
|
||||
ReflectionUtils.makeAccessible(method);
|
||||
try {
|
||||
method.invoke(nacosValueTarget.bean, convertIfNecessary(method, propertyValue));
|
||||
method.invoke(nacosValueTarget.bean,
|
||||
convertIfNecessary(method, propertyValue));
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Update value with {} (method) in {} (bean) with {}",
|
||||
method.getName(), nacosValueTarget.beanName, propertyValue);
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
}
|
||||
catch (Throwable e) {
|
||||
if (logger.isErrorEnabled()) {
|
||||
logger.error(
|
||||
"Can't update value with " + method.getName() + " (method) in "
|
||||
+ nacosValueTarget.beanName + " (bean)", e);
|
||||
logger.error("Can't update value with " + method.getName()
|
||||
+ " (method) in " + nacosValueTarget.beanName + " (bean)", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void setField(final NacosValueTarget nacosValueTarget, final String propertyValue) {
|
||||
private void setField(final NacosValueTarget nacosValueTarget,
|
||||
final Object propertyValue) {
|
||||
final Object bean = nacosValueTarget.bean;
|
||||
|
||||
Field field = nacosValueTarget.field;
|
||||
|
@ -285,11 +341,11 @@ public class NacosValueAnnotationBeanPostProcessor extends AnnotationInjectedBea
|
|||
logger.debug("Update value of the {}" + " (field) in {} (bean) with {}",
|
||||
fieldName, nacosValueTarget.beanName, propertyValue);
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
}
|
||||
catch (Throwable e) {
|
||||
if (logger.isErrorEnabled()) {
|
||||
logger.error(
|
||||
"Can't update value of the " + fieldName + " (field) in "
|
||||
+ nacosValueTarget.beanName + " (bean)", e);
|
||||
logger.error("Can't update value of the " + fieldName + " (field) in "
|
||||
+ nacosValueTarget.beanName + " (bean)", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -306,7 +362,9 @@ public class NacosValueAnnotationBeanPostProcessor extends AnnotationInjectedBea
|
|||
|
||||
private String lastMD5;
|
||||
|
||||
NacosValueTarget(Object bean, String beanName, Method method, Field field) {
|
||||
private final String nacosValueExpr;
|
||||
|
||||
NacosValueTarget(Object bean, String beanName, Method method, Field field, String nacosValueExpr) {
|
||||
this.bean = bean;
|
||||
|
||||
this.beanName = beanName;
|
||||
|
@ -316,6 +374,31 @@ public class NacosValueAnnotationBeanPostProcessor extends AnnotationInjectedBea
|
|||
this.field = field;
|
||||
|
||||
this.lastMD5 = "";
|
||||
|
||||
this.nacosValueExpr = resolveExpr(nacosValueExpr);
|
||||
}
|
||||
|
||||
private String resolveExpr(String nacosValueExpr) {
|
||||
try {
|
||||
int replaceHolderBegin = nacosValueExpr.indexOf(PLACEHOLDER_PREFIX) + PLACEHOLDER_PREFIX.length();
|
||||
int replaceHolderEnd = replaceHolderBegin;
|
||||
for (int i = 0; replaceHolderEnd < nacosValueExpr.length(); replaceHolderEnd++) {
|
||||
char ch = nacosValueExpr.charAt(replaceHolderEnd);
|
||||
if (PLACEHOLDER_MATCH_PREFIX == ch) {
|
||||
i++;
|
||||
} else if (PLACEHOLDER_MATCH_SUFFIX == ch && --i == -1) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
String replaceHolder = nacosValueExpr.substring(replaceHolderBegin, replaceHolderEnd);
|
||||
int separatorIndex = replaceHolder.indexOf(VALUE_SEPARATOR);
|
||||
if (separatorIndex != -1) {
|
||||
return nacosValueExpr.substring(0, separatorIndex + replaceHolderBegin) + nacosValueExpr.substring(replaceHolderEnd);
|
||||
}
|
||||
return nacosValueExpr;
|
||||
} catch (Exception e) {
|
||||
throw new IllegalArgumentException("The expr format is illegal, expr: " + nacosValueExpr, e);
|
||||
}
|
||||
}
|
||||
|
||||
protected void updateLastMD5(String newMD5) {
|
||||
|
@ -324,4 +407,4 @@ public class NacosValueAnnotationBeanPostProcessor extends AnnotationInjectedBea
|
|||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,331 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.spring.context.annotation.config;
|
||||
|
||||
import com.alibaba.nacos.common.utils.MD5Utils;
|
||||
import com.alibaba.nacos.spring.beans.factory.annotation.AbstractAnnotationBeanPostProcessor;
|
||||
import com.alibaba.nacos.spring.context.event.config.NacosConfigReceivedEvent;
|
||||
import com.alibaba.nacos.spring.util.NacosUtils;
|
||||
import com.alibaba.nacos.spring.util.PlaceholderHelper;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.TypeConverter;
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.BeanFactoryAware;
|
||||
import org.springframework.beans.factory.annotation.InjectionMetadata;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.beans.factory.config.BeanExpressionContext;
|
||||
import org.springframework.beans.factory.config.BeanExpressionResolver;
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.context.ApplicationListener;
|
||||
import org.springframework.context.EnvironmentAware;
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.core.annotation.AnnotationAttributes;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Member;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.*;
|
||||
|
||||
import static org.springframework.core.annotation.AnnotationUtils.getAnnotation;
|
||||
|
||||
/**
|
||||
* @author wuhaoqiang
|
||||
* @since 1.1.2
|
||||
**/
|
||||
public class SpringValueAnnotationBeanPostProcessor
|
||||
extends AbstractAnnotationBeanPostProcessor implements BeanFactoryAware,
|
||||
EnvironmentAware, ApplicationListener<NacosConfigReceivedEvent> {
|
||||
|
||||
/**
|
||||
* The name of {@link SpringValueAnnotationBeanPostProcessor} bean.
|
||||
*/
|
||||
public static final String BEAN_NAME = "StringValueAnnotationBeanPostProcessor";
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(getClass());
|
||||
|
||||
/**
|
||||
* placeholder, valueTarget.
|
||||
*/
|
||||
private Map<String, List<StringValueTarget>> placeholderStringValueTargetMap = new HashMap<String, List<StringValueTarget>>();
|
||||
|
||||
private ConfigurableListableBeanFactory beanFactory;
|
||||
|
||||
private Environment environment;
|
||||
|
||||
private BeanExpressionResolver exprResolver;
|
||||
|
||||
private BeanExpressionContext exprContext;
|
||||
|
||||
public SpringValueAnnotationBeanPostProcessor() {
|
||||
super(Value.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
|
||||
if (!(beanFactory instanceof ConfigurableListableBeanFactory)) {
|
||||
throw new IllegalArgumentException(
|
||||
"StringValueAnnotationBeanPostProcessor requires a ConfigurableListableBeanFactory");
|
||||
}
|
||||
this.beanFactory = (ConfigurableListableBeanFactory) beanFactory;
|
||||
this.exprResolver = ((ConfigurableListableBeanFactory) beanFactory).getBeanExpressionResolver();
|
||||
this.exprContext = new BeanExpressionContext((ConfigurableListableBeanFactory) beanFactory, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setEnvironment(Environment environment) {
|
||||
this.environment = environment;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object doGetInjectedBean(AnnotationAttributes attributes, Object bean,
|
||||
String beanName, Class<?> injectedType,
|
||||
InjectionMetadata.InjectedElement injectedElement) throws Exception {
|
||||
Object value = resolveStringValue(attributes.getString("value"));
|
||||
Member member = injectedElement.getMember();
|
||||
if (member instanceof Field) {
|
||||
return convertIfNecessary((Field) member, value);
|
||||
}
|
||||
|
||||
if (member instanceof Method) {
|
||||
return convertIfNecessary((Method) member, value);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String buildInjectedObjectCacheKey(AnnotationAttributes attributes,
|
||||
Object bean, String beanName, Class<?> injectedType,
|
||||
InjectionMetadata.InjectedElement injectedElement) {
|
||||
return bean.getClass().getName() + attributes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object postProcessBeforeInitialization(Object bean, final String beanName)
|
||||
throws BeansException {
|
||||
|
||||
doWithFields(bean, beanName);
|
||||
|
||||
doWithMethods(bean, beanName);
|
||||
|
||||
return super.postProcessBeforeInitialization(bean, beanName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onApplicationEvent(NacosConfigReceivedEvent event) {
|
||||
if (StringUtils.isEmpty(event)) {
|
||||
return;
|
||||
}
|
||||
Map<String, Object> updateProperties = NacosUtils.toProperties(event.getContent(), event.getType());
|
||||
|
||||
for (Map.Entry<String, List<StringValueTarget>> entry : placeholderStringValueTargetMap
|
||||
.entrySet()) {
|
||||
|
||||
String key = environment.resolvePlaceholders(entry.getKey());
|
||||
// Process modified keys, excluding deleted keys
|
||||
if (!updateProperties.containsKey(key)) {
|
||||
continue;
|
||||
}
|
||||
String newValue = environment.getProperty(key);
|
||||
|
||||
if (newValue == null) {
|
||||
continue;
|
||||
}
|
||||
List<StringValueTarget> beanPropertyList = entry.getValue();
|
||||
for (StringValueTarget target : beanPropertyList) {
|
||||
String md5String = MD5Utils.md5Hex(newValue, "UTF-8");
|
||||
boolean isUpdate = !target.lastMD5.equals(md5String);
|
||||
if (isUpdate) {
|
||||
target.updateLastMD5(md5String);
|
||||
Object evaluatedValue = resolveStringValue(target.stringValueExpr);
|
||||
if (target.method == null) {
|
||||
setField(target, evaluatedValue);
|
||||
} else {
|
||||
setMethod(target, evaluatedValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Object resolveStringValue(String strVal) {
|
||||
String value = beanFactory.resolveEmbeddedValue(strVal);
|
||||
if (exprResolver != null && value != null) {
|
||||
return exprResolver.evaluate(value, exprContext);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
private Object convertIfNecessary(Field field, Object value) {
|
||||
TypeConverter converter = beanFactory.getTypeConverter();
|
||||
return converter.convertIfNecessary(value, field.getType(), field);
|
||||
}
|
||||
|
||||
private Object convertIfNecessary(Method method, Object value) {
|
||||
Class<?>[] paramTypes = method.getParameterTypes();
|
||||
Object[] arguments = new Object[paramTypes.length];
|
||||
|
||||
TypeConverter converter = beanFactory.getTypeConverter();
|
||||
|
||||
if (arguments.length == 1) {
|
||||
return converter.convertIfNecessary(value, paramTypes[0],
|
||||
new MethodParameter(method, 0));
|
||||
}
|
||||
|
||||
for (int i = 0; i < arguments.length; i++) {
|
||||
arguments[i] = converter.convertIfNecessary(value, paramTypes[i],
|
||||
new MethodParameter(method, i));
|
||||
}
|
||||
|
||||
return arguments;
|
||||
}
|
||||
|
||||
private void doWithFields(final Object bean, final String beanName) {
|
||||
ReflectionUtils.doWithFields(bean.getClass(),
|
||||
new ReflectionUtils.FieldCallback() {
|
||||
@Override
|
||||
public void doWith(Field field) throws IllegalArgumentException {
|
||||
Value annotation = getAnnotation(field, Value.class);
|
||||
doWithAnnotation(beanName, bean, annotation, field.getModifiers(),
|
||||
null, field);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void doWithMethods(final Object bean, final String beanName) {
|
||||
ReflectionUtils.doWithMethods(bean.getClass(),
|
||||
new ReflectionUtils.MethodCallback() {
|
||||
@Override
|
||||
public void doWith(Method method) throws IllegalArgumentException {
|
||||
Value annotation = getAnnotation(method, Value.class);
|
||||
doWithAnnotation(beanName, bean, annotation,
|
||||
method.getModifiers(), method, null);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void doWithAnnotation(String beanName, Object bean, Value annotation,
|
||||
int modifiers, Method method, Field field) {
|
||||
if (annotation != null) {
|
||||
if (Modifier.isStatic(modifiers)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Set<String> placeholderList = PlaceholderHelper.findPlaceholderKeys(annotation.value());
|
||||
for (String placeholder : placeholderList) {
|
||||
StringValueTarget stringValueTarget = new StringValueTarget(bean, beanName,
|
||||
method, field, annotation.value());
|
||||
put2ListMap(placeholderStringValueTargetMap, placeholder,
|
||||
stringValueTarget);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private <K, V> void put2ListMap(Map<K, List<V>> map, K key, V value) {
|
||||
List<V> valueList = map.get(key);
|
||||
if (valueList == null) {
|
||||
valueList = new ArrayList<V>();
|
||||
}
|
||||
valueList.add(value);
|
||||
map.put(key, valueList);
|
||||
}
|
||||
|
||||
private void setMethod(StringValueTarget stringValueTarget, Object propertyValue) {
|
||||
Method method = stringValueTarget.method;
|
||||
ReflectionUtils.makeAccessible(method);
|
||||
try {
|
||||
method.invoke(stringValueTarget.bean,
|
||||
convertIfNecessary(method, propertyValue));
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Update value with {} (method) in {} (bean) with {}",
|
||||
method.getName(), stringValueTarget.beanName, propertyValue);
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
if (logger.isErrorEnabled()) {
|
||||
logger.error("Can't update value with " + method.getName()
|
||||
+ " (method) in " + stringValueTarget.beanName + " (bean)", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void setField(final StringValueTarget stringValueTarget,
|
||||
final Object propertyValue) {
|
||||
final Object bean = stringValueTarget.bean;
|
||||
|
||||
Field field = stringValueTarget.field;
|
||||
|
||||
String fieldName = field.getName();
|
||||
|
||||
try {
|
||||
ReflectionUtils.makeAccessible(field);
|
||||
field.set(bean, convertIfNecessary(field, propertyValue));
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Update value of the {}" + " (field) in {} (bean) with {}",
|
||||
fieldName, stringValueTarget.beanName, propertyValue);
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
if (logger.isErrorEnabled()) {
|
||||
logger.error("Can't update value of the " + fieldName + " (field) in "
|
||||
+ stringValueTarget.beanName + " (bean)", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class StringValueTarget {
|
||||
|
||||
private final Object bean;
|
||||
|
||||
private final String beanName;
|
||||
|
||||
private final Method method;
|
||||
|
||||
private final Field field;
|
||||
|
||||
private String lastMD5;
|
||||
|
||||
private final String stringValueExpr;
|
||||
|
||||
StringValueTarget(Object bean, String beanName, Method method, Field field, String stringValueExpr) {
|
||||
this.bean = bean;
|
||||
|
||||
this.beanName = beanName;
|
||||
|
||||
this.method = method;
|
||||
|
||||
this.field = field;
|
||||
|
||||
this.lastMD5 = "";
|
||||
|
||||
this.stringValueExpr = stringValueExpr;
|
||||
}
|
||||
|
||||
protected void updateLastMD5(String newMD5) {
|
||||
this.lastMD5 = newMD5;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -16,22 +16,29 @@
|
|||
*/
|
||||
package com.alibaba.nacos.spring.context.annotation.discovery;
|
||||
|
||||
import static com.alibaba.nacos.api.PropertyKeyConst.PASSWORD;
|
||||
import static com.alibaba.nacos.api.PropertyKeyConst.USERNAME;
|
||||
import static com.alibaba.nacos.api.annotation.NacosProperties.ACCESS_KEY;
|
||||
import static com.alibaba.nacos.api.annotation.NacosProperties.CLUSTER_NAME;
|
||||
import static com.alibaba.nacos.api.annotation.NacosProperties.CONTEXT_PATH;
|
||||
import static com.alibaba.nacos.api.annotation.NacosProperties.ENCODE;
|
||||
import static com.alibaba.nacos.api.annotation.NacosProperties.ENDPOINT;
|
||||
import static com.alibaba.nacos.api.annotation.NacosProperties.NAMESPACE;
|
||||
import static com.alibaba.nacos.api.annotation.NacosProperties.SECRET_KEY;
|
||||
import static com.alibaba.nacos.api.annotation.NacosProperties.SERVER_ADDR;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
import com.alibaba.nacos.api.annotation.NacosInjected;
|
||||
import com.alibaba.nacos.api.annotation.NacosProperties;
|
||||
import com.alibaba.nacos.spring.context.annotation.NacosBeanDefinitionRegistrar;
|
||||
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
import static com.alibaba.nacos.api.PropertyKeyConst.PASSWORD;
|
||||
import static com.alibaba.nacos.api.PropertyKeyConst.USERNAME;
|
||||
import static com.alibaba.nacos.api.annotation.NacosProperties.*;
|
||||
|
||||
/**
|
||||
* Annotation for enabling Nacos discovery features.
|
||||
*
|
||||
|
@ -42,7 +49,7 @@ import static com.alibaba.nacos.api.annotation.NacosProperties.*;
|
|||
@Target({ ElementType.TYPE, ElementType.ANNOTATION_TYPE })
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@Import(NacosDiscoveryBeanDefinitionRegistrar.class)
|
||||
@Import({NacosDiscoveryBeanDefinitionRegistrar.class, EnableNacosDiscoveryAotProcessor.class})
|
||||
public @interface EnableNacosDiscovery {
|
||||
/**
|
||||
* The prefix of property name of Nacos discovery
|
||||
|
|
|
@ -0,0 +1,92 @@
|
|||
/*
|
||||
*
|
||||
* * Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* * contributor license agreements. See the NOTICE file distributed with
|
||||
* * this work for additional information regarding copyright ownership.
|
||||
* * The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* * (the "License"); you may not use this file except in compliance with
|
||||
* * the License. You may obtain a copy of the License at
|
||||
* *
|
||||
* * http://www.apache.org/licenses/LICENSE-2.0
|
||||
* *
|
||||
* * Unless required by applicable law or agreed to in writing, software
|
||||
* * distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* * See the License for the specific language governing permissions and
|
||||
* * limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.spring.context.annotation.discovery;
|
||||
|
||||
import com.alibaba.nacos.spring.util.aot.AotDetector;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.BeanFactoryAware;
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
|
||||
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
|
||||
import org.springframework.context.EnvironmentAware;
|
||||
import org.springframework.core.annotation.AnnotationAttributes;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.core.type.AnnotationMetadata;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import static com.alibaba.nacos.spring.util.NacosBeanUtils.*;
|
||||
|
||||
/**
|
||||
* {@link EnableNacosDiscovery} AotProcessor
|
||||
* Except for the operation of registering BeanDefinition, all other operations in {@link NacosDiscoveryBeanDefinitionRegistrar} must be done here
|
||||
* because spring will not call {@link NacosDiscoveryBeanDefinitionRegistrar#registerBeanDefinitions} in AOT.
|
||||
* @author SuperZ1999
|
||||
*/
|
||||
public class EnableNacosDiscoveryAotProcessor implements BeanDefinitionRegistryPostProcessor, EnvironmentAware, BeanFactoryAware {
|
||||
private Environment environment;
|
||||
|
||||
private BeanFactory beanFactory;
|
||||
|
||||
@Override
|
||||
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
|
||||
if (!AotDetector.useGeneratedArtifacts()) {
|
||||
return;
|
||||
}
|
||||
DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) this.beanFactory;
|
||||
Map<String, Object> beansWithAnnotation = beanFactory.getBeansWithAnnotation(EnableNacosDiscovery.class);
|
||||
Object[] beans = beansWithAnnotation.values().toArray();
|
||||
if (beans.length != 0) {
|
||||
// only handle the first one
|
||||
Class<?> aClass = beans[0].getClass();
|
||||
if (aClass.getAnnotation(EnableNacosDiscovery.class) == null) {
|
||||
// cglib proxy object
|
||||
aClass = aClass.getSuperclass();
|
||||
}
|
||||
AnnotationMetadata annotationMetadata = AnnotationMetadata.introspect(aClass);
|
||||
AnnotationAttributes attributes = AnnotationAttributes
|
||||
.fromMap(annotationMetadata
|
||||
.getAnnotationAttributes(EnableNacosDiscovery.class.getName()));
|
||||
|
||||
// Register Global Nacos Properties Bean
|
||||
registerGlobalNacosProperties(attributes, registry, environment,
|
||||
DISCOVERY_GLOBAL_NACOS_PROPERTIES_BEAN_NAME);
|
||||
registerGlobalNacosProperties(attributes, registry, environment,
|
||||
MAINTAIN_GLOBAL_NACOS_PROPERTIES_BEAN_NAME);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setEnvironment(Environment environment) {
|
||||
this.environment = environment;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
|
||||
this.beanFactory = beanFactory;
|
||||
}
|
||||
}
|
|
@ -16,8 +16,11 @@
|
|||
*/
|
||||
package com.alibaba.nacos.spring.context.annotation.discovery;
|
||||
|
||||
import com.alibaba.nacos.spring.context.annotation.config.EnableNacosConfig;
|
||||
import com.alibaba.nacos.spring.util.NacosBeanUtils;
|
||||
import static com.alibaba.nacos.spring.util.NacosBeanUtils.DISCOVERY_GLOBAL_NACOS_PROPERTIES_BEAN_NAME;
|
||||
import static com.alibaba.nacos.spring.util.NacosBeanUtils.MAINTAIN_GLOBAL_NACOS_PROPERTIES_BEAN_NAME;
|
||||
import static com.alibaba.nacos.spring.util.NacosBeanUtils.registerGlobalNacosProperties;
|
||||
import static com.alibaba.nacos.spring.util.NacosBeanUtils.registerNacosCommonBeans;
|
||||
import static com.alibaba.nacos.spring.util.NacosBeanUtils.registerNacosDiscoveryBeans;
|
||||
|
||||
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
||||
import org.springframework.context.EnvironmentAware;
|
||||
|
@ -27,11 +30,8 @@ import org.springframework.core.env.Environment;
|
|||
import org.springframework.core.env.PropertyResolver;
|
||||
import org.springframework.core.type.AnnotationMetadata;
|
||||
|
||||
import static com.alibaba.nacos.spring.util.NacosBeanUtils.DISCOVERY_GLOBAL_NACOS_PROPERTIES_BEAN_NAME;
|
||||
import static com.alibaba.nacos.spring.util.NacosBeanUtils.MAINTAIN_GLOBAL_NACOS_PROPERTIES_BEAN_NAME;
|
||||
import static com.alibaba.nacos.spring.util.NacosBeanUtils.registerGlobalNacosProperties;
|
||||
import static com.alibaba.nacos.spring.util.NacosBeanUtils.registerNacosCommonBeans;
|
||||
import static com.alibaba.nacos.spring.util.NacosBeanUtils.registerNacosDiscoveryBeans;
|
||||
import com.alibaba.nacos.spring.context.annotation.config.EnableNacosConfig;
|
||||
import com.alibaba.nacos.spring.util.NacosBeanUtils;
|
||||
|
||||
/**
|
||||
* Nacos Discovery {@link ImportBeanDefinitionRegistrar BeanDefinition Registrar}
|
||||
|
|
|
@ -16,22 +16,30 @@
|
|||
*/
|
||||
package com.alibaba.nacos.spring.context.config.xml;
|
||||
|
||||
import java.util.Properties;
|
||||
import static com.alibaba.nacos.api.annotation.NacosProperties.ACCESS_KEY;
|
||||
import static com.alibaba.nacos.api.annotation.NacosProperties.CLUSTER_NAME;
|
||||
import static com.alibaba.nacos.api.annotation.NacosProperties.ENCODE;
|
||||
import static com.alibaba.nacos.api.annotation.NacosProperties.ENDPOINT;
|
||||
import static com.alibaba.nacos.api.annotation.NacosProperties.NAMESPACE;
|
||||
import static com.alibaba.nacos.api.annotation.NacosProperties.PASSWORD;
|
||||
import static com.alibaba.nacos.api.annotation.NacosProperties.SECRET_KEY;
|
||||
import static com.alibaba.nacos.api.annotation.NacosProperties.SERVER_ADDR;
|
||||
import static com.alibaba.nacos.api.annotation.NacosProperties.USERNAME;
|
||||
import static com.alibaba.nacos.spring.util.NacosBeanUtils.GLOBAL_NACOS_PROPERTIES_BEAN_NAME;
|
||||
import static com.alibaba.nacos.spring.util.NacosBeanUtils.registerGlobalNacosProperties;
|
||||
|
||||
import com.alibaba.nacos.api.PropertyKeyConst;
|
||||
import com.alibaba.nacos.api.annotation.NacosProperties;
|
||||
import com.alibaba.nacos.spring.util.NacosBeanUtils;
|
||||
import org.w3c.dom.Element;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
||||
import org.springframework.beans.factory.xml.BeanDefinitionParser;
|
||||
import org.springframework.beans.factory.xml.ParserContext;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
import static com.alibaba.nacos.api.annotation.NacosProperties.*;
|
||||
import static com.alibaba.nacos.spring.util.NacosBeanUtils.GLOBAL_NACOS_PROPERTIES_BEAN_NAME;
|
||||
import static com.alibaba.nacos.spring.util.NacosBeanUtils.registerGlobalNacosProperties;
|
||||
import com.alibaba.nacos.api.PropertyKeyConst;
|
||||
import com.alibaba.nacos.api.annotation.NacosProperties;
|
||||
import com.alibaba.nacos.spring.util.NacosBeanUtils;
|
||||
|
||||
/**
|
||||
* Nacos Global {@link Properties} {@link BeanDefinitionParser} for
|
||||
|
|
|
@ -16,14 +16,14 @@
|
|||
*/
|
||||
package com.alibaba.nacos.spring.context.config.xml;
|
||||
|
||||
import com.alibaba.nacos.spring.context.annotation.NacosBeanDefinitionRegistrar;
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
||||
import org.springframework.beans.factory.xml.BeanDefinitionParser;
|
||||
import org.springframework.beans.factory.xml.ParserContext;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
import com.alibaba.nacos.spring.context.annotation.NacosBeanDefinitionRegistrar;
|
||||
|
||||
/**
|
||||
* Nacos Annotation Driven {@link BeanDefinitionParser} for XML element
|
||||
|
@ -37,6 +37,7 @@ public class NacosAnnotationDrivenBeanDefinitionParser implements BeanDefinition
|
|||
|
||||
@Override
|
||||
public BeanDefinition parse(Element element, ParserContext parserContext) {
|
||||
|
||||
// Get Environment
|
||||
Environment environment = parserContext.getDelegate().getReaderContext()
|
||||
.getReader().getEnvironment();
|
||||
|
|
|
@ -16,19 +16,19 @@
|
|||
*/
|
||||
package com.alibaba.nacos.spring.context.config.xml;
|
||||
|
||||
import com.alibaba.nacos.spring.context.annotation.config.NacosPropertySource;
|
||||
import static com.alibaba.nacos.spring.util.NacosBeanUtils.registerNacosPropertySourcePostProcessor;
|
||||
import static com.alibaba.nacos.spring.util.NacosBeanUtils.registerXmlNacosPropertySourceBuilder;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
import org.springframework.beans.factory.support.AbstractBeanDefinition;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
||||
import org.springframework.beans.factory.xml.AbstractBeanDefinitionParser;
|
||||
import org.springframework.beans.factory.xml.BeanDefinitionParser;
|
||||
import org.springframework.beans.factory.xml.ParserContext;
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
import static com.alibaba.nacos.spring.util.NacosBeanUtils.registerNacosPropertySourcePostProcessor;
|
||||
import static com.alibaba.nacos.spring.util.NacosBeanUtils.registerXmlNacosPropertySourceBuilder;
|
||||
import com.alibaba.nacos.spring.context.annotation.config.NacosPropertySource;
|
||||
|
||||
/**
|
||||
* Nacos Property Source {@link BeanDefinitionParser} for <nacos:property-source
|
||||
|
|
|
@ -16,12 +16,11 @@
|
|||
*/
|
||||
package com.alibaba.nacos.spring.context.config.xml;
|
||||
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.support.GenericBeanDefinition;
|
||||
import org.springframework.beans.factory.xml.XmlReaderContext;
|
||||
import org.springframework.context.annotation.PropertySource;
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
/**
|
||||
* Nacos {@link PropertySource} XML {@link BeanDefinition}
|
||||
|
@ -40,20 +39,20 @@ public class NacosPropertySourceXmlBeanDefinition extends GenericBeanDefinition
|
|||
setBeanClass(getClass());
|
||||
}
|
||||
|
||||
void setXmlReaderContext(XmlReaderContext xmlReaderContext) {
|
||||
this.xmlReaderContext = xmlReaderContext;
|
||||
public Element getElement() {
|
||||
return element;
|
||||
}
|
||||
|
||||
void setElement(Element element) {
|
||||
this.element = element;
|
||||
}
|
||||
|
||||
public Element getElement() {
|
||||
return element;
|
||||
}
|
||||
|
||||
public XmlReaderContext getXmlReaderContext() {
|
||||
return xmlReaderContext;
|
||||
}
|
||||
|
||||
void setXmlReaderContext(XmlReaderContext xmlReaderContext) {
|
||||
this.xmlReaderContext = xmlReaderContext;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -16,13 +16,18 @@
|
|||
*/
|
||||
package com.alibaba.nacos.spring.context.event;
|
||||
|
||||
import static com.alibaba.nacos.spring.util.NacosUtils.resolveGenericType;
|
||||
import static java.lang.reflect.Modifier.isAbstract;
|
||||
import static java.lang.reflect.Modifier.isNative;
|
||||
import static java.lang.reflect.Modifier.isPublic;
|
||||
import static java.lang.reflect.Modifier.isStatic;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.aop.support.AopUtils;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationListener;
|
||||
|
@ -30,12 +35,6 @@ import org.springframework.context.event.ContextRefreshedEvent;
|
|||
import org.springframework.core.annotation.AnnotationUtils;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
|
||||
import static com.alibaba.nacos.spring.util.NacosUtils.resolveGenericType;
|
||||
import static java.lang.reflect.Modifier.isAbstract;
|
||||
import static java.lang.reflect.Modifier.isNative;
|
||||
import static java.lang.reflect.Modifier.isPublic;
|
||||
import static java.lang.reflect.Modifier.isStatic;
|
||||
|
||||
/**
|
||||
* Listener {@link Method method} Processor
|
||||
* <p>
|
||||
|
@ -55,7 +54,7 @@ import static java.lang.reflect.Modifier.isStatic;
|
|||
public abstract class AnnotationListenerMethodProcessor<A extends Annotation>
|
||||
implements ApplicationListener<ContextRefreshedEvent> {
|
||||
|
||||
protected final Log logger = LogFactory.getLog(getClass());
|
||||
protected final Logger logger = LoggerFactory.getLogger(getClass());
|
||||
private final Class<A> annotationType;
|
||||
|
||||
public AnnotationListenerMethodProcessor() {
|
||||
|
@ -95,7 +94,8 @@ public abstract class AnnotationListenerMethodProcessor<A extends Annotation>
|
|||
|
||||
private void processBeans(ApplicationContext applicationContext) {
|
||||
|
||||
Map<String, Object> beansMap = applicationContext.getBeansOfType(Object.class, false, false);
|
||||
Map<String, Object> beansMap = applicationContext.getBeansOfType(Object.class,
|
||||
false, false);
|
||||
|
||||
processBeans(beansMap, applicationContext);
|
||||
|
||||
|
|
|
@ -35,7 +35,6 @@ import org.springframework.context.support.AbstractApplicationContext;
|
|||
* hold all early {@link ApplicationEvent events} temporary until
|
||||
* {@link ConfigurableApplicationContext#isRunning() Spring ApplicationContext is active},
|
||||
* and then those {@link ApplicationEvent events} will be replayed.
|
||||
*
|
||||
* @author <a href="mailto:mercyblitz@gmail.com">Mercy</a>
|
||||
* @since 0.1.0
|
||||
*/
|
||||
|
@ -68,6 +67,10 @@ public class DeferredApplicationEventPublisher
|
|||
}
|
||||
}
|
||||
|
||||
public void publishEvent(Object event) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onApplicationEvent(ContextRefreshedEvent event) {
|
||||
|
||||
|
|
|
@ -16,12 +16,16 @@
|
|||
*/
|
||||
package com.alibaba.nacos.spring.context.event;
|
||||
|
||||
import com.alibaba.nacos.spring.context.event.config.NacosConfigMetadataEvent;
|
||||
import com.alibaba.nacos.api.annotation.NacosProperties;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import org.springframework.context.ApplicationListener;
|
||||
|
||||
import com.alibaba.nacos.spring.context.event.config.NacosConfigMetadataEvent;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Logging {@link NacosConfigMetadataEvent} {@link ApplicationListener}
|
||||
*
|
||||
|
@ -35,23 +39,57 @@ public class LoggingNacosConfigMetadataEventListener
|
|||
* The bean name of {@link LoggingNacosConfigMetadataEventListener}
|
||||
*/
|
||||
public static final String BEAN_NAME = "loggingNacosConfigMetadataEventListener";
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(getClass());
|
||||
|
||||
private final static String LOGGING_MESSAGE = "Nacos Config Metadata : "
|
||||
+ "dataId='{}'" + ", groupId='{}'" + ", beanName='{}'" + ", bean='{}'"
|
||||
+ ", beanType='{}'" + ", annotatedElement='{}'" + ", xmlResource='{}'"
|
||||
+ ", nacosProperties='{}'" + ", nacosPropertiesAttributes='{}'"
|
||||
+ ", source='{}'" + ", timestamp='{}'";
|
||||
private final Logger logger = LoggerFactory.getLogger(getClass());
|
||||
|
||||
@Override
|
||||
public void onApplicationEvent(NacosConfigMetadataEvent event) {
|
||||
if (logger.isInfoEnabled()) {
|
||||
logger.info(LOGGING_MESSAGE, event.getDataId(), event.getGroupId(),
|
||||
event.getBeanName(), event.getBean(), event.getBeanType(),
|
||||
event.getAnnotatedElement(), event.getXmlResource(),
|
||||
event.getNacosProperties(), event.getNacosPropertiesAttributes(),
|
||||
event.getSource(), event.getTimestamp());
|
||||
if (!logger.isInfoEnabled()) {
|
||||
return;
|
||||
}
|
||||
logger.info(LOGGING_MESSAGE, event.getDataId(), event.getGroupId(),
|
||||
event.getBeanName(), event.getBean(), event.getBeanType(),
|
||||
event.getAnnotatedElement(), event.getXmlResource(),
|
||||
obscuresNacosProperties(event.getNacosProperties()), event.getNacosPropertiesAttributes(),
|
||||
event.getSource(), event.getTimestamp());
|
||||
}
|
||||
|
||||
/**
|
||||
* obscures some private field like password in {@link com.alibaba.nacos.api.annotation.NacosProperties}
|
||||
* @param nacosProperties {@link com.alibaba.nacos.api.annotation.NacosProperties}
|
||||
* @return the properties String after obscures
|
||||
*/
|
||||
private String obscuresNacosProperties(Map<Object, Object> nacosProperties) {
|
||||
String nacosPropertyStr;
|
||||
if (nacosProperties != null && nacosProperties.size() > 0) {
|
||||
StringBuilder sb = new StringBuilder("{");
|
||||
int size = nacosProperties.size();
|
||||
int idx = 0;
|
||||
for (Map.Entry<Object, Object> e : nacosProperties.entrySet()) {
|
||||
Object key = e.getKey();
|
||||
Object value = e.getValue();
|
||||
sb.append(key);
|
||||
sb.append('=');
|
||||
// hide some private messages
|
||||
if (key != null && NacosProperties.PASSWORD.equals(key.toString())) {
|
||||
sb.append("******");
|
||||
} else {
|
||||
sb.append(value);
|
||||
}
|
||||
if (idx < size - 1) {
|
||||
sb.append(", ");
|
||||
}
|
||||
idx ++;
|
||||
}
|
||||
sb.append("}");
|
||||
nacosPropertyStr = sb.toString();
|
||||
} else {
|
||||
nacosPropertyStr = "{}";
|
||||
}
|
||||
return nacosPropertyStr;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,12 +18,12 @@ package com.alibaba.nacos.spring.context.event.config;
|
|||
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
|
||||
import com.alibaba.nacos.api.config.ConfigService;
|
||||
import com.alibaba.nacos.api.config.ConfigType;
|
||||
import com.alibaba.nacos.api.config.listener.Listener;
|
||||
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
|
||||
/**
|
||||
* A Delegating {@link NacosConfigReceivedEvent Event} Publishing {@link Listener} of
|
||||
* Nacos Config {@link Listener} with dataId, groupId and {@link ConfigService} instance.
|
||||
|
|
|
@ -14,27 +14,30 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.spring.context.event.config;
|
||||
|
||||
import java.util.Properties;
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
import org.springframework.beans.factory.DisposableBean;
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
|
||||
import com.alibaba.nacos.api.config.ConfigService;
|
||||
import com.alibaba.nacos.api.config.listener.Listener;
|
||||
import com.alibaba.nacos.api.exception.NacosException;
|
||||
import com.alibaba.nacos.spring.context.event.DeferredApplicationEventPublisher;
|
||||
import com.alibaba.nacos.spring.metadata.NacosServiceMetaData;
|
||||
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
|
||||
/**
|
||||
* {@link NacosConfigEvent Event} publishing {@link ConfigService}
|
||||
* {@link NacosConfigEvent Event} publishing {@link ConfigService}.
|
||||
*
|
||||
* @author <a href="mailto:mercyblitz@gmail.com">Mercy</a>
|
||||
* @since 0.1.0
|
||||
*/
|
||||
public class EventPublishingConfigService implements ConfigService, NacosServiceMetaData {
|
||||
public class EventPublishingConfigService
|
||||
implements ConfigService, NacosServiceMetaData, DisposableBean {
|
||||
|
||||
private final ConfigService configService;
|
||||
|
||||
|
@ -79,13 +82,13 @@ public class EventPublishingConfigService implements ConfigService, NacosService
|
|||
|
||||
/**
|
||||
* Implementation of the new version of support for multiple configuration file type
|
||||
* resolution
|
||||
* resolution.
|
||||
*
|
||||
* @param dataId dataId
|
||||
* @param group group
|
||||
* @param type config's type
|
||||
* @param listener listener
|
||||
* @throws NacosException
|
||||
* @throws NacosException NacosException
|
||||
*/
|
||||
public void addListener(String dataId, String group, String type, Listener listener)
|
||||
throws NacosException {
|
||||
|
@ -110,7 +113,32 @@ public class EventPublishingConfigService implements ConfigService, NacosService
|
|||
published));
|
||||
return published;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean publishConfig(String dataId, String group, String content, String type) throws NacosException {
|
||||
boolean published = configService.publishConfig(dataId, group, content, type);
|
||||
publishEvent(new NacosConfigPublishedEvent(configService, dataId, group, content,
|
||||
published));
|
||||
return published;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean publishConfigCas(String dataId, String group, String content, String casMd5) throws NacosException {
|
||||
boolean published = configService.publishConfigCas(dataId, group, content, casMd5);
|
||||
publishEvent(new NacosConfigPublishedEvent(configService, dataId, group, content,
|
||||
published));
|
||||
return published;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean publishConfigCas(String dataId, String group, String content, String casMd5, String type)
|
||||
throws NacosException {
|
||||
boolean published = configService.publishConfigCas(dataId, group, content, casMd5, type);
|
||||
publishEvent(new NacosConfigPublishedEvent(configService, dataId, group, content,
|
||||
published));
|
||||
return published;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeConfig(String dataId, String group) throws NacosException {
|
||||
boolean removed = configService.removeConfig(dataId, group);
|
||||
|
@ -130,6 +158,11 @@ public class EventPublishingConfigService implements ConfigService, NacosService
|
|||
return configService.getServerStatus();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void shutDown() throws NacosException {
|
||||
configService.shutDown();
|
||||
}
|
||||
|
||||
private void publishEvent(NacosConfigEvent nacosConfigEvent) {
|
||||
applicationEventPublisher.publishEvent(nacosConfigEvent);
|
||||
}
|
||||
|
@ -138,4 +171,14 @@ public class EventPublishingConfigService implements ConfigService, NacosService
|
|||
public Properties getProperties() {
|
||||
return properties;
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroy lifecycle method to invoke {@link #shutDown()}
|
||||
* @throws Exception throw exception
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@Override
|
||||
public void destroy() throws Exception {
|
||||
shutDown();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,10 +16,10 @@
|
|||
*/
|
||||
package com.alibaba.nacos.spring.context.event.config;
|
||||
|
||||
import com.alibaba.nacos.api.config.ConfigService;
|
||||
|
||||
import org.springframework.context.ApplicationEvent;
|
||||
|
||||
import com.alibaba.nacos.api.config.ConfigService;
|
||||
|
||||
/**
|
||||
* The Event of Nacos Configuration is used on Spring Event
|
||||
*
|
||||
|
|
|
@ -20,15 +20,14 @@ import java.lang.annotation.Annotation;
|
|||
import java.lang.reflect.AnnotatedElement;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.springframework.context.ApplicationEvent;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
import com.alibaba.nacos.api.config.annotation.NacosConfigListener;
|
||||
import com.alibaba.nacos.api.config.annotation.NacosConfigurationProperties;
|
||||
import com.alibaba.nacos.spring.context.annotation.config.NacosPropertySource;
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
import org.springframework.context.ApplicationEvent;
|
||||
import org.springframework.core.io.Resource;
|
||||
|
||||
/**
|
||||
* Nacos Config Meta-Data {@link NacosConfigEvent event}
|
||||
|
@ -52,7 +51,7 @@ public class NacosConfigMetadataEvent extends ApplicationEvent {
|
|||
|
||||
private Resource xmlResource;
|
||||
|
||||
private Properties nacosProperties;
|
||||
private Map<Object, Object> nacosProperties;
|
||||
|
||||
private Map<String, Object> nacosPropertiesAttributes;
|
||||
|
||||
|
@ -139,20 +138,20 @@ public class NacosConfigMetadataEvent extends ApplicationEvent {
|
|||
}
|
||||
|
||||
/**
|
||||
* Actual effective Nacos {@link Properties}
|
||||
* Actual effective Nacos {@link Map}
|
||||
*
|
||||
* @return non-null
|
||||
*/
|
||||
public Properties getNacosProperties() {
|
||||
public Map<Object, Object> getNacosProperties() {
|
||||
return nacosProperties;
|
||||
}
|
||||
|
||||
public void setNacosProperties(Properties nacosProperties) {
|
||||
public void setNacosProperties(Map<Object, Object> nacosProperties) {
|
||||
this.nacosProperties = nacosProperties;
|
||||
}
|
||||
|
||||
/**
|
||||
* Nacos {@link Properties}'s attributes that may come frome {@link Annotation} or
|
||||
* Nacos {@link Map}'s attributes that may come frome {@link Annotation} or
|
||||
* {@link Element XML element}
|
||||
*
|
||||
* @return non-null
|
||||
|
|
|
@ -25,11 +25,12 @@ import java.util.concurrent.TimeUnit;
|
|||
import java.util.concurrent.TimeoutException;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import com.alibaba.nacos.api.config.listener.AbstractListener;
|
||||
import com.alibaba.nacos.api.config.listener.Listener;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.alibaba.nacos.api.config.listener.AbstractListener;
|
||||
import com.alibaba.nacos.api.config.listener.Listener;
|
||||
|
||||
/**
|
||||
* Timeout {@link Listener Nacos Config Listener}
|
||||
*
|
||||
|
|
|
@ -16,9 +16,24 @@
|
|||
*/
|
||||
package com.alibaba.nacos.spring.context.properties.config;
|
||||
|
||||
import static com.alibaba.nacos.spring.util.NacosBeanUtils.getConfigServiceBeanBuilder;
|
||||
import static com.alibaba.nacos.spring.util.NacosUtils.getContent;
|
||||
import static org.springframework.core.annotation.AnnotationUtils.findAnnotation;
|
||||
import static org.springframework.core.annotation.AnnotationUtils.getAnnotationAttributes;
|
||||
import static org.springframework.util.StringUtils.hasText;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.PropertyValues;
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.validation.DataBinder;
|
||||
|
||||
import com.alibaba.nacos.api.annotation.NacosProperties;
|
||||
import com.alibaba.nacos.api.config.ConfigService;
|
||||
import com.alibaba.nacos.api.config.ConfigType;
|
||||
|
@ -33,22 +48,6 @@ import com.alibaba.nacos.spring.context.event.config.NacosConfigMetadataEvent;
|
|||
import com.alibaba.nacos.spring.context.event.config.NacosConfigurationPropertiesBeanBoundEvent;
|
||||
import com.alibaba.nacos.spring.util.NacosUtils;
|
||||
import com.alibaba.nacos.spring.util.ObjectUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import org.springframework.beans.PropertyValues;
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.validation.DataBinder;
|
||||
|
||||
import static com.alibaba.nacos.spring.util.NacosBeanUtils.getConfigServiceBeanBuilder;
|
||||
import static com.alibaba.nacos.spring.util.NacosUtils.getContent;
|
||||
import static org.springframework.core.annotation.AnnotationUtils.findAnnotation;
|
||||
import static org.springframework.core.annotation.AnnotationUtils.getAnnotationAttributes;
|
||||
import static org.springframework.util.StringUtils.hasText;
|
||||
|
||||
/**
|
||||
* {@link NacosConfigurationProperties} Bean Binder
|
||||
|
@ -102,17 +101,28 @@ public class NacosConfigurationPropertiesBinder {
|
|||
environment);
|
||||
final String groupId = NacosUtils.readFromEnvironment(properties.groupId(),
|
||||
environment);
|
||||
String fileType = NacosUtils.readTypeFromDataId(dataId);
|
||||
final String type = StringUtils.isEmpty(fileType)
|
||||
? (properties.yaml() ? ConfigType.YAML.getType()
|
||||
: properties.type().getType())
|
||||
: fileType;
|
||||
final String type;
|
||||
|
||||
ConfigType typeEunm = properties.type();
|
||||
if (ConfigType.UNSET.equals(typeEunm)) {
|
||||
type = NacosUtils.readFileExtension(dataId);
|
||||
}
|
||||
else {
|
||||
type = typeEunm.getType();
|
||||
}
|
||||
|
||||
final ConfigService configService = configServiceBeanBuilder
|
||||
.build(properties.properties());
|
||||
|
||||
// Add a Listener if auto-refreshed
|
||||
if (properties.autoRefreshed()) {
|
||||
|
||||
String content = getContent(configService, dataId, groupId);
|
||||
|
||||
if (hasText(content)) {
|
||||
doBind(bean, beanName, dataId, groupId, type, properties, content,
|
||||
configService);
|
||||
}
|
||||
|
||||
Listener listener = new AbstractListener() {
|
||||
@Override
|
||||
|
@ -136,13 +146,6 @@ public class NacosConfigurationPropertiesBinder {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
String content = getContent(configService, dataId, groupId);
|
||||
|
||||
if (hasText(content)) {
|
||||
doBind(bean, beanName, dataId, groupId, type, properties, content,
|
||||
configService);
|
||||
}
|
||||
}
|
||||
|
||||
protected void doBind(Object bean, String beanName, String dataId, String groupId,
|
||||
|
|
|
@ -16,10 +16,9 @@
|
|||
*/
|
||||
package com.alibaba.nacos.spring.context.properties.config;
|
||||
|
||||
import java.util.Properties;
|
||||
import static org.springframework.core.annotation.AnnotationUtils.findAnnotation;
|
||||
|
||||
import com.alibaba.nacos.api.config.annotation.NacosConfigurationProperties;
|
||||
import com.alibaba.nacos.spring.factory.NacosServiceFactory;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.config.BeanPostProcessor;
|
||||
|
@ -29,7 +28,8 @@ import org.springframework.context.ApplicationEventPublisher;
|
|||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.core.env.Environment;
|
||||
|
||||
import static org.springframework.core.annotation.AnnotationUtils.findAnnotation;
|
||||
import com.alibaba.nacos.api.config.annotation.NacosConfigurationProperties;
|
||||
import com.alibaba.nacos.spring.factory.NacosServiceFactory;
|
||||
|
||||
/**
|
||||
* {@link NacosConfigurationProperties} Binding {@link BeanPostProcessor}
|
||||
|
|
|
@ -16,14 +16,13 @@
|
|||
*/
|
||||
package com.alibaba.nacos.spring.convert.converter.config;
|
||||
|
||||
import com.alibaba.nacos.api.config.convert.NacosConfigConverter;
|
||||
import java.util.Map;
|
||||
|
||||
import com.alibaba.nacos.spring.util.ConfigParse;
|
||||
import com.alibaba.nacos.spring.util.ConfigParseUtils;
|
||||
import org.springframework.core.convert.ConversionService;
|
||||
import org.springframework.format.support.DefaultFormattingConversionService;
|
||||
|
||||
import java.util.Map;
|
||||
import com.alibaba.nacos.api.config.convert.NacosConfigConverter;
|
||||
import com.alibaba.nacos.spring.util.ConfigParseUtils;
|
||||
|
||||
/**
|
||||
* Default {@link NacosConfigConverter} implementation
|
||||
|
|
|
@ -16,36 +16,6 @@
|
|||
*/
|
||||
package com.alibaba.nacos.spring.core.env;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
import com.alibaba.nacos.api.config.ConfigType;
|
||||
import com.alibaba.nacos.spring.context.event.DeferredApplicationEventPublisher;
|
||||
import com.alibaba.nacos.spring.context.event.config.NacosConfigMetadataEvent;
|
||||
import com.alibaba.nacos.spring.util.NacosUtils;
|
||||
import com.alibaba.nacos.spring.util.config.NacosConfigLoader;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.BeanClassLoaderAware;
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.BeanFactoryAware;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.context.EnvironmentAware;
|
||||
import org.springframework.core.env.ConfigurableEnvironment;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import static com.alibaba.nacos.spring.context.annotation.config.NacosPropertySource.CONFIG_TYPE_ATTRIBUTE_NAME;
|
||||
import static com.alibaba.nacos.spring.context.annotation.config.NacosPropertySource.DATA_ID_ATTRIBUTE_NAME;
|
||||
import static com.alibaba.nacos.spring.context.annotation.config.NacosPropertySource.GROUP_ID_ATTRIBUTE_NAME;
|
||||
|
@ -59,6 +29,38 @@ import static com.alibaba.spring.util.ClassUtils.resolveGenericType;
|
|||
import static java.lang.String.format;
|
||||
import static org.springframework.util.ClassUtils.resolveClassName;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
import com.alibaba.nacos.api.config.ConfigService;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.BeanClassLoaderAware;
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.BeanFactoryAware;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.beans.factory.DisposableBean;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.context.EnvironmentAware;
|
||||
import org.springframework.core.env.ConfigurableEnvironment;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import com.alibaba.nacos.api.config.ConfigType;
|
||||
import com.alibaba.nacos.spring.context.event.DeferredApplicationEventPublisher;
|
||||
import com.alibaba.nacos.spring.context.event.config.NacosConfigMetadataEvent;
|
||||
import com.alibaba.nacos.spring.util.NacosUtils;
|
||||
import com.alibaba.nacos.spring.util.config.NacosConfigLoader;
|
||||
|
||||
/**
|
||||
* Abstract implementation of {@link NacosPropertySource} Builder
|
||||
*
|
||||
|
@ -68,20 +70,14 @@ import static org.springframework.util.ClassUtils.resolveClassName;
|
|||
*/
|
||||
public abstract class AbstractNacosPropertySourceBuilder<T extends BeanDefinition>
|
||||
implements EnvironmentAware, BeanFactoryAware, BeanClassLoaderAware,
|
||||
ApplicationContextAware, InitializingBean {
|
||||
ApplicationContextAware, InitializingBean, DisposableBean {
|
||||
|
||||
protected final Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||
|
||||
protected ConfigurableEnvironment environment;
|
||||
|
||||
protected BeanFactory beanFactory;
|
||||
|
||||
private NacosConfigLoader nacosConfigLoader;
|
||||
|
||||
private Properties globalNacosProperties;
|
||||
|
||||
private final Class<T> beanDefinitionType;
|
||||
|
||||
protected ConfigurableEnvironment environment;
|
||||
protected BeanFactory beanFactory;
|
||||
private NacosConfigLoader nacosConfigLoader;
|
||||
private Properties globalNacosProperties;
|
||||
private ClassLoader classLoader;
|
||||
|
||||
private ApplicationEventPublisher applicationEventPublisher;
|
||||
|
@ -165,13 +161,20 @@ public abstract class AbstractNacosPropertySourceBuilder<T extends BeanDefinitio
|
|||
String name = (String) runtimeAttributes.get(NAME_ATTRIBUTE_NAME);
|
||||
String dataId = (String) runtimeAttributes.get(DATA_ID_ATTRIBUTE_NAME);
|
||||
String groupId = (String) runtimeAttributes.get(GROUP_ID_ATTRIBUTE_NAME);
|
||||
String type = ((ConfigType) runtimeAttributes.get(CONFIG_TYPE_ATTRIBUTE_NAME))
|
||||
.getType();
|
||||
|
||||
dataId = NacosUtils.readFromEnvironment(dataId, environment);
|
||||
groupId = NacosUtils.readFromEnvironment(groupId, environment);
|
||||
type = StringUtils.isEmpty(NacosUtils.readTypeFromDataId(dataId)) ? type
|
||||
: NacosUtils.readTypeFromDataId(dataId);
|
||||
|
||||
final String type;
|
||||
|
||||
ConfigType typeEunm = (ConfigType) runtimeAttributes.get(CONFIG_TYPE_ATTRIBUTE_NAME);
|
||||
if (ConfigType.UNSET.equals(typeEunm)) {
|
||||
type = NacosUtils.readFileExtension(dataId);
|
||||
}
|
||||
else {
|
||||
type = typeEunm.getType();
|
||||
}
|
||||
|
||||
Map<String, Object> nacosPropertiesAttributes = (Map<String, Object>) runtimeAttributes
|
||||
.get(PROPERTIES_ATTRIBUTE_NAME);
|
||||
|
||||
|
@ -272,6 +275,17 @@ public abstract class AbstractNacosPropertySourceBuilder<T extends BeanDefinitio
|
|||
globalNacosProperties = CONFIG.getMergedGlobalProperties(beanFactory);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy() throws Exception {
|
||||
if (nacosConfigLoader == null) {
|
||||
return;
|
||||
}
|
||||
ConfigService configService = nacosConfigLoader.getConfigService();
|
||||
if (configService != null) {
|
||||
configService.shutDown();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The type of {@link T Bean Definition}
|
||||
*
|
||||
|
|
|
@ -16,6 +16,11 @@
|
|||
*/
|
||||
package com.alibaba.nacos.spring.core.env;
|
||||
|
||||
import static com.alibaba.nacos.spring.context.annotation.config.NacosPropertySource.AFTER_ATTRIBUTE_NAME;
|
||||
import static com.alibaba.nacos.spring.context.annotation.config.NacosPropertySource.AUTO_REFRESHED_ATTRIBUTE_NAME;
|
||||
import static com.alibaba.nacos.spring.context.annotation.config.NacosPropertySource.BEFORE_ATTRIBUTE_NAME;
|
||||
import static com.alibaba.nacos.spring.context.annotation.config.NacosPropertySource.FIRST_ATTRIBUTE_NAME;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
@ -23,16 +28,11 @@ import java.util.Map;
|
|||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
|
||||
import com.alibaba.nacos.spring.context.annotation.config.NacosPropertySources;
|
||||
import com.alibaba.nacos.spring.context.event.config.NacosConfigMetadataEvent;
|
||||
|
||||
import org.springframework.beans.factory.annotation.AnnotatedBeanDefinition;
|
||||
import org.springframework.core.type.AnnotationMetadata;
|
||||
|
||||
import static com.alibaba.nacos.spring.context.annotation.config.NacosPropertySource.AFTER_ATTRIBUTE_NAME;
|
||||
import static com.alibaba.nacos.spring.context.annotation.config.NacosPropertySource.AUTO_REFRESHED_ATTRIBUTE_NAME;
|
||||
import static com.alibaba.nacos.spring.context.annotation.config.NacosPropertySource.BEFORE_ATTRIBUTE_NAME;
|
||||
import static com.alibaba.nacos.spring.context.annotation.config.NacosPropertySource.FIRST_ATTRIBUTE_NAME;
|
||||
import com.alibaba.nacos.spring.context.annotation.config.NacosPropertySources;
|
||||
import com.alibaba.nacos.spring.context.event.config.NacosConfigMetadataEvent;
|
||||
|
||||
/**
|
||||
* Annotation {@link NacosPropertySource @NacosPropertySource}
|
||||
|
|
|
@ -16,15 +16,14 @@
|
|||
*/
|
||||
package com.alibaba.nacos.spring.core.env;
|
||||
|
||||
import static com.alibaba.nacos.spring.util.NacosUtils.toProperties;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.springframework.core.env.PropertiesPropertySource;
|
||||
import org.springframework.core.env.MapPropertySource;
|
||||
import org.springframework.core.env.PropertySource;
|
||||
|
||||
import static com.alibaba.nacos.spring.util.NacosUtils.toProperties;
|
||||
|
||||
/**
|
||||
* Nacos {@link PropertySource}, all read methods are immutable.
|
||||
*
|
||||
|
@ -32,7 +31,7 @@ import static com.alibaba.nacos.spring.util.NacosUtils.toProperties;
|
|||
* @see com.alibaba.nacos.spring.context.annotation.config.NacosPropertySource
|
||||
* @since 0.1.0
|
||||
*/
|
||||
public class NacosPropertySource extends PropertiesPropertySource {
|
||||
public class NacosPropertySource extends MapPropertySource {
|
||||
|
||||
private String groupId;
|
||||
|
||||
|
@ -48,7 +47,7 @@ public class NacosPropertySource extends PropertiesPropertySource {
|
|||
|
||||
private String type;
|
||||
|
||||
private Properties properties;
|
||||
private Map<Object, Object> properties;
|
||||
|
||||
private Map<String, Object> attributesMetadata;
|
||||
|
||||
|
@ -58,10 +57,6 @@ public class NacosPropertySource extends PropertiesPropertySource {
|
|||
|
||||
private Class<?> beanType;
|
||||
|
||||
/**
|
||||
* @param name the name of Nacos {@link PropertySource}
|
||||
* @param nacosConfig the Nacos Config with {@link Properties} format
|
||||
*/
|
||||
public NacosPropertySource(String dataId, String groupId, String name,
|
||||
String nacosConfig, String type) {
|
||||
super(name, toProperties(dataId, groupId, nacosConfig, type));
|
||||
|
@ -124,30 +119,14 @@ public class NacosPropertySource extends PropertiesPropertySource {
|
|||
this.type = type;
|
||||
}
|
||||
|
||||
public Properties getProperties() {
|
||||
public Map<Object, Object> getProperties() {
|
||||
return properties;
|
||||
}
|
||||
|
||||
public void setProperties(Properties properties) {
|
||||
public void setProperties(Map<Object, Object> properties) {
|
||||
this.properties = properties;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param attributesMetadata the attributesMetadata of attributes from
|
||||
* {@link com.alibaba.nacos.spring.context.annotation.config.NacosPropertySource @NacosPropertySource}
|
||||
* or <nacos:property-source ... >
|
||||
*/
|
||||
public void setAttributesMetadata(Map<String, Object> attributesMetadata) {
|
||||
this.attributesMetadata = attributesMetadata;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param origin where Nacos {@link PropertySource} comes from
|
||||
*/
|
||||
public void setOrigin(Object origin) {
|
||||
this.origin = origin;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the attributesMetadata of attributes from
|
||||
* {@link com.alibaba.nacos.spring.context.annotation.config.NacosPropertySource @NacosPropertySource}
|
||||
|
@ -158,6 +137,15 @@ public class NacosPropertySource extends PropertiesPropertySource {
|
|||
: Collections.<String, Object> emptyMap();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param attributesMetadata the attributesMetadata of attributes from
|
||||
* {@link com.alibaba.nacos.spring.context.annotation.config.NacosPropertySource @NacosPropertySource}
|
||||
* or <nacos:property-source ... >
|
||||
*/
|
||||
public void setAttributesMetadata(Map<String, Object> attributesMetadata) {
|
||||
this.attributesMetadata = attributesMetadata;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return where Nacos {@link PropertySource} comes from
|
||||
*/
|
||||
|
@ -165,6 +153,13 @@ public class NacosPropertySource extends PropertiesPropertySource {
|
|||
return origin;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param origin where Nacos {@link PropertySource} comes from
|
||||
*/
|
||||
public void setOrigin(Object origin) {
|
||||
this.origin = origin;
|
||||
}
|
||||
|
||||
public String getBeanName() {
|
||||
return beanName;
|
||||
}
|
||||
|
|
|
@ -16,6 +16,11 @@
|
|||
*/
|
||||
package com.alibaba.nacos.spring.core.env;
|
||||
|
||||
import static com.alibaba.nacos.spring.util.NacosBeanUtils.getConfigServiceBeanBuilder;
|
||||
import static com.alibaba.nacos.spring.util.NacosBeanUtils.getNacosServiceFactoryBean;
|
||||
import static com.alibaba.nacos.spring.util.NacosUtils.DEFAULT_STRING_ATTRIBUTE_VALUE;
|
||||
import static org.springframework.util.ObjectUtils.nullSafeEquals;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
|
@ -24,19 +29,10 @@ import java.util.List;
|
|||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
|
||||
import com.alibaba.nacos.api.config.ConfigService;
|
||||
import com.alibaba.nacos.api.config.listener.AbstractListener;
|
||||
import com.alibaba.nacos.api.config.listener.Listener;
|
||||
import com.alibaba.nacos.api.exception.NacosException;
|
||||
import com.alibaba.nacos.spring.beans.factory.annotation.ConfigServiceBeanBuilder;
|
||||
import com.alibaba.nacos.spring.context.annotation.config.NacosPropertySources;
|
||||
import com.alibaba.nacos.spring.context.config.xml.NacosPropertySourceXmlBeanDefinition;
|
||||
import com.alibaba.nacos.spring.context.event.config.EventPublishingConfigService;
|
||||
import com.alibaba.nacos.spring.factory.NacosServiceFactory;
|
||||
import com.alibaba.spring.util.BeanUtils;
|
||||
|
||||
import com.alibaba.nacos.spring.util.aot.AotDetector;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.annotation.AnnotatedGenericBeanDefinition;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
|
@ -51,10 +47,16 @@ import org.springframework.core.env.Environment;
|
|||
import org.springframework.core.env.MutablePropertySources;
|
||||
import org.springframework.core.env.PropertySources;
|
||||
|
||||
import static com.alibaba.nacos.spring.util.NacosBeanUtils.getConfigServiceBeanBuilder;
|
||||
import static com.alibaba.nacos.spring.util.NacosBeanUtils.getNacosServiceFactoryBean;
|
||||
import static com.alibaba.nacos.spring.util.NacosUtils.DEFAULT_STRING_ATTRIBUTE_VALUE;
|
||||
import static org.springframework.util.ObjectUtils.nullSafeEquals;
|
||||
import com.alibaba.nacos.api.config.ConfigService;
|
||||
import com.alibaba.nacos.api.config.listener.AbstractListener;
|
||||
import com.alibaba.nacos.api.config.listener.Listener;
|
||||
import com.alibaba.nacos.api.exception.NacosException;
|
||||
import com.alibaba.nacos.spring.beans.factory.annotation.ConfigServiceBeanBuilder;
|
||||
import com.alibaba.nacos.spring.context.annotation.config.NacosPropertySources;
|
||||
import com.alibaba.nacos.spring.context.config.xml.NacosPropertySourceXmlBeanDefinition;
|
||||
import com.alibaba.nacos.spring.context.event.config.EventPublishingConfigService;
|
||||
import com.alibaba.nacos.spring.factory.NacosServiceFactory;
|
||||
import com.alibaba.spring.util.BeanUtils;
|
||||
|
||||
/**
|
||||
* {@link BeanFactoryPostProcessor Post Processor} resolves
|
||||
|
@ -80,108 +82,15 @@ public class NacosPropertySourcePostProcessor
|
|||
*/
|
||||
public static final String BEAN_NAME = "nacosPropertySourcePostProcessor";
|
||||
|
||||
private static BeanFactory beanFactory;
|
||||
protected static BeanFactory beanFactory;
|
||||
|
||||
private final Set<String> processedBeanNames = new LinkedHashSet<String>();
|
||||
protected final Set<String> processedBeanNames = new LinkedHashSet<String>();
|
||||
|
||||
private ConfigurableEnvironment environment;
|
||||
|
||||
private Collection<AbstractNacosPropertySourceBuilder> nacosPropertySourceBuilders;
|
||||
protected Collection<AbstractNacosPropertySourceBuilder> nacosPropertySourceBuilders;
|
||||
|
||||
private ConfigServiceBeanBuilder configServiceBeanBuilder;
|
||||
|
||||
@Override
|
||||
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry)
|
||||
throws BeansException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)
|
||||
throws BeansException {
|
||||
String[] abstractNacosPropertySourceBuilderBeanNames = BeanUtils
|
||||
.getBeanNames(beanFactory, AbstractNacosPropertySourceBuilder.class);
|
||||
|
||||
this.nacosPropertySourceBuilders = new ArrayList<AbstractNacosPropertySourceBuilder>(
|
||||
abstractNacosPropertySourceBuilderBeanNames.length);
|
||||
|
||||
for (String beanName : abstractNacosPropertySourceBuilderBeanNames) {
|
||||
this.nacosPropertySourceBuilders.add(beanFactory.getBean(beanName,
|
||||
AbstractNacosPropertySourceBuilder.class));
|
||||
}
|
||||
|
||||
NacosPropertySourcePostProcessor.beanFactory = beanFactory;
|
||||
this.configServiceBeanBuilder = getConfigServiceBeanBuilder(beanFactory);
|
||||
|
||||
String[] beanNames = beanFactory.getBeanDefinitionNames();
|
||||
|
||||
for (String beanName : beanNames) {
|
||||
processPropertySource(beanName, beanFactory);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void processPropertySource(String beanName,
|
||||
ConfigurableListableBeanFactory beanFactory) {
|
||||
|
||||
if (processedBeanNames.contains(beanName)) {
|
||||
return;
|
||||
}
|
||||
|
||||
BeanDefinition beanDefinition = beanFactory.getBeanDefinition(beanName);
|
||||
|
||||
// Build multiple instance if possible
|
||||
List<NacosPropertySource> nacosPropertySources = buildNacosPropertySources(
|
||||
beanName, beanDefinition);
|
||||
|
||||
// Add Orderly
|
||||
for (NacosPropertySource nacosPropertySource : nacosPropertySources) {
|
||||
addNacosPropertySource(nacosPropertySource);
|
||||
Properties properties = configServiceBeanBuilder
|
||||
.resolveProperties(nacosPropertySource.getAttributesMetadata());
|
||||
addListenerIfAutoRefreshed(nacosPropertySource, properties, environment);
|
||||
}
|
||||
|
||||
processedBeanNames.add(beanName);
|
||||
}
|
||||
|
||||
private List<NacosPropertySource> buildNacosPropertySources(String beanName,
|
||||
BeanDefinition beanDefinition) {
|
||||
for (AbstractNacosPropertySourceBuilder builder : nacosPropertySourceBuilders) {
|
||||
if (builder.supports(beanDefinition)) {
|
||||
return builder.build(beanName, beanDefinition);
|
||||
}
|
||||
}
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
private void addNacosPropertySource(NacosPropertySource nacosPropertySource) {
|
||||
|
||||
MutablePropertySources propertySources = environment.getPropertySources();
|
||||
|
||||
boolean first = nacosPropertySource.isFirst();
|
||||
String before = nacosPropertySource.getBefore();
|
||||
String after = nacosPropertySource.getAfter();
|
||||
|
||||
boolean hasBefore = !nullSafeEquals(DEFAULT_STRING_ATTRIBUTE_VALUE, before);
|
||||
boolean hasAfter = !nullSafeEquals(DEFAULT_STRING_ATTRIBUTE_VALUE, after);
|
||||
|
||||
boolean isRelative = hasBefore || hasAfter;
|
||||
|
||||
if (first) { // If First
|
||||
propertySources.addFirst(nacosPropertySource);
|
||||
}
|
||||
else if (isRelative) { // If relative
|
||||
if (hasBefore) {
|
||||
propertySources.addBefore(before, nacosPropertySource);
|
||||
}
|
||||
if (hasAfter) {
|
||||
propertySources.addAfter(after, nacosPropertySource);
|
||||
}
|
||||
}
|
||||
else {
|
||||
propertySources.addLast(nacosPropertySource); // default add last
|
||||
}
|
||||
}
|
||||
protected ConfigServiceBeanBuilder configServiceBeanBuilder;
|
||||
|
||||
public static void addListenerIfAutoRefreshed(
|
||||
final NacosPropertySource nacosPropertySource, final Properties properties,
|
||||
|
@ -233,6 +142,103 @@ public class NacosPropertySourcePostProcessor
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry)
|
||||
throws BeansException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)
|
||||
throws BeansException {
|
||||
String[] abstractNacosPropertySourceBuilderBeanNames = BeanUtils
|
||||
.getBeanNames(beanFactory, AbstractNacosPropertySourceBuilder.class);
|
||||
|
||||
this.nacosPropertySourceBuilders = new ArrayList<AbstractNacosPropertySourceBuilder>(
|
||||
abstractNacosPropertySourceBuilderBeanNames.length);
|
||||
|
||||
for (String beanName : abstractNacosPropertySourceBuilderBeanNames) {
|
||||
this.nacosPropertySourceBuilders.add(beanFactory.getBean(beanName,
|
||||
AbstractNacosPropertySourceBuilder.class));
|
||||
}
|
||||
|
||||
NacosPropertySourcePostProcessor.beanFactory = beanFactory;
|
||||
this.configServiceBeanBuilder = getConfigServiceBeanBuilder(beanFactory);
|
||||
|
||||
String[] beanNames = beanFactory.getBeanDefinitionNames();
|
||||
|
||||
for (String beanName : beanNames) {
|
||||
processPropertySource(beanName, beanFactory);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected void processPropertySource(String beanName,
|
||||
ConfigurableListableBeanFactory beanFactory) {
|
||||
|
||||
if (processedBeanNames.contains(beanName)) {
|
||||
return;
|
||||
}
|
||||
|
||||
BeanDefinition beanDefinition = beanFactory.getBeanDefinition(beanName);
|
||||
|
||||
doProcessPropertySource(beanName, beanDefinition);
|
||||
|
||||
processedBeanNames.add(beanName);
|
||||
}
|
||||
|
||||
protected void doProcessPropertySource(String beanName, BeanDefinition beanDefinition) {
|
||||
// Build multiple instance if possible
|
||||
List<NacosPropertySource> nacosPropertySources = buildNacosPropertySources(
|
||||
beanName, beanDefinition);
|
||||
|
||||
// Add Orderly
|
||||
for (NacosPropertySource nacosPropertySource : nacosPropertySources) {
|
||||
addNacosPropertySource(nacosPropertySource);
|
||||
Properties properties = configServiceBeanBuilder
|
||||
.resolveProperties(nacosPropertySource.getAttributesMetadata());
|
||||
addListenerIfAutoRefreshed(nacosPropertySource, properties, environment);
|
||||
}
|
||||
}
|
||||
|
||||
private List<NacosPropertySource> buildNacosPropertySources(String beanName,
|
||||
BeanDefinition beanDefinition) {
|
||||
for (AbstractNacosPropertySourceBuilder builder : nacosPropertySourceBuilders) {
|
||||
if (builder.supports(beanDefinition)) {
|
||||
return builder.build(beanName, beanDefinition);
|
||||
}
|
||||
}
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
private void addNacosPropertySource(NacosPropertySource nacosPropertySource) {
|
||||
|
||||
MutablePropertySources propertySources = environment.getPropertySources();
|
||||
|
||||
boolean first = nacosPropertySource.isFirst();
|
||||
String before = nacosPropertySource.getBefore();
|
||||
String after = nacosPropertySource.getAfter();
|
||||
|
||||
boolean hasBefore = !nullSafeEquals(DEFAULT_STRING_ATTRIBUTE_VALUE, before);
|
||||
boolean hasAfter = !nullSafeEquals(DEFAULT_STRING_ATTRIBUTE_VALUE, after);
|
||||
|
||||
boolean isRelative = hasBefore || hasAfter;
|
||||
|
||||
if (first) { // If First
|
||||
propertySources.addFirst(nacosPropertySource);
|
||||
}
|
||||
else if (isRelative) { // If relative
|
||||
if (hasBefore) {
|
||||
propertySources.addBefore(before, nacosPropertySource);
|
||||
}
|
||||
if (hasAfter) {
|
||||
propertySources.addAfter(after, nacosPropertySource);
|
||||
}
|
||||
}
|
||||
else {
|
||||
propertySources.addLast(nacosPropertySource); // default add last
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The order is closed to {@link ConfigurationClassPostProcessor#getOrder()
|
||||
* HIGHEST_PRECEDENCE} almost.
|
||||
|
|
|
@ -16,21 +16,6 @@
|
|||
*/
|
||||
package com.alibaba.nacos.spring.core.env;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
import com.alibaba.nacos.api.config.ConfigType;
|
||||
import com.alibaba.nacos.spring.context.config.xml.NacosPropertySourceXmlBeanDefinition;
|
||||
import com.alibaba.nacos.spring.context.event.config.NacosConfigMetadataEvent;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.NamedNodeMap;
|
||||
|
||||
import org.springframework.beans.factory.xml.XmlReaderContext;
|
||||
import org.springframework.core.convert.ConversionService;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import static com.alibaba.nacos.api.common.Constants.DEFAULT_GROUP;
|
||||
import static com.alibaba.nacos.spring.context.annotation.config.NacosPropertySource.AFTER_ATTRIBUTE_NAME;
|
||||
import static com.alibaba.nacos.spring.context.annotation.config.NacosPropertySource.AUTO_REFRESHED_ATTRIBUTE_NAME;
|
||||
|
@ -45,6 +30,21 @@ import static com.alibaba.nacos.spring.util.NacosUtils.DEFAULT_BOOLEAN_ATTRIBUTE
|
|||
import static com.alibaba.nacos.spring.util.NacosUtils.DEFAULT_CONFIG_TYPE_VALUE;
|
||||
import static com.alibaba.nacos.spring.util.NacosUtils.DEFAULT_STRING_ATTRIBUTE_VALUE;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.springframework.beans.factory.xml.XmlReaderContext;
|
||||
import org.springframework.core.convert.ConversionService;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.NamedNodeMap;
|
||||
|
||||
import com.alibaba.nacos.api.config.ConfigType;
|
||||
import com.alibaba.nacos.spring.context.config.xml.NacosPropertySourceXmlBeanDefinition;
|
||||
import com.alibaba.nacos.spring.context.event.config.NacosConfigMetadataEvent;
|
||||
|
||||
/**
|
||||
* XML {@link NacosPropertySource} {@link AbstractNacosPropertySourceBuilder Builder}
|
||||
*
|
||||
|
@ -77,14 +77,14 @@ public class XmlNacosPropertySourceBuilder
|
|||
runtimeAttributes.put(AUTO_REFRESHED_ATTRIBUTE_NAME, getAttribute(element,
|
||||
AUTO_REFRESHED_ATTRIBUTE_NAME, DEFAULT_BOOLEAN_ATTRIBUTE_VALUE));
|
||||
// is first order
|
||||
runtimeAttributes.put(FIRST_ATTRIBUTE_NAME, getAttribute(element, FIRST_ATTRIBUTE_NAME,
|
||||
DEFAULT_BOOLEAN_ATTRIBUTE_VALUE));
|
||||
runtimeAttributes.put(FIRST_ATTRIBUTE_NAME, getAttribute(element,
|
||||
FIRST_ATTRIBUTE_NAME, DEFAULT_BOOLEAN_ATTRIBUTE_VALUE));
|
||||
// The relative order before specified
|
||||
runtimeAttributes.put(BEFORE_ATTRIBUTE_NAME, getAttribute(element, BEFORE_ATTRIBUTE_NAME,
|
||||
DEFAULT_STRING_ATTRIBUTE_VALUE));
|
||||
runtimeAttributes.put(BEFORE_ATTRIBUTE_NAME, getAttribute(element,
|
||||
BEFORE_ATTRIBUTE_NAME, DEFAULT_STRING_ATTRIBUTE_VALUE));
|
||||
// The relative order after specified
|
||||
runtimeAttributes.put(AFTER_ATTRIBUTE_NAME, getAttribute(element, AFTER_ATTRIBUTE_NAME,
|
||||
DEFAULT_STRING_ATTRIBUTE_VALUE));
|
||||
runtimeAttributes.put(AFTER_ATTRIBUTE_NAME, getAttribute(element,
|
||||
AFTER_ATTRIBUTE_NAME, DEFAULT_STRING_ATTRIBUTE_VALUE));
|
||||
// Config type
|
||||
String type = getAttribute(element, CONFIG_TYPE_ATTRIBUTE_NAME,
|
||||
DEFAULT_CONFIG_TYPE_VALUE);
|
||||
|
|
|
@ -0,0 +1,105 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.alibaba.nacos.spring.enums;
|
||||
|
||||
import com.alibaba.nacos.common.utils.StringUtils;
|
||||
|
||||
/**
|
||||
* Config file type enum.
|
||||
*
|
||||
*/
|
||||
public enum FileTypeEnum {
|
||||
|
||||
/**
|
||||
* Yaml file.
|
||||
*/
|
||||
YML("yaml"),
|
||||
|
||||
/**
|
||||
* Yaml file.
|
||||
*/
|
||||
YAML("yaml"),
|
||||
|
||||
/**
|
||||
* Text file.
|
||||
*/
|
||||
TXT("text"),
|
||||
|
||||
/**
|
||||
* Text file.
|
||||
*/
|
||||
TEXT("text"),
|
||||
|
||||
/**
|
||||
* Json file.
|
||||
*/
|
||||
JSON("json"),
|
||||
|
||||
/**
|
||||
* Xml file.
|
||||
*/
|
||||
XML("xml"),
|
||||
|
||||
/**
|
||||
* Html file.
|
||||
*/
|
||||
HTM("html"),
|
||||
|
||||
/**
|
||||
* Html file.
|
||||
*/
|
||||
HTML("html"),
|
||||
|
||||
/**
|
||||
* Properties file.
|
||||
*/
|
||||
PROPERTIES("properties");
|
||||
|
||||
/**
|
||||
* File type corresponding to file extension.
|
||||
*/
|
||||
private String fileType;
|
||||
|
||||
FileTypeEnum(String fileType) {
|
||||
this.fileType = fileType;
|
||||
}
|
||||
|
||||
public String getFileType() {
|
||||
return this.fileType;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the corresponding FileTypeEnum by file extension or fileType. If not found FileTypeEnum.TEXT is returned
|
||||
*
|
||||
* @param extOrFileType file extension or fileType
|
||||
* @return return {@link FileTypeEnum}
|
||||
*/
|
||||
public static FileTypeEnum getFileTypeEnumByFileExtensionOrFileType(String extOrFileType) {
|
||||
if (StringUtils.isNotBlank(extOrFileType)) {
|
||||
String upperExtName = extOrFileType.trim().toUpperCase();
|
||||
for (FileTypeEnum value : VALUES) {
|
||||
if (value.name().equals(upperExtName)) {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
}
|
||||
return FileTypeEnum.PROPERTIES;
|
||||
}
|
||||
|
||||
private static final FileTypeEnum[] VALUES = FileTypeEnum.values();
|
||||
}
|
|
@ -31,13 +31,13 @@ public class ApplicationContextHolder implements ApplicationContextAware {
|
|||
|
||||
private ConfigurableApplicationContext context;
|
||||
|
||||
public ConfigurableApplicationContext getApplicationContext() {
|
||||
return context;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setApplicationContext(ApplicationContext applicationContext)
|
||||
throws BeansException {
|
||||
context = (ConfigurableApplicationContext) applicationContext;
|
||||
}
|
||||
|
||||
public ConfigurableApplicationContext getApplicationContext() {
|
||||
return context;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,6 +16,9 @@
|
|||
*/
|
||||
package com.alibaba.nacos.spring.factory;
|
||||
|
||||
import static com.alibaba.nacos.spring.util.NacosBeanUtils.getNacosConfigListenerExecutorIfPresent;
|
||||
import static com.alibaba.nacos.spring.util.NacosUtils.identify;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
|
@ -25,6 +28,10 @@ import java.util.Map;
|
|||
import java.util.Properties;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
|
||||
import com.alibaba.nacos.api.NacosFactory;
|
||||
import com.alibaba.nacos.api.config.ConfigService;
|
||||
import com.alibaba.nacos.api.exception.NacosException;
|
||||
|
@ -32,13 +39,6 @@ import com.alibaba.nacos.api.naming.NamingMaintainService;
|
|||
import com.alibaba.nacos.api.naming.NamingService;
|
||||
import com.alibaba.nacos.spring.context.event.config.EventPublishingConfigService;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
|
||||
import static com.alibaba.nacos.spring.util.NacosBeanUtils.getNacosConfigListenerExecutorIfPresent;
|
||||
import static com.alibaba.nacos.spring.util.NacosUtils.identify;
|
||||
|
||||
/**
|
||||
* Cacheable Event Publishing {@link NacosServiceFactory}
|
||||
*
|
||||
|
@ -75,6 +75,10 @@ public class CacheableEventPublishingNacosServiceFactory implements NacosService
|
|||
createWorkerManager = Collections.unmodifiableMap(createWorkerManager);
|
||||
}
|
||||
|
||||
public static CacheableEventPublishingNacosServiceFactory getSingleton() {
|
||||
return SINGLETON;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConfigService createConfigService(Properties properties)
|
||||
throws NacosException {
|
||||
|
@ -93,6 +97,10 @@ public class CacheableEventPublishingNacosServiceFactory implements NacosService
|
|||
null);
|
||||
}
|
||||
|
||||
// Exist some cases need to create the ConfigService | NamingService |
|
||||
// NamingMaintainService
|
||||
// before loading the Context object, lazy loading
|
||||
|
||||
@Override
|
||||
public NamingMaintainService createNamingMaintainService(Properties properties)
|
||||
throws NacosException {
|
||||
|
@ -102,10 +110,6 @@ public class CacheableEventPublishingNacosServiceFactory implements NacosService
|
|||
.run(copy, null);
|
||||
}
|
||||
|
||||
// Exist some cases need to create the ConfigService | NamingService |
|
||||
// NamingMaintainService
|
||||
// before loading the Context object, lazy loading
|
||||
|
||||
public <T> T deferCreateService(T service, Properties properties) {
|
||||
DeferServiceHolder serviceHolder = new DeferServiceHolder();
|
||||
serviceHolder.setHolder(service);
|
||||
|
@ -162,10 +166,6 @@ public class CacheableEventPublishingNacosServiceFactory implements NacosService
|
|||
return maintainServiceCache.values();
|
||||
}
|
||||
|
||||
public static CacheableEventPublishingNacosServiceFactory getSingleton() {
|
||||
return SINGLETON;
|
||||
}
|
||||
|
||||
private static enum ServiceType {
|
||||
|
||||
/**
|
||||
|
|
|
@ -123,7 +123,12 @@ class DelegatingNamingMaintainService
|
|||
throws NacosException {
|
||||
delegate.updateService(service, selector);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void shutDown() throws NacosException {
|
||||
delegate.shutDown();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Properties getProperties() {
|
||||
return properties;
|
||||
|
|
|
@ -14,11 +14,14 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.spring.factory;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.springframework.beans.factory.DisposableBean;
|
||||
|
||||
import com.alibaba.nacos.api.exception.NacosException;
|
||||
import com.alibaba.nacos.api.naming.NamingService;
|
||||
import com.alibaba.nacos.api.naming.listener.EventListener;
|
||||
|
@ -29,14 +32,15 @@ import com.alibaba.nacos.api.selector.AbstractSelector;
|
|||
import com.alibaba.nacos.spring.metadata.NacosServiceMetaData;
|
||||
|
||||
/**
|
||||
* Delegating {@link NamingService} with {@link NacosServiceMetaData}
|
||||
* Delegating {@link NamingService} with {@link NacosServiceMetaData}.
|
||||
*
|
||||
* @author <a href="mailto:mercyblitz@gmail.com">Mercy</a>
|
||||
* @see NamingService
|
||||
* @see NacosServiceMetaData
|
||||
* @since 0.1.0
|
||||
*/
|
||||
class DelegatingNamingService implements NamingService, NacosServiceMetaData {
|
||||
class DelegatingNamingService
|
||||
implements NamingService, NacosServiceMetaData, DisposableBean {
|
||||
|
||||
private final NamingService delegate;
|
||||
|
||||
|
@ -82,7 +86,19 @@ class DelegatingNamingService implements NamingService, NacosServiceMetaData {
|
|||
throws NacosException {
|
||||
delegate.registerInstance(serviceName, groupName, instance);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void batchRegisterInstance(String serviceName, String groupName, List<Instance> instances)
|
||||
throws NacosException {
|
||||
delegate.batchRegisterInstance(serviceName, groupName, instances);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void batchDeregisterInstance(String serviceName, String groupName, List<Instance> instances)
|
||||
throws NacosException {
|
||||
delegate.batchDeregisterInstance(serviceName, groupName, instances);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deregisterInstance(String serviceName, String ip, int port)
|
||||
throws NacosException {
|
||||
|
@ -110,7 +126,7 @@ class DelegatingNamingService implements NamingService, NacosServiceMetaData {
|
|||
@Override
|
||||
public void deregisterInstance(String serviceName, Instance instance)
|
||||
throws NacosException {
|
||||
delegate.registerInstance(serviceName, instance);
|
||||
delegate.deregisterInstance(serviceName, instance);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -346,8 +362,23 @@ class DelegatingNamingService implements NamingService, NacosServiceMetaData {
|
|||
return delegate.getServerStatus();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void shutDown() throws NacosException {
|
||||
delegate.shutDown();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Properties getProperties() {
|
||||
return properties;
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroy lifecycle method to invoke {@link #shutDown()}
|
||||
* @throws Exception
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@Override
|
||||
public void destroy() throws Exception {
|
||||
shutDown();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
*/
|
||||
package com.alibaba.nacos.spring.util;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
/**
|
||||
|
@ -30,7 +31,7 @@ public interface ConfigParse {
|
|||
* @param configText receive config context
|
||||
* @return {@link Properties}
|
||||
*/
|
||||
Properties parse(String configText);
|
||||
Map<String, Object> parse(String configText);
|
||||
|
||||
/**
|
||||
* get this ConfigParse process config type
|
||||
|
|
|
@ -18,9 +18,9 @@ package com.alibaba.nacos.spring.util;
|
|||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.Properties;
|
||||
import java.util.ServiceLoader;
|
||||
|
||||
import com.alibaba.nacos.spring.util.parse.DefaultJsonConfigParse;
|
||||
|
@ -82,19 +82,18 @@ public final class ConfigParseUtils {
|
|||
.unmodifiableMap(CUSTOMER_CONFIG_PARSE_MAP);
|
||||
}
|
||||
|
||||
public static Properties toProperties(final String context, String type) {
|
||||
public static Map<String, Object> toProperties(final String context, String type) {
|
||||
|
||||
if (context == null) {
|
||||
return new Properties();
|
||||
return new LinkedHashMap<String, Object>();
|
||||
}
|
||||
// Again the type lowercase, ensure the search
|
||||
type = type.toLowerCase();
|
||||
|
||||
Properties properties = new Properties();
|
||||
if (DEFAULT_CONFIG_PARSE_MAP.containsKey(type)) {
|
||||
ConfigParse configParse = DEFAULT_CONFIG_PARSE_MAP.get(type);
|
||||
properties.putAll(configParse.parse(context));
|
||||
return properties;
|
||||
Map<String, Object> parseMap = configParse.parse(context);
|
||||
return parseMap == null ? new HashMap<>() : parseMap;
|
||||
}
|
||||
else {
|
||||
throw new UnsupportedOperationException(
|
||||
|
@ -102,26 +101,16 @@ public final class ConfigParseUtils {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* XML configuration parsing to support different schemas
|
||||
*
|
||||
* @param dataId config dataId
|
||||
* @param group config group
|
||||
* @param context config context
|
||||
* @param type config type
|
||||
* @return {@link Properties}
|
||||
*/
|
||||
public static Properties toProperties(final String dataId, final String group,
|
||||
final String context, String type) {
|
||||
public static Map<String, Object> toProperties(final String dataId,
|
||||
final String group, final String context, String type) {
|
||||
|
||||
if (context == null) {
|
||||
return new Properties();
|
||||
return new LinkedHashMap<String, Object>();
|
||||
}
|
||||
// Again the type lowercase, ensure the search
|
||||
type = type.toLowerCase();
|
||||
|
||||
String configParseKey = dataId + LINK_CHAR + group;
|
||||
Properties properties = new Properties();
|
||||
|
||||
if (CUSTOMER_CONFIG_PARSE_MAP.isEmpty() || LINK_CHAR.equals(configParseKey)) {
|
||||
return toProperties(context, type);
|
||||
|
@ -141,8 +130,7 @@ public final class ConfigParseUtils {
|
|||
throw new NoSuchElementException(
|
||||
"This config can't find ConfigParse to parse");
|
||||
}
|
||||
properties.putAll(configParse.parse(context));
|
||||
return properties;
|
||||
return configParse.parse(context);
|
||||
}
|
||||
else {
|
||||
throw new UnsupportedOperationException(
|
||||
|
@ -151,4 +139,4 @@ public final class ConfigParseUtils {
|
|||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,13 +16,6 @@
|
|||
*/
|
||||
package com.alibaba.nacos.spring.util;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
import com.alibaba.nacos.api.annotation.NacosProperties;
|
||||
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
|
||||
import static com.alibaba.nacos.spring.util.NacosBeanUtils.CONFIG_GLOBAL_NACOS_PROPERTIES_BEAN_NAME;
|
||||
import static com.alibaba.nacos.spring.util.NacosBeanUtils.DISCOVERY_GLOBAL_NACOS_PROPERTIES_BEAN_NAME;
|
||||
import static com.alibaba.nacos.spring.util.NacosBeanUtils.GLOBAL_NACOS_PROPERTIES_BEAN_NAME;
|
||||
|
@ -30,6 +23,13 @@ import static com.alibaba.nacos.spring.util.NacosBeanUtils.MAINTAIN_GLOBAL_NACOS
|
|||
import static com.alibaba.nacos.spring.util.NacosUtils.merge;
|
||||
import static java.util.Collections.emptyMap;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
|
||||
import com.alibaba.nacos.api.annotation.NacosProperties;
|
||||
|
||||
/**
|
||||
* The source enumeration of Global {@link NacosProperties}
|
||||
*
|
||||
|
|
|
@ -16,6 +16,10 @@
|
|||
*/
|
||||
package com.alibaba.nacos.spring.util;
|
||||
|
||||
import static com.alibaba.nacos.spring.context.constants.NacosConstants.DEFAULT_NACOS_CONFIG_LISTENER_PARALLELISM;
|
||||
import static com.alibaba.nacos.spring.context.constants.NacosConstants.NACOS_CONFIG_LISTENER_PARALLELISM;
|
||||
import static com.alibaba.nacos.spring.util.NacosUtils.resolveProperties;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
@ -25,6 +29,22 @@ import java.util.concurrent.Executors;
|
|||
import java.util.concurrent.ThreadFactory;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import com.alibaba.nacos.spring.context.annotation.config.SpringValueAnnotationBeanPostProcessor;
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.ListableBeanFactory;
|
||||
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.beans.factory.config.SingletonBeanRegistry;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
||||
import org.springframework.context.support.AbstractApplicationContext;
|
||||
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
|
||||
import org.springframework.core.annotation.AnnotationAttributes;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.core.env.PropertyResolver;
|
||||
|
||||
import com.alibaba.nacos.spring.beans.factory.annotation.AnnotationNacosInjectedBeanPostProcessor;
|
||||
import com.alibaba.nacos.spring.beans.factory.annotation.ConfigServiceBeanBuilder;
|
||||
import com.alibaba.nacos.spring.beans.factory.annotation.NamingMaintainServiceBeanBuilder;
|
||||
|
@ -40,25 +60,6 @@ import com.alibaba.nacos.spring.factory.ApplicationContextHolder;
|
|||
import com.alibaba.nacos.spring.factory.CacheableEventPublishingNacosServiceFactory;
|
||||
import com.alibaba.nacos.spring.factory.NacosServiceFactory;
|
||||
import com.alibaba.spring.util.BeanUtils;
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.ListableBeanFactory;
|
||||
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.beans.factory.config.SingletonBeanRegistry;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
||||
import org.springframework.context.support.AbstractApplicationContext;
|
||||
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
|
||||
import org.springframework.core.annotation.AnnotationAttributes;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.core.env.PropertyResolver;
|
||||
|
||||
import static com.alibaba.nacos.spring.context.constants.NacosConstants.DEFAULT_NACOS_CONFIG_LISTENER_PARALLELISM;
|
||||
import static com.alibaba.nacos.spring.context.constants.NacosConstants.NACOS_CONFIG_LISTENER_PARALLELISM;
|
||||
import static com.alibaba.nacos.spring.util.NacosUtils.resolveProperties;
|
||||
|
||||
/**
|
||||
* Nacos Bean Utilities class
|
||||
|
@ -362,6 +363,13 @@ public abstract class NacosBeanUtils {
|
|||
NacosValueAnnotationBeanPostProcessor.class);
|
||||
}
|
||||
|
||||
public static void registerStringValueAnnotationBeanPostProcessor(
|
||||
BeanDefinitionRegistry registry) {
|
||||
registerInfrastructureBeanIfAbsent(registry,
|
||||
SpringValueAnnotationBeanPostProcessor.BEAN_NAME,
|
||||
SpringValueAnnotationBeanPostProcessor.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register Nacos Common Beans
|
||||
*
|
||||
|
@ -398,6 +406,8 @@ public abstract class NacosBeanUtils {
|
|||
|
||||
registerNacosValueAnnotationBeanPostProcessor(registry);
|
||||
|
||||
registerStringValueAnnotationBeanPostProcessor(registry);
|
||||
|
||||
registerConfigServiceBeanBuilder(registry);
|
||||
|
||||
registerLoggingNacosConfigMetadataEventListener(registry);
|
||||
|
|
|
@ -16,45 +16,40 @@
|
|||
*/
|
||||
package com.alibaba.nacos.spring.util;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.Collection;
|
||||
import java.util.Enumeration;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import com.alibaba.nacos.api.annotation.NacosProperties;
|
||||
import com.alibaba.nacos.api.config.ConfigService;
|
||||
import com.alibaba.nacos.api.config.annotation.NacosConfigurationProperties;
|
||||
import com.alibaba.nacos.api.config.annotation.NacosIgnore;
|
||||
import com.alibaba.nacos.api.config.annotation.NacosProperty;
|
||||
import com.alibaba.nacos.api.exception.NacosException;
|
||||
import com.alibaba.nacos.spring.enums.FileTypeEnum;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import org.springframework.beans.MutablePropertyValues;
|
||||
import org.springframework.beans.PropertyValues;
|
||||
import org.springframework.beans.factory.config.BeanExpressionContext;
|
||||
import org.springframework.beans.factory.config.BeanExpressionResolver;
|
||||
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
|
||||
import org.springframework.context.expression.EnvironmentAccessor;
|
||||
import org.springframework.context.expression.StandardBeanExpressionResolver;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.core.env.PropertyResolver;
|
||||
import org.springframework.expression.Expression;
|
||||
import org.springframework.expression.ExpressionParser;
|
||||
import org.springframework.expression.common.TemplateParserContext;
|
||||
import org.springframework.expression.spel.standard.SpelExpressionParser;
|
||||
import org.springframework.expression.spel.support.StandardEvaluationContext;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import static com.alibaba.nacos.api.PropertyKeyConst.ACCESS_KEY;
|
||||
import static com.alibaba.nacos.api.PropertyKeyConst.CLUSTER_NAME;
|
||||
import static com.alibaba.nacos.api.PropertyKeyConst.CONTEXT_PATH;
|
||||
import static com.alibaba.nacos.api.PropertyKeyConst.ENCODE;
|
||||
import static com.alibaba.nacos.api.PropertyKeyConst.ENDPOINT;
|
||||
import static com.alibaba.nacos.api.PropertyKeyConst.NAMESPACE;
|
||||
import static com.alibaba.nacos.api.PropertyKeyConst.SECRET_KEY;
|
||||
import static com.alibaba.nacos.api.PropertyKeyConst.SERVER_ADDR;
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.*;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import static com.alibaba.nacos.api.PropertyKeyConst.*;
|
||||
import static org.springframework.core.annotation.AnnotationUtils.getAnnotation;
|
||||
import static org.springframework.core.annotation.AnnotationUtils.getAnnotationAttributes;
|
||||
import static org.springframework.util.StringUtils.hasText;
|
||||
|
@ -93,6 +88,19 @@ public abstract class NacosUtils {
|
|||
public static final long DEFAULT_TIMEOUT = Long.getLong("nacos.default.timeout",
|
||||
5000L);
|
||||
|
||||
private static final Set<Class<?>> NON_BEAN_CLASSES = Collections.unmodifiableSet(
|
||||
new HashSet<Class<?>>(Arrays.asList(Object.class, Class.class)));
|
||||
|
||||
private static ExpressionParser parser = new SpelExpressionParser();
|
||||
|
||||
private static BeanExpressionResolver resolver = new StandardBeanExpressionResolver();
|
||||
|
||||
private static ConcurrentHashMap<String, Expression> expressionCache
|
||||
= new ConcurrentHashMap();
|
||||
|
||||
private static ConcurrentHashMap<Environment, StandardEvaluationContext> environmentContextCache
|
||||
= new ConcurrentHashMap();
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(NacosUtils.class);
|
||||
|
||||
/**
|
||||
|
@ -191,16 +199,52 @@ public abstract class NacosUtils {
|
|||
return records.isEmpty();
|
||||
}
|
||||
|
||||
public static String readTypeFromDataId(String dataId) {
|
||||
if (StringUtils.isEmpty(dataId)) {
|
||||
return dataId;
|
||||
}
|
||||
int index = dataId.lastIndexOf(".");
|
||||
return index != -1 ? dataId.substring(index + 1) : "";
|
||||
public static String readFromEnvironment(String label, Environment environment) {
|
||||
String value = resolvePlaceholders(label, environment);
|
||||
return StringUtils.hasText(value)
|
||||
? evaluate(value, environment)
|
||||
: value;
|
||||
}
|
||||
|
||||
public static String readFromEnvironment(String label, Environment environment) {
|
||||
return environment.resolvePlaceholders(label);
|
||||
public static Object readFromBeanFactory(String label, ConfigurableBeanFactory beanFactory) {
|
||||
if (beanFactory == null) {
|
||||
return label;
|
||||
}
|
||||
String value = beanFactory.resolveEmbeddedValue(label);
|
||||
return StringUtils.hasText(value) ? evaluate(value, beanFactory) : value;
|
||||
}
|
||||
|
||||
public static String resolvePlaceholders(String label, Environment environment) {
|
||||
|
||||
return environment == null ? label : environment.resolvePlaceholders(label);
|
||||
}
|
||||
|
||||
public static String evaluate(String value, Environment environment) {
|
||||
Expression expression = expressionCache.get(value);
|
||||
if (expression == null) {
|
||||
expression = parser.parseExpression(value, new TemplateParserContext());
|
||||
expressionCache.put(value, expression);
|
||||
}
|
||||
|
||||
StandardEvaluationContext evaluationContext = environmentContextCache.get(environment);
|
||||
if (evaluationContext == null) {
|
||||
evaluationContext = new StandardEvaluationContext(environment);
|
||||
evaluationContext.addPropertyAccessor(new EnvironmentAccessor());
|
||||
environmentContextCache.put(environment, evaluationContext);
|
||||
}
|
||||
|
||||
return expression.getValue(evaluationContext, String.class);
|
||||
}
|
||||
|
||||
public static Object evaluate(String value, ConfigurableBeanFactory beanFactory) {
|
||||
return resolver.evaluate(value, new BeanExpressionContext(beanFactory, null));
|
||||
}
|
||||
|
||||
public static String readFileExtension(String dataId) {
|
||||
int lastIndex = dataId.lastIndexOf(".");
|
||||
final String extName = dataId.substring(lastIndex + 1);
|
||||
FileTypeEnum fileTypeEnum = FileTypeEnum.getFileTypeEnumByFileExtensionOrFileType(extName);
|
||||
return fileTypeEnum.getFileType();
|
||||
}
|
||||
|
||||
public static PropertyValues resolvePropertyValues(Object bean, String content,
|
||||
|
@ -210,7 +254,8 @@ public abstract class NacosUtils {
|
|||
|
||||
public static PropertyValues resolvePropertyValues(Object bean, final String prefix,
|
||||
String dataId, String groupId, String content, String type) {
|
||||
final Properties configProperties = toProperties(dataId, groupId, content, type);
|
||||
final Map<String, Object> configProperties = toProperties(dataId, groupId,
|
||||
content, type);
|
||||
final MutablePropertyValues propertyValues = new MutablePropertyValues();
|
||||
ReflectionUtils.doWithFields(bean.getClass(),
|
||||
new ReflectionUtils.FieldCallback() {
|
||||
|
@ -229,9 +274,16 @@ public abstract class NacosUtils {
|
|||
propertyValues);
|
||||
return;
|
||||
}
|
||||
if (containsDescendantOf(configProperties.keySet(),
|
||||
propertyName) && !isUnbindableBean(field.getType())) {
|
||||
bindBean(propertyName, field.getType(), configProperties,
|
||||
propertyValues);
|
||||
return;
|
||||
}
|
||||
|
||||
if (configProperties.containsKey(propertyName)) {
|
||||
String propertyValue = configProperties
|
||||
.getProperty(propertyName);
|
||||
String propertyValue = String
|
||||
.valueOf(configProperties.get(propertyName));
|
||||
propertyValues.add(field.getName(), propertyValue);
|
||||
}
|
||||
}
|
||||
|
@ -342,6 +394,50 @@ public abstract class NacosUtils {
|
|||
return content;
|
||||
}
|
||||
|
||||
/**
|
||||
* bind properties to bean
|
||||
*
|
||||
* @param propertyName propertyName
|
||||
* @param target bind target
|
||||
* @param configProperties config context
|
||||
* @param propertyValues {@link MutablePropertyValues}
|
||||
*/
|
||||
private static void bindBean(String propertyName, Class<?> target,
|
||||
Map<String, Object> configProperties, MutablePropertyValues propertyValues) {
|
||||
Object propertyValue = configProperties.get(propertyName);
|
||||
if (propertyValue != null) {
|
||||
propertyValues.add(propertyName, propertyValue);
|
||||
}
|
||||
if (isUnbindableBean(target)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Field[] fields = target.getDeclaredFields();
|
||||
for (Field field : fields) {
|
||||
String mergePropertyName = propertyName + "."
|
||||
+ NacosUtils.resolvePropertyName(field);
|
||||
bindBean(mergePropertyName, field.getType(), configProperties,
|
||||
propertyValues);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static boolean containsDescendantOf(Set<String> names, String propertyName) {
|
||||
for (String name : names) {
|
||||
if (name.startsWith(propertyName + ".")) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean isUnbindableBean(Class<?> resolved) {
|
||||
if (resolved.isPrimitive() || NON_BEAN_CLASSES.contains(resolved)) {
|
||||
return true;
|
||||
}
|
||||
return resolved.getName().startsWith("java.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple solutions to support {@link Map} or {@link Collection}
|
||||
*
|
||||
|
@ -350,21 +446,22 @@ public abstract class NacosUtils {
|
|||
* @param propertyValues {@link MutablePropertyValues}
|
||||
*/
|
||||
private static void bindContainer(String prefix, String fieldName,
|
||||
Properties configProperties, MutablePropertyValues propertyValues) {
|
||||
Map<String, Object> configProperties, MutablePropertyValues propertyValues) {
|
||||
String regx1 = fieldName + "\\[(.*)\\]";
|
||||
String regx2 = fieldName + "\\..*";
|
||||
Pattern pattern1 = Pattern.compile(regx1);
|
||||
Pattern pattern2 = Pattern.compile(regx2);
|
||||
Enumeration<String> enumeration = (Enumeration<String>) configProperties
|
||||
.propertyNames();
|
||||
while (enumeration.hasMoreElements()) {
|
||||
String s = enumeration.nextElement();
|
||||
Set<String> enumeration = configProperties.keySet();
|
||||
for (Object item : enumeration) {
|
||||
final String s = String.valueOf(item);
|
||||
String name = StringUtils.isEmpty(prefix) ? s : s.replace(prefix + ".", "");
|
||||
String value = configProperties.getProperty(s);
|
||||
Object value = configProperties.get(s);
|
||||
if (configProperties.containsKey(fieldName)) {
|
||||
// for example: list=1,2,3,4,5 will be into here
|
||||
bindContainer(prefix, fieldName, listToProperties(fieldName,
|
||||
configProperties.getProperty(fieldName)), propertyValues);
|
||||
bindContainer(prefix, fieldName,
|
||||
listToProperties(fieldName,
|
||||
String.valueOf(configProperties.get(fieldName))),
|
||||
propertyValues);
|
||||
}
|
||||
else if (pattern1.matcher(s).find()) {
|
||||
propertyValues.add(name, value);
|
||||
|
@ -386,10 +483,11 @@ public abstract class NacosUtils {
|
|||
* @param content content
|
||||
* @return {@link Properties}
|
||||
*/
|
||||
private static Properties listToProperties(String fieldName, String content) {
|
||||
private static Map<String, Object> listToProperties(String fieldName,
|
||||
String content) {
|
||||
String[] splits = content.split(",");
|
||||
int index = 0;
|
||||
Properties properties = new Properties();
|
||||
Map<String, Object> properties = new LinkedHashMap<String, Object>();
|
||||
for (String s : splits) {
|
||||
properties.put(fieldName + "[" + index + "]", s.trim());
|
||||
index++;
|
||||
|
@ -414,15 +512,16 @@ public abstract class NacosUtils {
|
|||
return (Class<T>) actualTypeArguments[0];
|
||||
}
|
||||
|
||||
public static Properties toProperties(String text) {
|
||||
public static Map<String, Object> toProperties(String text) {
|
||||
return toProperties(text, "properties");
|
||||
}
|
||||
|
||||
public static Properties toProperties(String text, String type) {
|
||||
public static Map<String, Object> toProperties(String text, String type) {
|
||||
return toProperties("", "", text, type);
|
||||
}
|
||||
|
||||
public static Properties toProperties(String dataId, String group, String text) {
|
||||
public static Map<String, Object> toProperties(String dataId, String group,
|
||||
String text) {
|
||||
return toProperties(dataId, group, text, "properties");
|
||||
}
|
||||
|
||||
|
@ -433,10 +532,10 @@ public abstract class NacosUtils {
|
|||
* @param group config group
|
||||
* @param text config context
|
||||
* @param type config type
|
||||
* @return {@link Properties}
|
||||
* @return map format of result
|
||||
*/
|
||||
public static Properties toProperties(String dataId, String group, String text,
|
||||
String type) {
|
||||
public static Map<String, Object> toProperties(String dataId, String group,
|
||||
String text, String type) {
|
||||
type = type.toLowerCase();
|
||||
if ("yml".equalsIgnoreCase(type)) {
|
||||
type = "yaml";
|
||||
|
|
|
@ -19,16 +19,15 @@ package com.alibaba.nacos.spring.util;
|
|||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Collection;
|
||||
import java.util.Hashtable;
|
||||
import java.util.Map;
|
||||
|
||||
import com.alibaba.nacos.api.config.annotation.NacosIgnore;
|
||||
|
||||
import org.springframework.beans.TypeConverter;
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
|
||||
import com.alibaba.nacos.api.config.annotation.NacosIgnore;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:liaochunyhm@live.com">liaochuntao</a>
|
||||
* @since 0.3.0
|
||||
|
|
|
@ -0,0 +1,126 @@
|
|||
package com.alibaba.nacos.spring.util;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.common.collect.Sets;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.Stack;
|
||||
|
||||
/**
|
||||
* @author wuhaoqiang
|
||||
* @since 1.1.2
|
||||
**/
|
||||
public class PlaceholderHelper {
|
||||
|
||||
private static final String PLACEHOLDER_PREFIX = "${";
|
||||
private static final String PLACEHOLDER_SUFFIX = "}";
|
||||
private static final String VALUE_SEPARATOR = ":";
|
||||
private static final String SIMPLE_PLACEHOLDER_PREFIX = "{";
|
||||
|
||||
/**
|
||||
* find keys from placeholder
|
||||
* ${key} - "key"
|
||||
* xxx${key}yyy - "key"
|
||||
* ${key:${key2:1}} - "key", "key2"
|
||||
* ${${key}} - "key"
|
||||
* ${${key:100}} - "key"
|
||||
* ${${key}:${key2}} - "key", "key2"
|
||||
* @param propertyString ${key}
|
||||
* @return key
|
||||
*/
|
||||
public static Set<String> findPlaceholderKeys(String propertyString) {
|
||||
Set<String> placeholderKeys = Sets.newHashSet();
|
||||
|
||||
if (Strings.isNullOrEmpty(propertyString) ||
|
||||
!(propertyString.contains(PLACEHOLDER_PREFIX) && propertyString.contains(PLACEHOLDER_SUFFIX))) {
|
||||
return placeholderKeys;
|
||||
}
|
||||
// handle xxx${yyy}zzz -> ${yyy}zzz
|
||||
propertyString = propertyString.substring(propertyString.indexOf(PLACEHOLDER_PREFIX));
|
||||
|
||||
Stack<String> stack = new Stack<String>();
|
||||
stack.push(propertyString);
|
||||
|
||||
while (!stack.isEmpty()) {
|
||||
String strVal = stack.pop();
|
||||
int startIndex = strVal.indexOf(PLACEHOLDER_PREFIX);
|
||||
if (startIndex == -1) {
|
||||
placeholderKeys.add(strVal);
|
||||
continue;
|
||||
}
|
||||
int endIndex = findPlaceholderEndIndex(strVal, startIndex);
|
||||
if (endIndex == -1) {
|
||||
// invalid placeholder
|
||||
continue;
|
||||
}
|
||||
|
||||
String placeholderCandidate = strVal.substring(startIndex + PLACEHOLDER_PREFIX.length(), endIndex);
|
||||
|
||||
// ${key}
|
||||
// startsWith '${' continue
|
||||
if (placeholderCandidate.startsWith(PLACEHOLDER_PREFIX)) {
|
||||
stack.push(placeholderCandidate);
|
||||
} else {
|
||||
// exist ':' -> key:${key2:2}
|
||||
int separatorIndex = placeholderCandidate.indexOf(VALUE_SEPARATOR);
|
||||
|
||||
if (separatorIndex == -1) {
|
||||
stack.push(placeholderCandidate);
|
||||
} else {
|
||||
stack.push(placeholderCandidate.substring(0, separatorIndex));
|
||||
String defaultValuePart =
|
||||
normalizeToPlaceholder(placeholderCandidate.substring(separatorIndex + VALUE_SEPARATOR.length()));
|
||||
if (!Strings.isNullOrEmpty(defaultValuePart)) {
|
||||
stack.push(defaultValuePart);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// has remaining part, e.g. ${a}.${b}
|
||||
if (endIndex + PLACEHOLDER_SUFFIX.length() < strVal.length() - 1) {
|
||||
String remainingPart = normalizeToPlaceholder(strVal.substring(endIndex + PLACEHOLDER_SUFFIX.length()));
|
||||
if (!Strings.isNullOrEmpty(remainingPart)) {
|
||||
stack.push(remainingPart);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return placeholderKeys;
|
||||
}
|
||||
|
||||
private static String normalizeToPlaceholder(String strVal) {
|
||||
int startIndex = strVal.indexOf(PLACEHOLDER_PREFIX);
|
||||
if (startIndex == -1) {
|
||||
return null;
|
||||
}
|
||||
int endIndex = strVal.lastIndexOf(PLACEHOLDER_SUFFIX);
|
||||
if (endIndex == -1) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return strVal.substring(startIndex, endIndex + PLACEHOLDER_SUFFIX.length());
|
||||
}
|
||||
|
||||
private static int findPlaceholderEndIndex(CharSequence buf, int startIndex) {
|
||||
int index = startIndex + PLACEHOLDER_PREFIX.length();
|
||||
int withinNestedPlaceholder = 0;
|
||||
while (index < buf.length()) {
|
||||
if (StringUtils.substringMatch(buf, index, PLACEHOLDER_SUFFIX)) {
|
||||
if (withinNestedPlaceholder > 0) {
|
||||
withinNestedPlaceholder--;
|
||||
index = index + PLACEHOLDER_SUFFIX.length();
|
||||
} else {
|
||||
return index;
|
||||
}
|
||||
} else if (StringUtils.substringMatch(buf, index, SIMPLE_PLACEHOLDER_PREFIX)) {
|
||||
withinNestedPlaceholder++;
|
||||
index = index + SIMPLE_PLACEHOLDER_PREFIX.length();
|
||||
} else {
|
||||
index++;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
*
|
||||
* * Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* * contributor license agreements. See the NOTICE file distributed with
|
||||
* * this work for additional information regarding copyright ownership.
|
||||
* * The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* * (the "License"); you may not use this file except in compliance with
|
||||
* * the License. You may obtain a copy of the License at
|
||||
* *
|
||||
* * http://www.apache.org/licenses/LICENSE-2.0
|
||||
* *
|
||||
* * Unless required by applicable law or agreed to in writing, software
|
||||
* * distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* * See the License for the specific language governing permissions and
|
||||
* * limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.spring.util.aot;
|
||||
|
||||
import org.springframework.core.SpringProperties;
|
||||
|
||||
public abstract class AotDetector {
|
||||
|
||||
/**
|
||||
* System property that indicates the application should run with AOT
|
||||
* generated artifacts. If such optimizations are not available, it is
|
||||
* recommended to throw an exception rather than fall back to the regular
|
||||
* runtime behavior.
|
||||
*/
|
||||
public static final String AOT_ENABLED = "spring.aot.enabled";
|
||||
|
||||
/**
|
||||
* Determine whether AOT optimizations must be considered at runtime. This
|
||||
* is mandatory in a native image but can be triggered on the JVM using
|
||||
* the {@value #AOT_ENABLED} Spring property.
|
||||
* @return whether AOT optimizations must be considered
|
||||
*/
|
||||
public static boolean useGeneratedArtifacts() {
|
||||
return (NativeDetector.inNativeImage() || SpringProperties.getFlag(AOT_ENABLED));
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
*
|
||||
* * Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* * contributor license agreements. See the NOTICE file distributed with
|
||||
* * this work for additional information regarding copyright ownership.
|
||||
* * The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* * (the "License"); you may not use this file except in compliance with
|
||||
* * the License. You may obtain a copy of the License at
|
||||
* *
|
||||
* * http://www.apache.org/licenses/LICENSE-2.0
|
||||
* *
|
||||
* * Unless required by applicable law or agreed to in writing, software
|
||||
* * distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* * See the License for the specific language governing permissions and
|
||||
* * limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.spring.util.aot;
|
||||
|
||||
public abstract class NativeDetector {
|
||||
|
||||
// See https://github.com/oracle/graal/blob/master/sdk/src/org.graalvm.nativeimage/src/org/graalvm/nativeimage/ImageInfo.java
|
||||
private static final boolean imageCode = (System.getProperty("org.graalvm.nativeimage.imagecode") != null);
|
||||
|
||||
/**
|
||||
* @return Returns {@code true} if invoked in the context of image building or during image runtime, else {@code false}.
|
||||
*/
|
||||
public static boolean inNativeImage() {
|
||||
return imageCode;
|
||||
}
|
||||
}
|
|
@ -18,6 +18,9 @@ package com.alibaba.nacos.spring.util.config;
|
|||
|
||||
import java.util.Properties;
|
||||
|
||||
import org.springframework.core.convert.ConversionService;
|
||||
import org.springframework.core.env.ConfigurableEnvironment;
|
||||
|
||||
import com.alibaba.nacos.api.NacosFactory;
|
||||
import com.alibaba.nacos.api.annotation.NacosProperties;
|
||||
import com.alibaba.nacos.api.config.ConfigService;
|
||||
|
@ -26,9 +29,6 @@ import com.alibaba.nacos.spring.factory.NacosServiceFactory;
|
|||
import com.alibaba.nacos.spring.util.NacosUtils;
|
||||
import com.alibaba.nacos.spring.util.PropertiesPlaceholderResolver;
|
||||
|
||||
import org.springframework.core.convert.ConversionService;
|
||||
import org.springframework.core.env.ConfigurableEnvironment;
|
||||
|
||||
/**
|
||||
* Nacos Configuration Loader
|
||||
*
|
||||
|
|
|
@ -16,14 +16,14 @@
|
|||
*/
|
||||
package com.alibaba.nacos.spring.util.parse;
|
||||
|
||||
import static com.alibaba.nacos.spring.util.parse.DefaultYamlConfigParse.createYaml;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import com.alibaba.nacos.api.config.ConfigType;
|
||||
import com.alibaba.nacos.spring.util.AbstractConfigParse;
|
||||
|
||||
import static com.alibaba.nacos.spring.util.parse.DefaultYamlConfigParse.createYaml;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:liaochunyhm@live.com">liaochuntao</a>
|
||||
* @since 0.3.0
|
||||
|
@ -31,15 +31,16 @@ import static com.alibaba.nacos.spring.util.parse.DefaultYamlConfigParse.createY
|
|||
public class DefaultJsonConfigParse extends AbstractConfigParse {
|
||||
|
||||
@Override
|
||||
public Properties parse(String configText) {
|
||||
final Properties result = new Properties();
|
||||
public Map<String, Object> parse(String configText) {
|
||||
final AtomicReference<Map<String, Object>> result = new AtomicReference<Map<String, Object>>();
|
||||
configText = configText.replaceAll("\t", "");
|
||||
DefaultYamlConfigParse.process(new DefaultYamlConfigParse.MatchCallback() {
|
||||
@Override
|
||||
public void process(Properties properties, Map<String, Object> map) {
|
||||
result.putAll(properties);
|
||||
public void process(Map<String, Object> map) {
|
||||
result.set(map);
|
||||
}
|
||||
}, createYaml(), configText);
|
||||
return result;
|
||||
return result.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -14,18 +14,28 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.spring.util.parse;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.io.IOException;
|
||||
import java.io.StringReader;
|
||||
import java.util.Properties;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.LineNumberReader;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.core.io.ByteArrayResource;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import com.alibaba.nacos.api.config.ConfigType;
|
||||
import com.alibaba.nacos.spring.util.AbstractConfigParse;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:liaochunyhm@live.com">liaochuntao</a>
|
||||
|
@ -37,17 +47,18 @@ public class DefaultPropertiesConfigParse extends AbstractConfigParse {
|
|||
.getLogger(DefaultPropertiesConfigParse.class);
|
||||
|
||||
@Override
|
||||
public Properties parse(String configText) {
|
||||
Properties properties = new Properties();
|
||||
public Map<String, Object> parse(String configText) {
|
||||
OriginTrackedPropertiesLoader loader = new OriginTrackedPropertiesLoader(
|
||||
new ByteArrayResource(configText.getBytes(Charset.defaultCharset())));
|
||||
try {
|
||||
if (StringUtils.hasText(configText)) {
|
||||
properties.load(new StringReader(configText));
|
||||
return loader.load();
|
||||
}
|
||||
return new LinkedHashMap<String, Object>();
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new ConfigParseException(e);
|
||||
}
|
||||
return properties;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -55,4 +66,517 @@ public class DefaultPropertiesConfigParse extends AbstractConfigParse {
|
|||
return ConfigType.PROPERTIES.getType();
|
||||
}
|
||||
|
||||
public interface OriginProvider {
|
||||
|
||||
/**
|
||||
* Return the source origin or {@code null} if the origin is not known.
|
||||
*
|
||||
* @return the origin or {@code null}
|
||||
*/
|
||||
Origin getOrigin();
|
||||
|
||||
}
|
||||
|
||||
public abstract static class Origin {
|
||||
|
||||
/**
|
||||
* Find the {@link Origin} that an object originated from. Checks if the source
|
||||
* object is an {@link OriginProvider} and also searches exception stacks.
|
||||
*
|
||||
* @param source the source object or {@code null}
|
||||
* @return an optional {@link Origin}
|
||||
*/
|
||||
static Origin from(Object source) {
|
||||
if (source instanceof Origin) {
|
||||
return (Origin) source;
|
||||
}
|
||||
Origin origin = null;
|
||||
if (source != null && source instanceof OriginProvider) {
|
||||
origin = ((OriginProvider) source).getOrigin();
|
||||
}
|
||||
if (origin == null && source != null && source instanceof Throwable) {
|
||||
return from(((Throwable) source).getCause());
|
||||
}
|
||||
return origin;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class OriginTrackedValue implements OriginProvider {
|
||||
|
||||
private final Object value;
|
||||
|
||||
private final Origin origin;
|
||||
|
||||
private OriginTrackedValue(Object value, Origin origin) {
|
||||
this.value = value;
|
||||
this.origin = origin;
|
||||
}
|
||||
|
||||
public static OriginTrackedValue of(Object value) {
|
||||
return of(value, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an {@link OriginTrackedValue} containing the specified {@code
|
||||
* value} and {@code origin}. If the source value implements {@link CharSequence}
|
||||
* then so will the resulting {@link OriginTrackedValue}.
|
||||
*
|
||||
* @param value the source value
|
||||
* @param origin the origin
|
||||
* @return an {@link OriginTrackedValue} or {@code null} if the source value was
|
||||
* {@code null}.
|
||||
*/
|
||||
public static OriginTrackedValue of(Object value, Origin origin) {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
if (value instanceof CharSequence) {
|
||||
return new OriginTrackedCharSequence((CharSequence) value, origin);
|
||||
}
|
||||
return new OriginTrackedValue(value, origin);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the tracked value.
|
||||
*
|
||||
* @return the tracked value
|
||||
*/
|
||||
public Object getValue() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Origin getOrigin() {
|
||||
return this.origin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return (this.value != null ? this.value.toString() : null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return ObjectUtils.nullSafeHashCode(this.value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj == null || obj.getClass() != getClass()) {
|
||||
return false;
|
||||
}
|
||||
return ObjectUtils.nullSafeEquals(this.value,
|
||||
((OriginTrackedValue) obj).value);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link OriginTrackedValue} for a {@link CharSequence}.
|
||||
*/
|
||||
private static class OriginTrackedCharSequence extends OriginTrackedValue
|
||||
implements CharSequence {
|
||||
|
||||
OriginTrackedCharSequence(CharSequence value, Origin origin) {
|
||||
super(value, origin);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int length() {
|
||||
return getValue().length();
|
||||
}
|
||||
|
||||
@Override
|
||||
public char charAt(int index) {
|
||||
return getValue().charAt(index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence subSequence(int start, int end) {
|
||||
return getValue().subSequence(start, end);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence getValue() {
|
||||
return (CharSequence) super.getValue();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* A location (line and column number) within the resource.
|
||||
*/
|
||||
static class Location {
|
||||
|
||||
private final int line;
|
||||
|
||||
private final int column;
|
||||
|
||||
/**
|
||||
* Create a new {@link Location} instance.
|
||||
*
|
||||
* @param line the line number (zero indexed)
|
||||
* @param column the column number (zero indexed)
|
||||
*/
|
||||
public Location(int line, int column) {
|
||||
this.line = line;
|
||||
this.column = column;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the line of the text resource where the property originated.
|
||||
*
|
||||
* @return the line number (zero indexed)
|
||||
*/
|
||||
public int getLine() {
|
||||
return this.line;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the column of the text resource where the property originated.
|
||||
*
|
||||
* @return the column number (zero indexed)
|
||||
*/
|
||||
public int getColumn() {
|
||||
return this.column;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return (31 * this.line) + this.column;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (obj == null || getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
Location other = (Location) obj;
|
||||
boolean result = true;
|
||||
result = result && this.line == other.line;
|
||||
result = result && this.column == other.column;
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return (this.line + 1) + ":" + (this.column + 1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class OriginTrackedPropertiesLoader {
|
||||
|
||||
private final Resource resource;
|
||||
|
||||
/**
|
||||
* Create a new {@link OriginTrackedPropertiesLoader} instance.
|
||||
*
|
||||
* @param resource the resource of the {@code .properties} data
|
||||
*/
|
||||
OriginTrackedPropertiesLoader(Resource resource) {
|
||||
Assert.notNull(resource, "Resource must not be null");
|
||||
this.resource = resource;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load {@code .properties} data and return a map of {@code String} ->
|
||||
* {@link OriginTrackedValue}.
|
||||
*
|
||||
* @return the loaded properties
|
||||
* @throws IOException on read error
|
||||
*/
|
||||
public Map<String, Object> load() throws IOException {
|
||||
return load(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load {@code .properties} data and return a map of {@code String} ->
|
||||
* {@link OriginTrackedValue}.
|
||||
*
|
||||
* @param expandLists if list {@code name[]=a,b,c} shortcuts should be expanded
|
||||
* @return the loaded properties
|
||||
* @throws IOException on read error
|
||||
*/
|
||||
public Map<String, Object> load(boolean expandLists) throws IOException {
|
||||
OriginTrackedPropertiesLoader.CharacterReader reader = new OriginTrackedPropertiesLoader.CharacterReader(
|
||||
this.resource);
|
||||
try {
|
||||
Map<String, Object> result = new LinkedHashMap<String, Object>();
|
||||
StringBuilder buffer = new StringBuilder();
|
||||
while (reader.read()) {
|
||||
String key = loadKey(buffer, reader).trim();
|
||||
if (expandLists && key.endsWith("[]")) {
|
||||
key = key.substring(0, key.length() - 2);
|
||||
int index = 0;
|
||||
do {
|
||||
OriginTrackedValue value = loadValue(buffer, reader, true);
|
||||
put(result, key + "[" + (index++) + "]", value);
|
||||
if (!reader.isEndOfLine()) {
|
||||
reader.read();
|
||||
}
|
||||
}
|
||||
while (!reader.isEndOfLine());
|
||||
}
|
||||
else {
|
||||
OriginTrackedValue value = loadValue(buffer, reader, false);
|
||||
put(result, key, value);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
finally {
|
||||
reader.close();
|
||||
}
|
||||
}
|
||||
|
||||
private void put(Map<String, Object> result, String key,
|
||||
OriginTrackedValue value) {
|
||||
if (!key.isEmpty()) {
|
||||
result.put(key, value.value);
|
||||
}
|
||||
}
|
||||
|
||||
private String loadKey(StringBuilder buffer,
|
||||
OriginTrackedPropertiesLoader.CharacterReader reader) throws IOException {
|
||||
buffer.setLength(0);
|
||||
boolean previousWhitespace = false;
|
||||
while (!reader.isEndOfLine()) {
|
||||
if (reader.isPropertyDelimiter()) {
|
||||
reader.read();
|
||||
return buffer.toString();
|
||||
}
|
||||
if (!reader.isWhiteSpace() && previousWhitespace) {
|
||||
return buffer.toString();
|
||||
}
|
||||
previousWhitespace = reader.isWhiteSpace();
|
||||
buffer.append(reader.getCharacter());
|
||||
reader.read();
|
||||
}
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
private OriginTrackedValue loadValue(StringBuilder buffer,
|
||||
OriginTrackedPropertiesLoader.CharacterReader reader, boolean splitLists)
|
||||
throws IOException {
|
||||
buffer.setLength(0);
|
||||
while (reader.isWhiteSpace() && !reader.isEndOfLine()) {
|
||||
reader.read();
|
||||
}
|
||||
Location location = reader.getLocation();
|
||||
while (!reader.isEndOfLine() && !(splitLists && reader.isListDelimiter())) {
|
||||
buffer.append(reader.getCharacter());
|
||||
reader.read();
|
||||
}
|
||||
TextResourceOrigin origin = new TextResourceOrigin(this.resource, location);
|
||||
return OriginTrackedValue.of(buffer.toString(), origin);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads characters from the source resource, taking care of skipping comments,
|
||||
* handling multi-line values and tracking {@code '\'} escapes.
|
||||
*/
|
||||
private class CharacterReader implements Closeable {
|
||||
|
||||
private final String[] ESCAPES = { "trnf", "\t\r\n\f" };
|
||||
|
||||
private final LineNumberReader reader;
|
||||
|
||||
private int columnNumber = -1;
|
||||
|
||||
private boolean escaped;
|
||||
|
||||
private int character;
|
||||
|
||||
CharacterReader(Resource resource) throws IOException {
|
||||
this.reader = new LineNumberReader(new InputStreamReader(
|
||||
resource.getInputStream(), StandardCharsets.UTF_8));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
this.reader.close();
|
||||
}
|
||||
|
||||
public boolean read() throws IOException {
|
||||
return read(false);
|
||||
}
|
||||
|
||||
public boolean read(boolean wrappedLine) throws IOException {
|
||||
this.escaped = false;
|
||||
this.character = this.reader.read();
|
||||
this.columnNumber++;
|
||||
if (this.columnNumber == 0) {
|
||||
skipLeadingWhitespace();
|
||||
if (!wrappedLine) {
|
||||
skipComment();
|
||||
}
|
||||
}
|
||||
if (this.character == '\\') {
|
||||
this.escaped = true;
|
||||
readEscaped();
|
||||
}
|
||||
else if (this.character == '\n') {
|
||||
this.columnNumber = -1;
|
||||
}
|
||||
return !isEndOfFile();
|
||||
}
|
||||
|
||||
private void skipLeadingWhitespace() throws IOException {
|
||||
while (isWhiteSpace()) {
|
||||
this.character = this.reader.read();
|
||||
this.columnNumber++;
|
||||
}
|
||||
}
|
||||
|
||||
private void skipComment() throws IOException {
|
||||
if (this.character == '#' || this.character == '!') {
|
||||
while (this.character != '\n' && this.character != -1) {
|
||||
this.character = this.reader.read();
|
||||
}
|
||||
this.columnNumber = -1;
|
||||
read();
|
||||
}
|
||||
}
|
||||
|
||||
private void readEscaped() throws IOException {
|
||||
this.character = this.reader.read();
|
||||
int escapeIndex = ESCAPES[0].indexOf(this.character);
|
||||
if (escapeIndex != -1) {
|
||||
this.character = ESCAPES[1].charAt(escapeIndex);
|
||||
}
|
||||
else if (this.character == '\n') {
|
||||
this.columnNumber = -1;
|
||||
read(true);
|
||||
}
|
||||
else if (this.character == 'u') {
|
||||
readUnicode();
|
||||
}
|
||||
}
|
||||
|
||||
private void readUnicode() throws IOException {
|
||||
this.character = 0;
|
||||
for (int i = 0; i < 4; i++) {
|
||||
int digit = this.reader.read();
|
||||
if (digit >= '0' && digit <= '9') {
|
||||
this.character = (this.character << 4) + digit - '0';
|
||||
}
|
||||
else if (digit >= 'a' && digit <= 'f') {
|
||||
this.character = (this.character << 4) + digit - 'a' + 10;
|
||||
}
|
||||
else if (digit >= 'A' && digit <= 'F') {
|
||||
this.character = (this.character << 4) + digit - 'A' + 10;
|
||||
}
|
||||
else {
|
||||
throw new IllegalStateException("Malformed \\uxxxx encoding.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isWhiteSpace() {
|
||||
return !this.escaped && (this.character == ' ' || this.character == '\t'
|
||||
|| this.character == '\f');
|
||||
}
|
||||
|
||||
public boolean isEndOfFile() {
|
||||
return this.character == -1;
|
||||
}
|
||||
|
||||
public boolean isEndOfLine() {
|
||||
return this.character == -1 || (!this.escaped && this.character == '\n');
|
||||
}
|
||||
|
||||
public boolean isListDelimiter() {
|
||||
return !this.escaped && this.character == ',';
|
||||
}
|
||||
|
||||
public boolean isPropertyDelimiter() {
|
||||
return !this.escaped && (this.character == '=' || this.character == ':');
|
||||
}
|
||||
|
||||
public char getCharacter() {
|
||||
return (char) this.character;
|
||||
}
|
||||
|
||||
public Location getLocation() {
|
||||
return new Location(this.reader.getLineNumber(), this.columnNumber);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public class TextResourceOrigin extends Origin {
|
||||
|
||||
private final Resource resource;
|
||||
|
||||
private final Location location;
|
||||
|
||||
public TextResourceOrigin(Resource resource, Location location) {
|
||||
this.resource = resource;
|
||||
this.location = location;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the resource where the property originated.
|
||||
*
|
||||
* @return the text resource or {@code null}
|
||||
*/
|
||||
public Resource getResource() {
|
||||
return this.resource;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the location of the property within the source (if known).
|
||||
*
|
||||
* @return the location or {@code null}
|
||||
*/
|
||||
public Location getLocation() {
|
||||
return this.location;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = 1;
|
||||
result = 31 * result + ObjectUtils.nullSafeHashCode(this.resource);
|
||||
result = 31 * result + ObjectUtils.nullSafeHashCode(this.location);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
if (obj instanceof TextResourceOrigin) {
|
||||
TextResourceOrigin other = (TextResourceOrigin) obj;
|
||||
boolean result = true;
|
||||
result = result
|
||||
&& ObjectUtils.nullSafeEquals(this.resource, other.resource);
|
||||
result = result
|
||||
&& ObjectUtils.nullSafeEquals(this.location, other.location);
|
||||
return result;
|
||||
}
|
||||
return super.equals(obj);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder result = new StringBuilder();
|
||||
result.append(this.resource != null ? this.resource.getDescription()
|
||||
: "unknown resource [?]");
|
||||
if (this.location != null) {
|
||||
result.append(":").append(this.location);
|
||||
}
|
||||
return result.toString();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -21,18 +21,17 @@ import java.util.LinkedHashMap;
|
|||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
|
||||
import com.alibaba.nacos.api.config.ConfigType;
|
||||
import com.alibaba.nacos.spring.util.AbstractConfigParse;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.NodeList;
|
||||
|
||||
import org.springframework.util.StringUtils;
|
||||
import com.alibaba.nacos.api.config.ConfigType;
|
||||
import com.alibaba.nacos.spring.util.AbstractConfigParse;
|
||||
|
||||
/*
|
||||
<xmlSign>
|
||||
|
@ -79,8 +78,8 @@ public class DefaultXmlConfigParse extends AbstractConfigParse {
|
|||
private DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
|
||||
|
||||
@Override
|
||||
public Properties parse(String configText) {
|
||||
Properties properties = new Properties();
|
||||
public Map<String, Object> parse(String configText) {
|
||||
Map<String, Object> properties = new LinkedHashMap<String, Object>(8);
|
||||
try {
|
||||
Document document = factory.newDocumentBuilder()
|
||||
.parse(new ByteArrayInputStream(configText.getBytes("UTF-8")));
|
||||
|
@ -131,7 +130,8 @@ public class DefaultXmlConfigParse extends AbstractConfigParse {
|
|||
}
|
||||
}
|
||||
|
||||
private void mapToProperties(String prefixName, Properties properties, Object data) {
|
||||
private void mapToProperties(String prefixName, Map<String, Object> properties,
|
||||
Object data) {
|
||||
if (data instanceof List) {
|
||||
List list = (List) data;
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
|
@ -150,7 +150,7 @@ public class DefaultXmlConfigParse extends AbstractConfigParse {
|
|||
}
|
||||
}
|
||||
else {
|
||||
properties.setProperty(prefixName, String.valueOf(data));
|
||||
properties.put(prefixName, String.valueOf(data));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -14,200 +14,183 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.spring.util.parse;
|
||||
|
||||
import java.util.AbstractMap;
|
||||
import com.alibaba.nacos.api.config.ConfigType;
|
||||
import com.alibaba.nacos.spring.util.AbstractConfigParse;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.yaml.snakeyaml.DumperOptions;
|
||||
import org.yaml.snakeyaml.LoaderOptions;
|
||||
import org.yaml.snakeyaml.Yaml;
|
||||
import org.yaml.snakeyaml.constructor.Constructor;
|
||||
import org.yaml.snakeyaml.constructor.SafeConstructor;
|
||||
import org.yaml.snakeyaml.nodes.Tag;
|
||||
import org.yaml.snakeyaml.representer.Representer;
|
||||
import org.yaml.snakeyaml.resolver.Resolver;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
|
||||
import com.alibaba.nacos.api.config.ConfigType;
|
||||
import com.alibaba.nacos.spring.util.AbstractConfigParse;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.yaml.snakeyaml.Yaml;
|
||||
import org.yaml.snakeyaml.constructor.Constructor;
|
||||
import org.yaml.snakeyaml.nodes.MappingNode;
|
||||
import org.yaml.snakeyaml.parser.ParserException;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* DefaultYamlConfigParse.
|
||||
*
|
||||
* @author <a href="mailto:liaochunyhm@live.com">liaochuntao</a>
|
||||
* @since 0.3.0
|
||||
*/
|
||||
public class DefaultYamlConfigParse extends AbstractConfigParse {
|
||||
|
||||
protected static final Logger logger = LoggerFactory
|
||||
.getLogger(DefaultYamlConfigParse.class);
|
||||
protected static final Logger LOGGER = LoggerFactory.getLogger(DefaultYamlConfigParse.class);
|
||||
|
||||
protected static Yaml createYaml() {
|
||||
return new Yaml(new MapAppenderConstructor());
|
||||
}
|
||||
private static final String YAML_ALLOW_COMPLEX_OBJECT = "yamlAllowComplexObject";
|
||||
|
||||
@Override
|
||||
public Properties parse(String configText) {
|
||||
final Properties result = new Properties();
|
||||
process(new MatchCallback() {
|
||||
@Override
|
||||
public void process(Properties properties, Map<String, Object> map) {
|
||||
result.putAll(properties);
|
||||
}
|
||||
}, createYaml(), configText);
|
||||
return result;
|
||||
}
|
||||
private static boolean getYamlAllowComplexObject() {
|
||||
return Boolean.getBoolean(YAML_ALLOW_COMPLEX_OBJECT);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String processType() {
|
||||
return ConfigType.YAML.getType();
|
||||
}
|
||||
protected static Yaml createYaml() {
|
||||
LoaderOptions loaderOptions = new LoaderOptions();
|
||||
loaderOptions.setAllowDuplicateKeys(false);
|
||||
SafeConstructor constructor;
|
||||
if (getYamlAllowComplexObject()) {
|
||||
constructor = new Constructor(loaderOptions);
|
||||
} else {
|
||||
constructor = new SafeConstructor(loaderOptions);
|
||||
}
|
||||
DumperOptions dumperOptions = new DumperOptions();
|
||||
Representer representer = new Representer(dumperOptions);
|
||||
LimitedResolver resolver = new LimitedResolver();
|
||||
return new Yaml(constructor, representer, dumperOptions, loaderOptions, resolver);
|
||||
}
|
||||
|
||||
protected static boolean process(MatchCallback callback, Yaml yaml, String content) {
|
||||
int count = 0;
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Loading from YAML: " + content);
|
||||
}
|
||||
for (Object object : yaml.loadAll(content)) {
|
||||
if (object != null && process(asMap(object), callback)) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Loaded " + count + " document" + (count > 1 ? "s" : "")
|
||||
+ " from YAML resource: " + content);
|
||||
}
|
||||
return (count > 0);
|
||||
}
|
||||
protected static boolean process(MatchCallback callback, Yaml yaml, String content) {
|
||||
int count = 0;
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug("Loading from YAML: " + content);
|
||||
}
|
||||
for (Object object : yaml.loadAll(content)) {
|
||||
if (object != null && process(asMap(object), callback)) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug("Loaded " + count + " document" + (count > 1 ? "s" : "") + " from YAML resource: " + content);
|
||||
}
|
||||
return (count > 0);
|
||||
}
|
||||
|
||||
protected static boolean process(Map<String, Object> map, MatchCallback callback) {
|
||||
Properties properties = new Properties();
|
||||
properties.putAll(getFlattenedMap(map));
|
||||
protected static boolean process(Map<String, Object> map, MatchCallback callback) {
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug("Merging document (no matchers set): " + map);
|
||||
}
|
||||
callback.process(getFlattenedMap(map));
|
||||
return true;
|
||||
}
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Merging document (no matchers set): " + map);
|
||||
}
|
||||
callback.process(properties, map);
|
||||
return true;
|
||||
}
|
||||
@SuppressWarnings("unchecked")
|
||||
protected static Map<String, Object> asMap(Object object) {
|
||||
// YAML can have numbers as keys
|
||||
Map<String, Object> result = new LinkedHashMap();
|
||||
if (!(object instanceof Map)) {
|
||||
// A document can be a text literal
|
||||
result.put("document", object);
|
||||
return result;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
protected static Map<String, Object> asMap(Object object) {
|
||||
// YAML can have numbers as keys
|
||||
Map<String, Object> result = new LinkedHashMap();
|
||||
if (!(object instanceof Map)) {
|
||||
// A document can be a text literal
|
||||
result.put("document", object);
|
||||
return result;
|
||||
}
|
||||
Map<Object, Object> map = (Map<Object, Object>) object;
|
||||
for (Map.Entry<Object, Object> entry : map.entrySet()) {
|
||||
Object key = entry.getKey();
|
||||
Object value = entry.getValue();
|
||||
if (value instanceof Map) {
|
||||
value = asMap(value);
|
||||
}
|
||||
if (key instanceof CharSequence) {
|
||||
result.put(key.toString(), value);
|
||||
} else {
|
||||
result.put("[" + key.toString() + "]", value);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
Map<Object, Object> map = (Map<Object, Object>) object;
|
||||
for (Map.Entry<Object, Object> entry : map.entrySet()) {
|
||||
Object key = entry.getKey();
|
||||
Object value = entry.getValue();
|
||||
if (value instanceof Map) {
|
||||
value = asMap(value);
|
||||
}
|
||||
if (key instanceof CharSequence) {
|
||||
result.put(key.toString(), value);
|
||||
}
|
||||
else {
|
||||
result.put("[" + key.toString() + "]", value);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
private static class LimitedResolver extends Resolver {
|
||||
|
||||
protected static Map<String, Object> getFlattenedMap(Map<String, Object> source) {
|
||||
Map<String, Object> result = new LinkedHashMap<String, Object>();
|
||||
buildFlattenedMap(result, source, null);
|
||||
return result;
|
||||
}
|
||||
@Override
|
||||
public void addImplicitResolver(Tag tag, Pattern regexp, String first) {
|
||||
if (tag == Tag.TIMESTAMP) {
|
||||
return;
|
||||
}
|
||||
super.addImplicitResolver(tag, regexp, first);
|
||||
}
|
||||
}
|
||||
|
||||
protected static void buildFlattenedMap(Map<String, Object> result,
|
||||
Map<String, Object> source, String path) {
|
||||
for (Map.Entry<String, Object> entry : source.entrySet()) {
|
||||
String key = entry.getKey();
|
||||
if (!com.alibaba.nacos.client.utils.StringUtils.isBlank(path)) {
|
||||
if (key.startsWith("[")) {
|
||||
key = path + key;
|
||||
}
|
||||
else {
|
||||
key = path + '.' + key;
|
||||
}
|
||||
}
|
||||
Object value = entry.getValue();
|
||||
if (value instanceof String) {
|
||||
result.put(key, value);
|
||||
}
|
||||
else if (value instanceof Map) {
|
||||
// Need a compound key
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, Object> map = (Map<String, Object>) value;
|
||||
buildFlattenedMap(result, map, key);
|
||||
}
|
||||
else if (value instanceof Collection) {
|
||||
// Need a compound key
|
||||
@SuppressWarnings("unchecked")
|
||||
Collection<Object> collection = (Collection<Object>) value;
|
||||
int count = 0;
|
||||
for (Object object : collection) {
|
||||
buildFlattenedMap(result,
|
||||
Collections.singletonMap("[" + (count++) + "]", object), key);
|
||||
}
|
||||
}
|
||||
else {
|
||||
result.put(key, (value != null ? value.toString() : ""));
|
||||
}
|
||||
}
|
||||
}
|
||||
protected static Map<String, Object> getFlattenedMap(Map<String, Object> source) {
|
||||
Map<String, Object> result = new LinkedHashMap<String, Object>();
|
||||
buildFlattenedMap(result, source, null);
|
||||
return result;
|
||||
}
|
||||
|
||||
protected interface MatchCallback {
|
||||
protected static void buildFlattenedMap(Map<String, Object> result, Map<String, Object> source, String path) {
|
||||
for (Map.Entry<String, Object> entry : source.entrySet()) {
|
||||
String key = entry.getKey();
|
||||
if (!StringUtils.isBlank(path)) {
|
||||
if (key.startsWith("[")) {
|
||||
key = path + key;
|
||||
} else {
|
||||
key = path + '.' + key;
|
||||
}
|
||||
}
|
||||
Object value = entry.getValue();
|
||||
if (value instanceof String) {
|
||||
result.put(key, value);
|
||||
} else if (value instanceof Map) {
|
||||
// Need a compound key
|
||||
@SuppressWarnings("unchecked") Map<String, Object> map = (Map<String, Object>) value;
|
||||
buildFlattenedMap(result, map, key);
|
||||
} else if (value instanceof Collection) {
|
||||
// Need a compound key
|
||||
@SuppressWarnings("unchecked") Collection<Object> collection = (Collection<Object>) value;
|
||||
int count = 0;
|
||||
for (Object object : collection) {
|
||||
buildFlattenedMap(result, Collections.singletonMap("[" + (count++) + "]", object), key);
|
||||
}
|
||||
} else {
|
||||
result.put(key, (value != null ? value.toString() : ""));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Put Map to Properties
|
||||
*
|
||||
* @param properties {@link Properties}
|
||||
* @param map {@link Map}
|
||||
*/
|
||||
void process(Properties properties, Map<String, Object> map);
|
||||
}
|
||||
@Override
|
||||
public Map<String, Object> parse(String configText) {
|
||||
final AtomicReference<Map<String, Object>> result = new AtomicReference<Map<String, Object>>();
|
||||
process(new MatchCallback() {
|
||||
@Override
|
||||
public void process(Map<String, Object> map) {
|
||||
result.set(map);
|
||||
}
|
||||
}, createYaml(), configText);
|
||||
return result.get();
|
||||
}
|
||||
|
||||
protected static class MapAppenderConstructor extends Constructor {
|
||||
@Override
|
||||
public String processType() {
|
||||
return ConfigType.YAML.getType();
|
||||
}
|
||||
|
||||
MapAppenderConstructor() {
|
||||
super();
|
||||
}
|
||||
protected interface MatchCallback {
|
||||
|
||||
@Override
|
||||
protected Map<Object, Object> constructMapping(MappingNode node) {
|
||||
try {
|
||||
return super.constructMapping(node);
|
||||
}
|
||||
catch (IllegalStateException ex) {
|
||||
throw new ParserException("while parsing MappingNode",
|
||||
node.getStartMark(), ex.getMessage(), node.getEndMark());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Map<Object, Object> createDefaultMap() {
|
||||
final Map<Object, Object> delegate = super.createDefaultMap();
|
||||
return new AbstractMap<Object, Object>() {
|
||||
@Override
|
||||
public Object put(Object key, Object value) {
|
||||
if (delegate.containsKey(key)) {
|
||||
throw new IllegalStateException("Duplicate key: " + key);
|
||||
}
|
||||
return delegate.put(key, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Entry<Object, Object>> entrySet() {
|
||||
return delegate.entrySet();
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Put Map to Properties.
|
||||
*
|
||||
* @param map {@link Map}
|
||||
*/
|
||||
void process(Map<String, Object> map);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
</xsd:annotation>
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="endpoint" default="${nacos.endpoint:}"/>
|
||||
<xsd:attribute name="namespace" default="${nacos.endpoint:}"/>
|
||||
<xsd:attribute name="namespace" default="${nacos.namespace:}"/>
|
||||
<xsd:attribute name="access-key" default="${nacos.access-key:}"/>
|
||||
<xsd:attribute name="secret-key" default="${nacos.secret-key:}"/>
|
||||
<xsd:attribute name="server-addr" default="${nacos.server-addr:}"/>
|
||||
|
@ -63,7 +63,7 @@
|
|||
<xsd:attribute name="first" default="false"/>
|
||||
<xsd:attribute name="before" default=""/>
|
||||
<xsd:attribute name="after" default=""/>
|
||||
<xsd:attribute name="type" default="properties" />
|
||||
<xsd:attribute name="type" default="properties"/>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
*
|
||||
* * Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* * contributor license agreements. See the NOTICE file distributed with
|
||||
* * this work for additional information regarding copyright ownership.
|
||||
* * The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* * (the "License"); you may not use this file except in compliance with
|
||||
* * the License. You may obtain a copy of the License at
|
||||
* *
|
||||
* * http://www.apache.org/licenses/LICENSE-2.0
|
||||
* *
|
||||
* * Unless required by applicable law or agreed to in writing, software
|
||||
* * distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* * See the License for the specific language governing permissions and
|
||||
* * limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.spring.beans.factory.annotation;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.beans.IntrospectionException;
|
||||
import java.beans.PropertyDescriptor;
|
||||
|
||||
/**
|
||||
* {@link AbstractAnnotationBeanPostProcessor} Test
|
||||
* @author SuperZ1999
|
||||
* @date 2023/9/28
|
||||
*/
|
||||
public class AbstractAnnotationBeanPostProcessorTest {
|
||||
@Test
|
||||
public void testPropertyDescriptor() throws IntrospectionException {
|
||||
PropertyDescriptor pd = new PropertyDescriptor("name", Student.class);
|
||||
Class<?> type = pd.getPropertyType();
|
||||
Assert.assertEquals(type, String.class);
|
||||
}
|
||||
|
||||
static class Student {
|
||||
String name;
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -16,6 +16,23 @@
|
|||
*/
|
||||
package com.alibaba.nacos.spring.beans.factory.annotation;
|
||||
|
||||
import static com.alibaba.nacos.spring.test.MockNacosServiceFactory.CONTENT;
|
||||
import static com.alibaba.nacos.spring.test.MockNacosServiceFactory.DATA_ID;
|
||||
import static com.alibaba.nacos.spring.test.MockNacosServiceFactory.GROUP_ID;
|
||||
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Assert;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.TestExecutionListeners;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.test.context.support.DependencyInjectionTestExecutionListener;
|
||||
import org.springframework.test.context.support.DirtiesContextTestExecutionListener;
|
||||
|
||||
import com.alibaba.nacos.api.annotation.NacosInjected;
|
||||
import com.alibaba.nacos.api.annotation.NacosProperties;
|
||||
import com.alibaba.nacos.api.config.ConfigService;
|
||||
|
@ -25,21 +42,7 @@ import com.alibaba.nacos.spring.context.annotation.EnableNacos;
|
|||
import com.alibaba.nacos.spring.factory.ApplicationContextHolder;
|
||||
import com.alibaba.nacos.spring.test.AbstractNacosHttpServerTestExecutionListener;
|
||||
import com.alibaba.nacos.spring.test.TestConfiguration;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.TestExecutionListeners;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.test.context.support.DependencyInjectionTestExecutionListener;
|
||||
import org.springframework.test.context.support.DirtiesContextTestExecutionListener;
|
||||
|
||||
import static com.alibaba.nacos.spring.test.MockNacosServiceFactory.CONTENT;
|
||||
import static com.alibaba.nacos.spring.test.MockNacosServiceFactory.DATA_ID;
|
||||
import static com.alibaba.nacos.spring.test.MockNacosServiceFactory.GROUP_ID;
|
||||
import com.alibaba.nacos.spring.util.NacosUtils;
|
||||
|
||||
/**
|
||||
* {@link AnnotationNacosInjectedBeanPostProcessor} Test
|
||||
|
@ -58,6 +61,19 @@ import static com.alibaba.nacos.spring.test.MockNacosServiceFactory.GROUP_ID;
|
|||
public class AnnotationNacosInjectedBeanPostProcessorTest
|
||||
extends AbstractNacosHttpServerTestExecutionListener {
|
||||
|
||||
@NacosInjected
|
||||
private ConfigService configService;
|
||||
@NacosInjected(properties = @NacosProperties(encode = "UTF-8"))
|
||||
private ConfigService configService2;
|
||||
@NacosInjected(properties = @NacosProperties(encode = "GBK"))
|
||||
private ConfigService configService3;
|
||||
@NacosInjected
|
||||
private NamingService namingService;
|
||||
@NacosInjected(properties = @NacosProperties(encode = "UTF-8"))
|
||||
private NamingService namingService2;
|
||||
@NacosInjected(properties = @NacosProperties(encode = "GBK"))
|
||||
private NamingService namingService3;
|
||||
|
||||
@Bean(name = ApplicationContextHolder.BEAN_NAME)
|
||||
public ApplicationContextHolder applicationContextHolder(
|
||||
ApplicationContext applicationContext) {
|
||||
|
@ -71,24 +87,6 @@ public class AnnotationNacosInjectedBeanPostProcessorTest
|
|||
return "server.addr";
|
||||
}
|
||||
|
||||
@NacosInjected
|
||||
private ConfigService configService;
|
||||
|
||||
@NacosInjected(properties = @NacosProperties(encode = "UTF-8"))
|
||||
private ConfigService configService2;
|
||||
|
||||
@NacosInjected(properties = @NacosProperties(encode = "GBK"))
|
||||
private ConfigService configService3;
|
||||
|
||||
@NacosInjected
|
||||
private NamingService namingService;
|
||||
|
||||
@NacosInjected(properties = @NacosProperties(encode = "UTF-8"))
|
||||
private NamingService namingService2;
|
||||
|
||||
@NacosInjected(properties = @NacosProperties(encode = "GBK"))
|
||||
private NamingService namingService3;
|
||||
|
||||
@Test
|
||||
public void testInjection() {
|
||||
|
||||
|
|
|
@ -16,21 +16,18 @@
|
|||
*/
|
||||
package com.alibaba.nacos.spring.config;
|
||||
|
||||
import static com.alibaba.nacos.api.common.Constants.DEFAULT_GROUP;
|
||||
import static com.alibaba.nacos.embedded.web.server.NacosConfigHttpHandler.CONTENT_PARAM_NAME;
|
||||
import static com.alibaba.nacos.embedded.web.server.NacosConfigHttpHandler.DATA_ID_PARAM_NAME;
|
||||
import static com.alibaba.nacos.embedded.web.server.NacosConfigHttpHandler.GROUP_ID_PARAM_NAME;
|
||||
import static com.alibaba.nacos.spring.test.MockNacosServiceFactory.DATA_ID;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import com.alibaba.nacos.api.annotation.NacosInjected;
|
||||
import com.alibaba.nacos.api.config.ConfigService;
|
||||
import com.alibaba.nacos.embedded.web.server.EmbeddedNacosHttpServer;
|
||||
import com.alibaba.nacos.spring.context.config.xml.GlobalNacosPropertiesBeanDefinitionParser;
|
||||
import com.alibaba.nacos.spring.context.config.xml.NacosAnnotationDrivenBeanDefinitionParser;
|
||||
import com.alibaba.nacos.spring.context.config.xml.NacosNamespaceHandler;
|
||||
import com.alibaba.nacos.spring.test.AbstractNacosHttpServerTestExecutionListener;
|
||||
import com.alibaba.nacos.spring.test.User;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
|
@ -39,11 +36,16 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
|||
import org.springframework.test.context.support.DependencyInjectionTestExecutionListener;
|
||||
import org.springframework.test.context.support.DirtiesContextTestExecutionListener;
|
||||
|
||||
import static com.alibaba.nacos.api.common.Constants.DEFAULT_GROUP;
|
||||
import static com.alibaba.nacos.embedded.web.server.NacosConfigHttpHandler.CONTENT_PARAM_NAME;
|
||||
import static com.alibaba.nacos.embedded.web.server.NacosConfigHttpHandler.DATA_ID_PARAM_NAME;
|
||||
import static com.alibaba.nacos.embedded.web.server.NacosConfigHttpHandler.GROUP_ID_PARAM_NAME;
|
||||
import static com.alibaba.nacos.spring.test.MockNacosServiceFactory.DATA_ID;
|
||||
import com.alibaba.nacos.api.annotation.NacosInjected;
|
||||
import com.alibaba.nacos.api.annotation.NacosProperties;
|
||||
import com.alibaba.nacos.api.config.ConfigService;
|
||||
import com.alibaba.nacos.embedded.web.server.EmbeddedNacosHttpServer;
|
||||
import com.alibaba.nacos.spring.context.annotation.EnableNacos;
|
||||
import com.alibaba.nacos.spring.context.config.xml.GlobalNacosPropertiesBeanDefinitionParser;
|
||||
import com.alibaba.nacos.spring.context.config.xml.NacosAnnotationDrivenBeanDefinitionParser;
|
||||
import com.alibaba.nacos.spring.context.config.xml.NacosNamespaceHandler;
|
||||
import com.alibaba.nacos.spring.test.AbstractNacosHttpServerTestExecutionListener;
|
||||
import com.alibaba.nacos.spring.test.User;
|
||||
|
||||
/**
|
||||
* {@link NacosNamespaceHandler} Test
|
||||
|
@ -59,11 +61,13 @@ import static com.alibaba.nacos.spring.test.MockNacosServiceFactory.DATA_ID;
|
|||
@DirtiesContext
|
||||
@TestExecutionListeners({ DependencyInjectionTestExecutionListener.class,
|
||||
DirtiesContextTestExecutionListener.class, NacosNamespaceHandlerTest.class })
|
||||
@EnableNacos(globalProperties = @NacosProperties(serverAddr = "${nacos.server-addr}"))
|
||||
public class NacosNamespaceHandlerTest
|
||||
extends AbstractNacosHttpServerTestExecutionListener {
|
||||
|
||||
@Autowired
|
||||
private User user;
|
||||
@NacosInjected
|
||||
private ConfigService configService;
|
||||
|
||||
@Override
|
||||
protected String getServerAddressPropertyName() {
|
||||
|
@ -79,9 +83,6 @@ public class NacosNamespaceHandlerTest
|
|||
server.initConfig(config);
|
||||
}
|
||||
|
||||
@NacosInjected
|
||||
private ConfigService configService;
|
||||
|
||||
@Test
|
||||
public void testGetConfig() throws Exception {
|
||||
configService.publishConfig(DATA_ID, DEFAULT_GROUP, "9527");
|
||||
|
|
|
@ -16,9 +16,29 @@
|
|||
*/
|
||||
package com.alibaba.nacos.spring.context.annotation;
|
||||
|
||||
import static com.alibaba.nacos.api.common.Constants.DEFAULT_GROUP;
|
||||
import static com.alibaba.nacos.spring.test.MockNacosServiceFactory.DATA_ID;
|
||||
import static com.alibaba.nacos.spring.util.NacosBeanUtils.NACOS_CONFIG_LISTENER_EXECUTOR_BEAN_NAME;
|
||||
import static com.alibaba.nacos.spring.util.NacosBeanUtils.PLACEHOLDER_CONFIGURER_BEAN_NAME;
|
||||
|
||||
import java.util.Properties;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.TestExecutionListeners;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.test.context.support.DependencyInjectionTestExecutionListener;
|
||||
import org.springframework.test.context.support.DirtiesContextTestExecutionListener;
|
||||
|
||||
import com.alibaba.nacos.api.annotation.NacosInjected;
|
||||
import com.alibaba.nacos.api.annotation.NacosProperties;
|
||||
import com.alibaba.nacos.api.config.ConfigService;
|
||||
|
@ -36,25 +56,7 @@ import com.alibaba.nacos.spring.core.env.NacosPropertySourcePostProcessor;
|
|||
import com.alibaba.nacos.spring.test.AbstractNacosHttpServerTestExecutionListener;
|
||||
import com.alibaba.nacos.spring.test.Config;
|
||||
import com.alibaba.nacos.spring.util.NacosBeanUtils;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.TestExecutionListeners;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.test.context.support.DependencyInjectionTestExecutionListener;
|
||||
import org.springframework.test.context.support.DirtiesContextTestExecutionListener;
|
||||
|
||||
import static com.alibaba.nacos.api.common.Constants.DEFAULT_GROUP;
|
||||
import static com.alibaba.nacos.spring.test.MockNacosServiceFactory.DATA_ID;
|
||||
import static com.alibaba.nacos.spring.util.NacosBeanUtils.NACOS_CONFIG_LISTENER_EXECUTOR_BEAN_NAME;
|
||||
import static com.alibaba.nacos.spring.util.NacosBeanUtils.PLACEHOLDER_CONFIGURER_BEAN_NAME;
|
||||
import com.alibaba.nacos.spring.util.NacosUtils;
|
||||
|
||||
/**
|
||||
* {@link NacosBeanDefinitionRegistrar} Test
|
||||
|
@ -73,6 +75,56 @@ import static com.alibaba.nacos.spring.util.NacosBeanUtils.PLACEHOLDER_CONFIGURE
|
|||
public class NacosBeanDefinitionRegistrarTest
|
||||
extends AbstractNacosHttpServerTestExecutionListener {
|
||||
|
||||
@Autowired
|
||||
@Qualifier(NacosBeanUtils.GLOBAL_NACOS_PROPERTIES_BEAN_NAME)
|
||||
private Properties globalProperties;
|
||||
@Autowired
|
||||
@Qualifier(NacosBeanUtils.CONFIG_GLOBAL_NACOS_PROPERTIES_BEAN_NAME)
|
||||
private Properties configGlobalProperties;
|
||||
@Autowired
|
||||
@Qualifier(NacosBeanUtils.DISCOVERY_GLOBAL_NACOS_PROPERTIES_BEAN_NAME)
|
||||
private Properties discoveryGlobalProperties;
|
||||
@Autowired
|
||||
@Qualifier(AnnotationNacosInjectedBeanPostProcessor.BEAN_NAME)
|
||||
private AnnotationNacosInjectedBeanPostProcessor annotationNacosInjectedBeanPostProcessor;
|
||||
@Autowired
|
||||
@Qualifier(PLACEHOLDER_CONFIGURER_BEAN_NAME)
|
||||
private PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer;
|
||||
@Autowired
|
||||
@Qualifier(NacosConfigurationPropertiesBindingPostProcessor.BEAN_NAME)
|
||||
private NacosConfigurationPropertiesBindingPostProcessor nacosConfigurationPropertiesBindingPostProcessor;
|
||||
@Autowired
|
||||
@Qualifier(NacosConfigListenerMethodProcessor.BEAN_NAME)
|
||||
private NacosConfigListenerMethodProcessor nacosConfigListenerMethodProcessor;
|
||||
@Autowired
|
||||
@Qualifier(NacosPropertySourcePostProcessor.BEAN_NAME)
|
||||
private NacosPropertySourcePostProcessor nacosPropertySourcePostProcessor;
|
||||
@Autowired
|
||||
@Qualifier(AnnotationNacosPropertySourceBuilder.BEAN_NAME)
|
||||
private AnnotationNacosPropertySourceBuilder annotationNacosPropertySourceBuilder;
|
||||
@Autowired
|
||||
@Qualifier(NacosValueAnnotationBeanPostProcessor.BEAN_NAME)
|
||||
private NacosValueAnnotationBeanPostProcessor nacosValueAnnotationBeanPostProcessor;
|
||||
@Autowired
|
||||
@Qualifier(ConfigServiceBeanBuilder.BEAN_NAME)
|
||||
private ConfigServiceBeanBuilder configServiceBeanBuilder;
|
||||
@Autowired
|
||||
@Qualifier(NACOS_CONFIG_LISTENER_EXECUTOR_BEAN_NAME)
|
||||
private ExecutorService nacosConfigListenerExecutor;
|
||||
@Autowired
|
||||
@Qualifier(NamingServiceBeanBuilder.BEAN_NAME)
|
||||
private NamingServiceBeanBuilder namingServiceBeanBuilder;
|
||||
@NacosInjected
|
||||
private ConfigService globalConfigService;
|
||||
@NacosInjected(properties = @NacosProperties(serverAddr = "${server.addr}"))
|
||||
private ConfigService configService;
|
||||
@NacosInjected
|
||||
private NamingService namingService;
|
||||
@Autowired
|
||||
private Config config;
|
||||
@Value("${user.home:${user.dir}}")
|
||||
private String dir;
|
||||
|
||||
@Override
|
||||
protected String getServerAddressPropertyName() {
|
||||
return "server.addr";
|
||||
|
@ -83,72 +135,6 @@ public class NacosBeanDefinitionRegistrarTest
|
|||
return new Config();
|
||||
}
|
||||
|
||||
@Autowired
|
||||
@Qualifier(NacosBeanUtils.GLOBAL_NACOS_PROPERTIES_BEAN_NAME)
|
||||
private Properties globalProperties;
|
||||
|
||||
@Autowired
|
||||
@Qualifier(NacosBeanUtils.CONFIG_GLOBAL_NACOS_PROPERTIES_BEAN_NAME)
|
||||
private Properties configGlobalProperties;
|
||||
@Autowired
|
||||
@Qualifier(NacosBeanUtils.DISCOVERY_GLOBAL_NACOS_PROPERTIES_BEAN_NAME)
|
||||
private Properties discoveryGlobalProperties;
|
||||
|
||||
@Autowired
|
||||
@Qualifier(AnnotationNacosInjectedBeanPostProcessor.BEAN_NAME)
|
||||
private AnnotationNacosInjectedBeanPostProcessor annotationNacosInjectedBeanPostProcessor;
|
||||
|
||||
@Autowired
|
||||
@Qualifier(PLACEHOLDER_CONFIGURER_BEAN_NAME)
|
||||
private PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer;
|
||||
|
||||
@Autowired
|
||||
@Qualifier(NacosConfigurationPropertiesBindingPostProcessor.BEAN_NAME)
|
||||
private NacosConfigurationPropertiesBindingPostProcessor nacosConfigurationPropertiesBindingPostProcessor;
|
||||
|
||||
@Autowired
|
||||
@Qualifier(NacosConfigListenerMethodProcessor.BEAN_NAME)
|
||||
private NacosConfigListenerMethodProcessor nacosConfigListenerMethodProcessor;
|
||||
|
||||
@Autowired
|
||||
@Qualifier(NacosPropertySourcePostProcessor.BEAN_NAME)
|
||||
private NacosPropertySourcePostProcessor nacosPropertySourcePostProcessor;
|
||||
|
||||
@Autowired
|
||||
@Qualifier(AnnotationNacosPropertySourceBuilder.BEAN_NAME)
|
||||
private AnnotationNacosPropertySourceBuilder annotationNacosPropertySourceBuilder;
|
||||
|
||||
@Autowired
|
||||
@Qualifier(NacosValueAnnotationBeanPostProcessor.BEAN_NAME)
|
||||
private NacosValueAnnotationBeanPostProcessor nacosValueAnnotationBeanPostProcessor;
|
||||
|
||||
@Autowired
|
||||
@Qualifier(ConfigServiceBeanBuilder.BEAN_NAME)
|
||||
private ConfigServiceBeanBuilder configServiceBeanBuilder;
|
||||
|
||||
@Autowired
|
||||
@Qualifier(NACOS_CONFIG_LISTENER_EXECUTOR_BEAN_NAME)
|
||||
private ExecutorService nacosConfigListenerExecutor;
|
||||
|
||||
@Autowired
|
||||
@Qualifier(NamingServiceBeanBuilder.BEAN_NAME)
|
||||
private NamingServiceBeanBuilder namingServiceBeanBuilder;
|
||||
|
||||
@NacosInjected
|
||||
private ConfigService globalConfigService;
|
||||
|
||||
@NacosInjected(properties = @NacosProperties(serverAddr = "${server.addr}"))
|
||||
private ConfigService configService;
|
||||
|
||||
@NacosInjected
|
||||
private NamingService namingService;
|
||||
|
||||
@Autowired
|
||||
private Config config;
|
||||
|
||||
@Value("${user.home:${user.dir}}")
|
||||
private String dir;
|
||||
|
||||
@Test
|
||||
public void testGetConfig() throws Exception {
|
||||
configService.publishConfig(DATA_ID, DEFAULT_GROUP, "9527");
|
||||
|
|
|
@ -16,11 +16,6 @@
|
|||
*/
|
||||
package com.alibaba.nacos.spring.context.annotation.config;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.mock.env.MockEnvironment;
|
||||
|
||||
import static com.alibaba.nacos.spring.context.annotation.config.EnableNacosConfig.ACCESS_KEY_PLACEHOLDER;
|
||||
import static com.alibaba.nacos.spring.context.annotation.config.EnableNacosConfig.CLUSTER_NAME_PLACEHOLDER;
|
||||
import static com.alibaba.nacos.spring.context.annotation.config.EnableNacosConfig.CONTEXT_PATH_PLACEHOLDER;
|
||||
|
@ -30,6 +25,10 @@ import static com.alibaba.nacos.spring.context.annotation.config.EnableNacosConf
|
|||
import static com.alibaba.nacos.spring.context.annotation.config.EnableNacosConfig.SECRET_KEY_PLACEHOLDER;
|
||||
import static com.alibaba.nacos.spring.context.annotation.config.EnableNacosConfig.SERVER_ADDR_PLACEHOLDER;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.springframework.mock.env.MockEnvironment;
|
||||
|
||||
/**
|
||||
* {@link EnableNacosConfig} Test
|
||||
*
|
||||
|
|
|
@ -16,12 +16,14 @@
|
|||
*/
|
||||
package com.alibaba.nacos.spring.context.annotation.config;
|
||||
|
||||
import static com.alibaba.nacos.spring.util.NacosBeanUtils.CONFIG_GLOBAL_NACOS_PROPERTIES_BEAN_NAME;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
import com.alibaba.nacos.api.annotation.NacosProperties;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
|
@ -29,7 +31,8 @@ import org.springframework.stereotype.Component;
|
|||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
import static com.alibaba.nacos.spring.util.NacosBeanUtils.CONFIG_GLOBAL_NACOS_PROPERTIES_BEAN_NAME;
|
||||
import com.alibaba.nacos.api.annotation.NacosProperties;
|
||||
import com.alibaba.nacos.spring.util.NacosUtils;
|
||||
|
||||
/**
|
||||
* {@link NacosConfigBeanDefinitionRegistrar} Test
|
||||
|
@ -45,7 +48,6 @@ public class NacosConfigBeanDefinitionRegistrarTest {
|
|||
|
||||
@Autowired
|
||||
private BeanFactory beanFactory;
|
||||
|
||||
@Autowired
|
||||
@Qualifier(CONFIG_GLOBAL_NACOS_PROPERTIES_BEAN_NAME)
|
||||
private Properties properties;
|
||||
|
|
|
@ -16,26 +16,17 @@
|
|||
*/
|
||||
package com.alibaba.nacos.spring.context.annotation.config;
|
||||
|
||||
import static com.alibaba.nacos.api.common.Constants.DEFAULT_GROUP;
|
||||
import static com.alibaba.nacos.spring.test.MockNacosServiceFactory.DATA_ID;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNull;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
|
||||
import com.alibaba.nacos.api.annotation.NacosInjected;
|
||||
import com.alibaba.nacos.api.annotation.NacosProperties;
|
||||
import com.alibaba.nacos.api.config.ConfigService;
|
||||
import com.alibaba.nacos.api.config.annotation.NacosConfigListener;
|
||||
import com.alibaba.nacos.api.config.listener.AbstractListener;
|
||||
import com.alibaba.nacos.api.exception.NacosException;
|
||||
import com.alibaba.nacos.spring.beans.factory.annotation.AnnotationNacosInjectedBeanPostProcessor;
|
||||
import com.alibaba.nacos.spring.beans.factory.annotation.ConfigServiceBeanBuilder;
|
||||
import com.alibaba.nacos.spring.context.annotation.EnableNacos;
|
||||
import com.alibaba.nacos.spring.convert.converter.config.UserNacosConfigConverter;
|
||||
import com.alibaba.nacos.spring.factory.ApplicationContextHolder;
|
||||
import com.alibaba.nacos.spring.test.AbstractNacosHttpServerTestExecutionListener;
|
||||
import com.alibaba.nacos.spring.test.Listeners;
|
||||
import com.alibaba.nacos.spring.test.TestConfiguration;
|
||||
import com.alibaba.nacos.spring.test.User;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
|
@ -45,10 +36,21 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
|||
import org.springframework.test.context.support.DependencyInjectionTestExecutionListener;
|
||||
import org.springframework.test.context.support.DirtiesContextTestExecutionListener;
|
||||
|
||||
import static com.alibaba.nacos.api.common.Constants.DEFAULT_GROUP;
|
||||
import static com.alibaba.nacos.spring.test.MockNacosServiceFactory.DATA_ID;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import com.alibaba.nacos.api.annotation.NacosInjected;
|
||||
import com.alibaba.nacos.api.annotation.NacosProperties;
|
||||
import com.alibaba.nacos.api.config.ConfigService;
|
||||
import com.alibaba.nacos.api.config.annotation.NacosConfigListener;
|
||||
import com.alibaba.nacos.api.config.listener.AbstractListener;
|
||||
import com.alibaba.nacos.api.exception.NacosException;
|
||||
import com.alibaba.nacos.spring.beans.factory.annotation.AnnotationNacosInjectedBeanPostProcessor;
|
||||
import com.alibaba.nacos.spring.beans.factory.annotation.ConfigServiceBeanBuilder;
|
||||
import com.alibaba.nacos.spring.convert.converter.config.UserNacosConfigConverter;
|
||||
import com.alibaba.nacos.spring.factory.ApplicationContextHolder;
|
||||
import com.alibaba.nacos.spring.test.AbstractNacosHttpServerTestExecutionListener;
|
||||
import com.alibaba.nacos.spring.test.Listeners;
|
||||
import com.alibaba.nacos.spring.test.TestConfiguration;
|
||||
import com.alibaba.nacos.spring.test.User;
|
||||
import com.alibaba.nacos.spring.util.NacosUtils;
|
||||
|
||||
/**
|
||||
* {@link NacosConfigListenerMethodProcessor} Test
|
||||
|
@ -64,10 +66,16 @@ import static org.junit.Assert.assertNull;
|
|||
@TestExecutionListeners({ DependencyInjectionTestExecutionListener.class,
|
||||
DirtiesContextTestExecutionListener.class,
|
||||
NacosConfigListenerMethodProcessorTest.class })
|
||||
@EnableNacos(globalProperties = @NacosProperties(serverAddr = "${server.addr}"))
|
||||
@EnableNacosConfig(globalProperties = @NacosProperties(serverAddr = "${server.addr}"))
|
||||
public class NacosConfigListenerMethodProcessorTest
|
||||
extends AbstractNacosHttpServerTestExecutionListener {
|
||||
|
||||
@Autowired
|
||||
private Listeners listeners;
|
||||
@NacosInjected
|
||||
private ConfigService configService;
|
||||
private volatile boolean received = false;
|
||||
|
||||
@Bean(name = ApplicationContextHolder.BEAN_NAME)
|
||||
public ApplicationContextHolder applicationContextHolder(
|
||||
ApplicationContext applicationContext) {
|
||||
|
@ -81,14 +89,6 @@ public class NacosConfigListenerMethodProcessorTest
|
|||
return "server.addr";
|
||||
}
|
||||
|
||||
@Autowired
|
||||
private Listeners listeners;
|
||||
|
||||
@NacosInjected
|
||||
private ConfigService configService;
|
||||
|
||||
private volatile boolean received = false;
|
||||
|
||||
@PostConstruct
|
||||
public void initListener() throws NacosException {
|
||||
configService.addListener(DATA_ID, DEFAULT_GROUP, new AbstractListener() {
|
||||
|
|
|
@ -14,22 +14,18 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.spring.context.annotation.config;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import com.alibaba.nacos.api.annotation.NacosInjected;
|
||||
import com.alibaba.nacos.api.annotation.NacosProperties;
|
||||
import com.alibaba.nacos.api.config.ConfigService;
|
||||
import com.alibaba.nacos.api.config.annotation.NacosConfigListener;
|
||||
import com.alibaba.nacos.api.exception.NacosException;
|
||||
import com.alibaba.nacos.spring.test.AbstractNacosHttpServerTestExecutionListener;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.TestExecutionListeners;
|
||||
|
@ -37,7 +33,17 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
|||
import org.springframework.test.context.support.DependencyInjectionTestExecutionListener;
|
||||
import org.springframework.test.context.support.DirtiesContextTestExecutionListener;
|
||||
|
||||
import com.alibaba.nacos.api.annotation.NacosInjected;
|
||||
import com.alibaba.nacos.api.annotation.NacosProperties;
|
||||
import com.alibaba.nacos.api.config.ConfigService;
|
||||
import com.alibaba.nacos.api.config.annotation.NacosConfigListener;
|
||||
import com.alibaba.nacos.api.exception.NacosException;
|
||||
import com.alibaba.nacos.spring.test.AbstractNacosHttpServerTestExecutionListener;
|
||||
import com.alibaba.nacos.spring.util.NacosUtils;
|
||||
|
||||
/**
|
||||
* NacosConfigListenerTest.
|
||||
*
|
||||
* @author <a href="mailto:liaochunyhm@live.com">liaochuntao</a>
|
||||
* @since
|
||||
*/
|
||||
|
@ -49,18 +55,17 @@ import org.springframework.test.context.support.DirtiesContextTestExecutionListe
|
|||
public class NacosConfigListenerTest
|
||||
extends AbstractNacosHttpServerTestExecutionListener {
|
||||
|
||||
@Override
|
||||
protected String getServerAddressPropertyName() {
|
||||
return "server.addr";
|
||||
}
|
||||
|
||||
@NacosInjected
|
||||
private ConfigService configService;
|
||||
|
||||
private static volatile String content = "";
|
||||
private static volatile boolean receiveOne = false;
|
||||
private static volatile boolean receiveTwo = false;
|
||||
private static volatile boolean receiveThree = false;
|
||||
@NacosInjected
|
||||
private ConfigService configService;
|
||||
|
||||
@Override
|
||||
protected String getServerAddressPropertyName() {
|
||||
return "server.addr";
|
||||
}
|
||||
|
||||
@NacosConfigListener(dataId = "com.alibaba.nacos.example.properties", timeout = 2000L)
|
||||
public void onMessage(String config) {
|
||||
|
@ -97,17 +102,10 @@ public class NacosConfigListenerTest
|
|||
"DEFAULT_GROUP", "" + currentTimeMillis);
|
||||
result = configService.publishConfig("convert_map.properties",
|
||||
"DEFAULT_GROUP", "this.is.test=true");
|
||||
result = configService.publishConfig("convert_map.yaml",
|
||||
"DEFAULT_GROUP", "routingMap:\n" +
|
||||
" - aaa\n" +
|
||||
" - bbb\n" +
|
||||
" - ccc\n" +
|
||||
" - ddd\n" +
|
||||
" - eee\n" +
|
||||
"endPointMap:\n" +
|
||||
" - fff\n" +
|
||||
"testMap:\n" +
|
||||
" abc: def1");
|
||||
result = configService.publishConfig("convert_map.yaml", "DEFAULT_GROUP",
|
||||
"routingMap:\n" + " - aaa\n" + " - bbb\n" + " - ccc\n"
|
||||
+ " - ddd\n" + " - eee\n" + "endPointMap:\n" + " - fff\n"
|
||||
+ "testMap:\n" + " abc: def1");
|
||||
}
|
||||
catch (NacosException e) {
|
||||
e.printStackTrace();
|
||||
|
|
|
@ -16,12 +16,15 @@
|
|||
*/
|
||||
package com.alibaba.nacos.spring.context.annotation.config;
|
||||
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Assert;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.springframework.mock.env.MockEnvironment;
|
||||
|
||||
import com.alibaba.nacos.api.annotation.NacosProperties;
|
||||
import com.alibaba.nacos.spring.context.annotation.EnableNacos;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.mock.env.MockEnvironment;
|
||||
import com.alibaba.nacos.spring.util.NacosUtils;
|
||||
|
||||
/**
|
||||
* {@link NacosProperties} Test
|
||||
|
@ -32,14 +35,6 @@ import org.springframework.mock.env.MockEnvironment;
|
|||
*/
|
||||
public class NacosPropertiesTest {
|
||||
|
||||
@EnableNacos(globalProperties = @NacosProperties)
|
||||
private static class NacosPropertiesDefaultValues {
|
||||
}
|
||||
|
||||
@EnableNacos(globalProperties = @NacosProperties(endpoint = "e", namespace = "n", accessKey = "a", secretKey = "s", serverAddr = "127.0.0.1", contextPath = "/", clusterName = "c", encode = "GBK"))
|
||||
private static class NacosPropertiesValues {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConstants() {
|
||||
Assert.assertEquals("nacos.", NacosProperties.PREFIX);
|
||||
|
@ -141,4 +136,12 @@ public class NacosPropertiesTest {
|
|||
return nacosProperties;
|
||||
}
|
||||
|
||||
@EnableNacos(globalProperties = @NacosProperties)
|
||||
private static class NacosPropertiesDefaultValues {
|
||||
}
|
||||
|
||||
@EnableNacos(globalProperties = @NacosProperties(endpoint = "e", namespace = "n", accessKey = "a", secretKey = "s", serverAddr = "127.0.0.1", contextPath = "/", clusterName = "c", encode = "GBK"))
|
||||
private static class NacosPropertiesValues {
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,104 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.alibaba.nacos.spring.context.annotation.config;
|
||||
|
||||
import static com.alibaba.nacos.api.common.Constants.DEFAULT_GROUP;
|
||||
import static com.alibaba.nacos.embedded.web.server.NacosConfigHttpHandler.CONTENT_PARAM_NAME;
|
||||
import static com.alibaba.nacos.embedded.web.server.NacosConfigHttpHandler.DATA_ID_PARAM_NAME;
|
||||
import static com.alibaba.nacos.embedded.web.server.NacosConfigHttpHandler.GROUP_ID_PARAM_NAME;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Assert;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.TestExecutionListeners;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.test.context.support.DependencyInjectionTestExecutionListener;
|
||||
import org.springframework.test.context.support.DirtiesContextTestExecutionListener;
|
||||
|
||||
import com.alibaba.nacos.api.annotation.NacosInjected;
|
||||
import com.alibaba.nacos.api.annotation.NacosProperties;
|
||||
import com.alibaba.nacos.api.config.ConfigService;
|
||||
import com.alibaba.nacos.api.exception.NacosException;
|
||||
import com.alibaba.nacos.embedded.web.server.EmbeddedNacosHttpServer;
|
||||
import com.alibaba.nacos.spring.test.AbstractNacosHttpServerTestExecutionListener;
|
||||
import com.alibaba.nacos.spring.test.YamlBean;
|
||||
import com.alibaba.nacos.spring.util.NacosUtils;
|
||||
|
||||
/**
|
||||
* @author mai.jh
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration(classes = { NacosPropertySourceBeanTest.class })
|
||||
@TestExecutionListeners({ DependencyInjectionTestExecutionListener.class,
|
||||
DirtiesContextTestExecutionListener.class, NacosPropertySourceBeanTest.class })
|
||||
@NacosPropertySources(value = { @NacosPropertySource(dataId = YamlBean.DATA_ID_YAML
|
||||
+ ".yml", autoRefreshed = true) })
|
||||
@EnableNacosConfig(globalProperties = @NacosProperties(serverAddr = "${server.addr}"))
|
||||
@Component
|
||||
public class NacosPropertySourceBeanTest
|
||||
extends AbstractNacosHttpServerTestExecutionListener {
|
||||
|
||||
private String yaml = "student:\n" + " name: lct-1\n" + " num: 12\n"
|
||||
+ " testApp: \n" + " name: test";
|
||||
|
||||
private String except = "YamlBean{student=Student{name='lct-1', num='12', testApp=TestApp{name='test'}}}";
|
||||
@NacosInjected
|
||||
private ConfigService configService;
|
||||
@Autowired
|
||||
private YamlBean yamlBean;
|
||||
|
||||
@Override
|
||||
public void init(EmbeddedNacosHttpServer httpServer) {
|
||||
Map<String, String> config = new HashMap<String, String>(1);
|
||||
config.put(DATA_ID_PARAM_NAME, YamlBean.DATA_ID_YAML + ".yml");
|
||||
config.put(GROUP_ID_PARAM_NAME, DEFAULT_GROUP);
|
||||
config.put(CONTENT_PARAM_NAME, yaml);
|
||||
|
||||
httpServer.initConfig(config);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public YamlBean yamlBean() {
|
||||
return new YamlBean();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getServerAddressPropertyName() {
|
||||
return "server.addr";
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValue() throws NacosException, InterruptedException {
|
||||
|
||||
configService.publishConfig(YamlBean.DATA_ID_YAML + ".yml", DEFAULT_GROUP, yaml);
|
||||
|
||||
Thread.sleep(2000);
|
||||
|
||||
Assert.assertEquals(except, yamlBean.toString());
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
*
|
||||
* * Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* * contributor license agreements. See the NOTICE file distributed with
|
||||
* * this work for additional information regarding copyright ownership.
|
||||
* * The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* * (the "License"); you may not use this file except in compliance with
|
||||
* * the License. You may obtain a copy of the License at
|
||||
* *
|
||||
* * http://www.apache.org/licenses/LICENSE-2.0
|
||||
* *
|
||||
* * Unless required by applicable law or agreed to in writing, software
|
||||
* * distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* * See the License for the specific language governing permissions and
|
||||
* * limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.spring.context.annotation.config;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.springframework.core.env.MapPropertySource;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
/**
|
||||
* {@link NacosPropertySourceBuilder} Test
|
||||
* @author SuperZ1999
|
||||
* @date 2023/9/28
|
||||
*/
|
||||
public class NacosPropertySourceBuilderTest {
|
||||
@Test
|
||||
public void test() {
|
||||
MapPropertySource propertySource = new MapPropertySource("test", new HashMap<>());
|
||||
Assert.assertNotNull(propertySource);
|
||||
}
|
||||
}
|
|
@ -16,22 +16,19 @@
|
|||
*/
|
||||
package com.alibaba.nacos.spring.context.annotation.config;
|
||||
|
||||
import static com.alibaba.nacos.api.common.Constants.DEFAULT_GROUP;
|
||||
import static com.alibaba.nacos.embedded.web.server.NacosConfigHttpHandler.CONTENT_PARAM_NAME;
|
||||
import static com.alibaba.nacos.embedded.web.server.NacosConfigHttpHandler.DATA_ID_PARAM_NAME;
|
||||
import static com.alibaba.nacos.embedded.web.server.NacosConfigHttpHandler.GROUP_ID_PARAM_NAME;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import com.alibaba.nacos.api.annotation.NacosInjected;
|
||||
import com.alibaba.nacos.api.annotation.NacosProperties;
|
||||
import com.alibaba.nacos.api.config.ConfigService;
|
||||
import com.alibaba.nacos.api.config.ConfigType;
|
||||
import com.alibaba.nacos.api.config.annotation.NacosValue;
|
||||
import com.alibaba.nacos.api.exception.NacosException;
|
||||
import com.alibaba.nacos.embedded.web.server.EmbeddedNacosHttpServer;
|
||||
import com.alibaba.nacos.spring.context.annotation.EnableNacos;
|
||||
import com.alibaba.nacos.spring.test.AbstractNacosHttpServerTestExecutionListener;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Assert;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
|
@ -42,10 +39,15 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
|||
import org.springframework.test.context.support.DependencyInjectionTestExecutionListener;
|
||||
import org.springframework.test.context.support.DirtiesContextTestExecutionListener;
|
||||
|
||||
import static com.alibaba.nacos.api.common.Constants.DEFAULT_GROUP;
|
||||
import static com.alibaba.nacos.embedded.web.server.NacosConfigHttpHandler.CONTENT_PARAM_NAME;
|
||||
import static com.alibaba.nacos.embedded.web.server.NacosConfigHttpHandler.DATA_ID_PARAM_NAME;
|
||||
import static com.alibaba.nacos.embedded.web.server.NacosConfigHttpHandler.GROUP_ID_PARAM_NAME;
|
||||
import com.alibaba.nacos.api.annotation.NacosInjected;
|
||||
import com.alibaba.nacos.api.annotation.NacosProperties;
|
||||
import com.alibaba.nacos.api.config.ConfigService;
|
||||
import com.alibaba.nacos.api.config.ConfigType;
|
||||
import com.alibaba.nacos.api.config.annotation.NacosValue;
|
||||
import com.alibaba.nacos.api.exception.NacosException;
|
||||
import com.alibaba.nacos.embedded.web.server.EmbeddedNacosHttpServer;
|
||||
import com.alibaba.nacos.spring.test.AbstractNacosHttpServerTestExecutionListener;
|
||||
import com.alibaba.nacos.spring.util.NacosUtils;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:liaochunyhm@live.com">liaochuntao</a>
|
||||
|
@ -56,26 +58,28 @@ import static com.alibaba.nacos.embedded.web.server.NacosConfigHttpHandler.GROUP
|
|||
@TestExecutionListeners({ DependencyInjectionTestExecutionListener.class,
|
||||
DirtiesContextTestExecutionListener.class, NacosPropertySourceJsonTest.class })
|
||||
@NacosPropertySource(dataId = NacosPropertySourceJsonTest.DATA_ID, autoRefreshed = true, type = ConfigType.JSON)
|
||||
@EnableNacos(globalProperties = @NacosProperties(serverAddr = "${server.addr}"))
|
||||
@EnableNacosConfig(globalProperties = @NacosProperties(serverAddr = "${server.addr}"))
|
||||
@Component
|
||||
public class NacosPropertySourceJsonTest
|
||||
extends AbstractNacosHttpServerTestExecutionListener {
|
||||
|
||||
public static final String DATA_ID = "data_json";
|
||||
private String configStr = "{\n" + " \"people\":{\n"
|
||||
+ " \"a\":\"liaochuntao\",\n" + " \"b\":\"this is test\"\n"
|
||||
+ " }\n" + "}";
|
||||
private String newConfigStr = "{\n" + " \"people\":{\n"
|
||||
+ " \"a\":\"liaochuntao\",\n"
|
||||
+ " \"b\":\"refresh this is test\"\n" + " }\n" + "}";
|
||||
@NacosInjected
|
||||
private ConfigService configService;
|
||||
@Autowired
|
||||
private App app;
|
||||
|
||||
@Override
|
||||
protected String getServerAddressPropertyName() {
|
||||
return "server.addr";
|
||||
}
|
||||
|
||||
private String configStr = "{\n" + " \"people\":{\n"
|
||||
+ " \"a\":\"liaochuntao\",\n" + " \"b\":\"this is test\"\n"
|
||||
+ " }\n" + "}";
|
||||
|
||||
private String newConfigStr = "{\n" + " \"people\":{\n"
|
||||
+ " \"a\":\"liaochuntao\",\n"
|
||||
+ " \"b\":\"refresh this is test\"\n" + " }\n" + "}";
|
||||
|
||||
@Override
|
||||
public void init(EmbeddedNacosHttpServer httpServer) {
|
||||
Map<String, String> config = new HashMap<String, String>(1);
|
||||
|
@ -86,8 +90,24 @@ public class NacosPropertySourceJsonTest
|
|||
httpServer.initConfig(config);
|
||||
}
|
||||
|
||||
@NacosInjected
|
||||
private ConfigService configService;
|
||||
@Bean
|
||||
public App app() {
|
||||
return new App();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValue() throws NacosException, InterruptedException {
|
||||
|
||||
Assert.assertEquals("liaochuntao", app.a);
|
||||
Assert.assertEquals("this is test", app.b);
|
||||
|
||||
configService.publishConfig(DATA_ID, DEFAULT_GROUP, newConfigStr);
|
||||
|
||||
Thread.sleep(2000);
|
||||
|
||||
Assert.assertEquals("liaochuntao", app.a);
|
||||
Assert.assertEquals("refresh this is test", app.b);
|
||||
}
|
||||
|
||||
public static class App {
|
||||
|
||||
|
@ -113,26 +133,4 @@ public class NacosPropertySourceJsonTest
|
|||
}
|
||||
}
|
||||
|
||||
@Bean
|
||||
public App app() {
|
||||
return new App();
|
||||
}
|
||||
|
||||
@Autowired
|
||||
private App app;
|
||||
|
||||
@Test
|
||||
public void testValue() throws NacosException, InterruptedException {
|
||||
|
||||
Assert.assertEquals("liaochuntao", app.a);
|
||||
Assert.assertEquals("this is test", app.b);
|
||||
|
||||
configService.publishConfig(DATA_ID, DEFAULT_GROUP, newConfigStr);
|
||||
|
||||
Thread.sleep(2000);
|
||||
|
||||
Assert.assertEquals("liaochuntao", app.a);
|
||||
Assert.assertEquals("refresh this is test", app.b);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -16,27 +16,23 @@
|
|||
*/
|
||||
package com.alibaba.nacos.spring.context.annotation.config;
|
||||
|
||||
import static com.alibaba.nacos.api.common.Constants.DEFAULT_GROUP;
|
||||
import static com.alibaba.nacos.embedded.web.server.NacosConfigHttpHandler.CONTENT_PARAM_NAME;
|
||||
import static com.alibaba.nacos.embedded.web.server.NacosConfigHttpHandler.DATA_ID_PARAM_NAME;
|
||||
import static com.alibaba.nacos.embedded.web.server.NacosConfigHttpHandler.GROUP_ID_PARAM_NAME;
|
||||
import static com.alibaba.nacos.spring.test.MockNacosServiceFactory.DATA_ID;
|
||||
import static com.alibaba.nacos.spring.test.TestConfiguration.CONFIG_SERVICE_BEAN_NAME;
|
||||
import static org.springframework.core.env.StandardEnvironment.SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME;
|
||||
import static org.springframework.core.env.StandardEnvironment.SYSTEM_PROPERTIES_PROPERTY_SOURCE_NAME;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import com.alibaba.nacos.api.annotation.NacosInjected;
|
||||
import com.alibaba.nacos.api.annotation.NacosProperties;
|
||||
import com.alibaba.nacos.api.config.ConfigService;
|
||||
import com.alibaba.nacos.api.exception.NacosException;
|
||||
import com.alibaba.nacos.embedded.web.server.EmbeddedNacosHttpServer;
|
||||
import com.alibaba.nacos.spring.beans.factory.annotation.AnnotationNacosInjectedBeanPostProcessor;
|
||||
import com.alibaba.nacos.spring.beans.factory.annotation.ConfigServiceBeanBuilder;
|
||||
import com.alibaba.nacos.spring.context.annotation.EnableNacos;
|
||||
import com.alibaba.nacos.spring.core.env.AnnotationNacosPropertySourceBuilder;
|
||||
import com.alibaba.nacos.spring.core.env.NacosPropertySourcePostProcessor;
|
||||
import com.alibaba.nacos.spring.factory.ApplicationContextHolder;
|
||||
import com.alibaba.nacos.spring.test.AbstractNacosHttpServerTestExecutionListener;
|
||||
import com.alibaba.nacos.spring.test.TestApplicationHolder;
|
||||
import com.alibaba.nacos.spring.test.TestConfiguration;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Assert;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
|
@ -49,14 +45,20 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
|||
import org.springframework.test.context.support.DependencyInjectionTestExecutionListener;
|
||||
import org.springframework.test.context.support.DirtiesContextTestExecutionListener;
|
||||
|
||||
import static com.alibaba.nacos.api.common.Constants.DEFAULT_GROUP;
|
||||
import static com.alibaba.nacos.embedded.web.server.NacosConfigHttpHandler.CONTENT_PARAM_NAME;
|
||||
import static com.alibaba.nacos.embedded.web.server.NacosConfigHttpHandler.DATA_ID_PARAM_NAME;
|
||||
import static com.alibaba.nacos.embedded.web.server.NacosConfigHttpHandler.GROUP_ID_PARAM_NAME;
|
||||
import static com.alibaba.nacos.spring.test.MockNacosServiceFactory.DATA_ID;
|
||||
import static com.alibaba.nacos.spring.test.TestConfiguration.CONFIG_SERVICE_BEAN_NAME;
|
||||
import static org.springframework.core.env.StandardEnvironment.SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME;
|
||||
import static org.springframework.core.env.StandardEnvironment.SYSTEM_PROPERTIES_PROPERTY_SOURCE_NAME;
|
||||
import com.alibaba.nacos.api.annotation.NacosInjected;
|
||||
import com.alibaba.nacos.api.annotation.NacosProperties;
|
||||
import com.alibaba.nacos.api.config.ConfigService;
|
||||
import com.alibaba.nacos.api.exception.NacosException;
|
||||
import com.alibaba.nacos.embedded.web.server.EmbeddedNacosHttpServer;
|
||||
import com.alibaba.nacos.spring.beans.factory.annotation.AnnotationNacosInjectedBeanPostProcessor;
|
||||
import com.alibaba.nacos.spring.beans.factory.annotation.ConfigServiceBeanBuilder;
|
||||
import com.alibaba.nacos.spring.core.env.AnnotationNacosPropertySourceBuilder;
|
||||
import com.alibaba.nacos.spring.core.env.NacosPropertySourcePostProcessor;
|
||||
import com.alibaba.nacos.spring.factory.ApplicationContextHolder;
|
||||
import com.alibaba.nacos.spring.test.AbstractNacosHttpServerTestExecutionListener;
|
||||
import com.alibaba.nacos.spring.test.TestApplicationHolder;
|
||||
import com.alibaba.nacos.spring.test.TestConfiguration;
|
||||
import com.alibaba.nacos.spring.util.NacosUtils;
|
||||
|
||||
/**
|
||||
* {@link NacosPropertySourcePostProcessor} Test
|
||||
|
@ -70,31 +72,18 @@ import static org.springframework.core.env.StandardEnvironment.SYSTEM_PROPERTIES
|
|||
@TestExecutionListeners({ DependencyInjectionTestExecutionListener.class,
|
||||
DirtiesContextTestExecutionListener.class,
|
||||
NacosPropertySourcePostProcessorTest.class })
|
||||
@EnableNacos(globalProperties = @NacosProperties(serverAddr = "${server.addr}"))
|
||||
@EnableNacosConfig(globalProperties = @NacosProperties(serverAddr = "${server.addr}"))
|
||||
public class NacosPropertySourcePostProcessorTest
|
||||
extends AbstractNacosHttpServerTestExecutionListener {
|
||||
|
||||
private static final String TEST_PROPERTY_NAME = "user.name";
|
||||
|
||||
private static final String TEST_PROPERTY_VALUE = "mercyblitz@"
|
||||
+ System.currentTimeMillis();
|
||||
|
||||
private static final String TEST_CONTENT = TEST_PROPERTY_NAME + "="
|
||||
+ TEST_PROPERTY_VALUE + System.getProperty("line.separator")
|
||||
+ "PATH = /My/Path";
|
||||
|
||||
@NacosPropertySources({
|
||||
@NacosPropertySource(name = "second", dataId = DATA_ID, first = true, before = SYSTEM_PROPERTIES_PROPERTY_SOURCE_NAME, after = SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME),
|
||||
@NacosPropertySource(name = "first", dataId = DATA_ID, first = true, before = SYSTEM_PROPERTIES_PROPERTY_SOURCE_NAME, after = SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME) })
|
||||
@NacosPropertySource(dataId = DATA_ID, before = SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME, after = SYSTEM_PROPERTIES_PROPERTY_SOURCE_NAME)
|
||||
private static class FirstOrderNacosPropertySource {
|
||||
|
||||
}
|
||||
|
||||
@NacosPropertySource(dataId = DATA_ID, before = SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME, after = SYSTEM_PROPERTIES_PROPERTY_SOURCE_NAME)
|
||||
private static class RelativeOrderNacosPropertySource {
|
||||
|
||||
}
|
||||
@NacosInjected
|
||||
private ConfigService configService;
|
||||
|
||||
@Override
|
||||
public void init(EmbeddedNacosHttpServer httpServer) {
|
||||
|
@ -118,9 +107,6 @@ public class NacosPropertySourcePostProcessorTest
|
|||
return applicationContextHolder;
|
||||
}
|
||||
|
||||
@NacosInjected
|
||||
private ConfigService configService;
|
||||
|
||||
@Test
|
||||
public void testFirstOrder() throws NacosException {
|
||||
|
||||
|
@ -200,4 +186,17 @@ public class NacosPropertySourcePostProcessorTest
|
|||
TestApplicationHolder.class);
|
||||
return context;
|
||||
}
|
||||
|
||||
@NacosPropertySources({
|
||||
@NacosPropertySource(name = "second", dataId = DATA_ID, first = true, before = SYSTEM_PROPERTIES_PROPERTY_SOURCE_NAME, after = SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME),
|
||||
@NacosPropertySource(name = "first", dataId = DATA_ID, first = true, before = SYSTEM_PROPERTIES_PROPERTY_SOURCE_NAME, after = SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME) })
|
||||
@NacosPropertySource(dataId = DATA_ID, before = SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME, after = SYSTEM_PROPERTIES_PROPERTY_SOURCE_NAME)
|
||||
private static class FirstOrderNacosPropertySource {
|
||||
|
||||
}
|
||||
|
||||
@NacosPropertySource(dataId = DATA_ID, before = SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME, after = SYSTEM_PROPERTIES_PROPERTY_SOURCE_NAME)
|
||||
private static class RelativeOrderNacosPropertySource {
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,23 +16,20 @@
|
|||
*/
|
||||
package com.alibaba.nacos.spring.context.annotation.config;
|
||||
|
||||
import static com.alibaba.nacos.embedded.web.server.NacosConfigHttpHandler.CONTENT_PARAM_NAME;
|
||||
import static com.alibaba.nacos.embedded.web.server.NacosConfigHttpHandler.DATA_ID_PARAM_NAME;
|
||||
import static com.alibaba.nacos.embedded.web.server.NacosConfigHttpHandler.GROUP_ID_PARAM_NAME;
|
||||
import static com.alibaba.nacos.spring.context.annotation.config.NacosPropertySourceReadFromEnvironmentTest.ENV_GROUP_ID;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import com.alibaba.nacos.api.annotation.NacosInjected;
|
||||
import com.alibaba.nacos.api.annotation.NacosProperties;
|
||||
import com.alibaba.nacos.api.config.ConfigService;
|
||||
import com.alibaba.nacos.api.config.annotation.NacosValue;
|
||||
import com.alibaba.nacos.api.exception.NacosException;
|
||||
import com.alibaba.nacos.embedded.web.server.EmbeddedNacosHttpServer;
|
||||
import com.alibaba.nacos.spring.context.annotation.EnableNacos;
|
||||
import com.alibaba.nacos.spring.test.AbstractNacosHttpServerTestExecutionListener;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Assert;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
|
@ -44,10 +41,14 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
|||
import org.springframework.test.context.support.DependencyInjectionTestExecutionListener;
|
||||
import org.springframework.test.context.support.DirtiesContextTestExecutionListener;
|
||||
|
||||
import static com.alibaba.nacos.embedded.web.server.NacosConfigHttpHandler.CONTENT_PARAM_NAME;
|
||||
import static com.alibaba.nacos.embedded.web.server.NacosConfigHttpHandler.DATA_ID_PARAM_NAME;
|
||||
import static com.alibaba.nacos.embedded.web.server.NacosConfigHttpHandler.GROUP_ID_PARAM_NAME;
|
||||
import static com.alibaba.nacos.spring.context.annotation.config.NacosPropertySourceReadFromEnvironmentTest.ENV_GROUP_ID;
|
||||
import com.alibaba.nacos.api.annotation.NacosInjected;
|
||||
import com.alibaba.nacos.api.annotation.NacosProperties;
|
||||
import com.alibaba.nacos.api.config.ConfigService;
|
||||
import com.alibaba.nacos.api.config.annotation.NacosValue;
|
||||
import com.alibaba.nacos.api.exception.NacosException;
|
||||
import com.alibaba.nacos.embedded.web.server.EmbeddedNacosHttpServer;
|
||||
import com.alibaba.nacos.spring.test.AbstractNacosHttpServerTestExecutionListener;
|
||||
import com.alibaba.nacos.spring.util.NacosUtils;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:liaochunyhm@live.com">liaochuntao</a>
|
||||
|
@ -60,30 +61,32 @@ import static com.alibaba.nacos.spring.context.annotation.config.NacosPropertySo
|
|||
DirtiesContextTestExecutionListener.class,
|
||||
NacosPropertySourceReadFromEnvironmentTest.class })
|
||||
@NacosPropertySource(dataId = NacosPropertySourceReadFromEnvironmentTest.ENV_DATA_ID, groupId = ENV_GROUP_ID, autoRefreshed = true)
|
||||
@EnableNacos(globalProperties = @NacosProperties(serverAddr = "${server.addr}", enableRemoteSyncConfig = "true", maxRetry = "5", configRetryTime = "2600", configLongPollTimeout = "26000"))
|
||||
@EnableNacosConfig(globalProperties = @NacosProperties(serverAddr = "${server.addr}", enableRemoteSyncConfig = "true", maxRetry = "5", configRetryTime = "2600", configLongPollTimeout = "26000"))
|
||||
@Component
|
||||
public class NacosPropertySourceReadFromEnvironmentTest
|
||||
extends AbstractNacosHttpServerTestExecutionListener {
|
||||
|
||||
private static final String LINE_SEPARATOR = System.getProperty("line.separator");
|
||||
|
||||
public static final String ENV_DATA_ID = "${data-id}";
|
||||
|
||||
public static final String ENV_GROUP_ID = "${group-id:nacos_env_test}";
|
||||
|
||||
public static final String DATA_ID = "app.properties";
|
||||
|
||||
private static final String LINE_SEPARATOR = System.getProperty("line.separator");
|
||||
private static final String APP_NAME = "Nacos-Spring";
|
||||
|
||||
private static final String ANOTHER_APP_NAME = "Nacos-Spring-1";
|
||||
|
||||
private static final int VALUE_1 = 1;
|
||||
|
||||
private static final int VALUE_2 = 2;
|
||||
|
||||
private static final int VALUE_3 = 3;
|
||||
|
||||
private static final int VALUE_4 = 4;
|
||||
@NacosInjected
|
||||
private ConfigService configService;
|
||||
@Autowired
|
||||
private App app;
|
||||
@Autowired
|
||||
private ConfigurableEnvironment environment;
|
||||
|
||||
@BeforeClass
|
||||
public static void init() {
|
||||
System.setProperty("data-id", "app.properties");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(EmbeddedNacosHttpServer httpServer) {
|
||||
|
@ -96,16 +99,67 @@ public class NacosPropertySourceReadFromEnvironmentTest
|
|||
httpServer.initConfig(config);
|
||||
}
|
||||
|
||||
@BeforeClass
|
||||
public static void init() {
|
||||
System.setProperty("data-id", "app.properties");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getServerAddressPropertyName() {
|
||||
return "server.addr";
|
||||
}
|
||||
|
||||
@Bean
|
||||
public App app() {
|
||||
return new App();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValue() throws NacosException, InterruptedException {
|
||||
Assert.assertEquals(APP_NAME, app.name);
|
||||
|
||||
Assert.assertEquals(APP_NAME, app.nameWithDefaultValue);
|
||||
|
||||
Assert.assertEquals(APP_NAME, app.nacosNameAutoRefreshed);
|
||||
|
||||
Assert.assertEquals(APP_NAME, app.nacosNameAutoRefreshedWithDefaultValue);
|
||||
|
||||
Assert.assertEquals(APP_NAME, app.nacosNameNotAutoRefreshed);
|
||||
|
||||
Assert.assertEquals(APP_NAME, environment.getProperty("app.name"));
|
||||
|
||||
Assert.assertEquals(VALUE_1, app.nacosFieldIntValue);
|
||||
|
||||
Assert.assertEquals(VALUE_2, app.nacosMethodIntValue);
|
||||
|
||||
Assert.assertEquals(VALUE_1, app.nacosFieldIntValueAutoRefreshed);
|
||||
|
||||
Assert.assertEquals(VALUE_2, app.nacosMethodIntValueAutoRefreshed);
|
||||
|
||||
configService.publishConfig(DATA_ID, "nacos_env_test",
|
||||
"app.name=" + ANOTHER_APP_NAME + LINE_SEPARATOR
|
||||
+ "app.nacosFieldIntValueAutoRefreshed=" + VALUE_3
|
||||
+ LINE_SEPARATOR + "app.nacosMethodIntValueAutoRefreshed="
|
||||
+ VALUE_4);
|
||||
|
||||
Thread.sleep(1000);
|
||||
|
||||
Assert.assertEquals(APP_NAME, app.name);
|
||||
|
||||
Assert.assertEquals(APP_NAME, app.nameWithDefaultValue);
|
||||
|
||||
Assert.assertEquals(ANOTHER_APP_NAME, app.nacosNameAutoRefreshed);
|
||||
|
||||
Assert.assertEquals(ANOTHER_APP_NAME, app.nacosNameAutoRefreshedWithDefaultValue);
|
||||
|
||||
Assert.assertEquals(APP_NAME, app.nacosNameNotAutoRefreshed);
|
||||
|
||||
Assert.assertEquals(ANOTHER_APP_NAME, environment.getProperty("app.name"));
|
||||
|
||||
Assert.assertEquals(VALUE_1, app.nacosFieldIntValue);
|
||||
|
||||
Assert.assertEquals(VALUE_2, app.nacosMethodIntValue);
|
||||
|
||||
Assert.assertEquals(VALUE_3, app.nacosFieldIntValueAutoRefreshed);
|
||||
|
||||
Assert.assertEquals(VALUE_4, app.nacosMethodIntValueAutoRefreshed);
|
||||
}
|
||||
|
||||
public static class App {
|
||||
|
||||
@Value("${app.name}")
|
||||
|
@ -130,14 +184,13 @@ public class NacosPropertySourceReadFromEnvironmentTest
|
|||
private int nacosFieldIntValueAutoRefreshed;
|
||||
|
||||
private int nacosMethodIntValue;
|
||||
private int nacosMethodIntValueAutoRefreshed;
|
||||
|
||||
@NacosValue("${app.nacosMethodIntValue:" + VALUE_2 + "}")
|
||||
public void setNacosMethodIntValue(int nacosMethodIntValue) {
|
||||
this.nacosMethodIntValue = nacosMethodIntValue;
|
||||
}
|
||||
|
||||
private int nacosMethodIntValueAutoRefreshed;
|
||||
|
||||
@NacosValue(value = "${app.nacosMethodIntValueAutoRefreshed}", autoRefreshed = true)
|
||||
public void setNacosMethodIntValueAutoRefreshed(
|
||||
int nacosMethodIntValueAutoRefreshed) {
|
||||
|
@ -145,67 +198,4 @@ public class NacosPropertySourceReadFromEnvironmentTest
|
|||
}
|
||||
}
|
||||
|
||||
@Bean
|
||||
public App app() {
|
||||
return new App();
|
||||
}
|
||||
|
||||
@NacosInjected
|
||||
private ConfigService configService;
|
||||
|
||||
@Autowired
|
||||
private App app;
|
||||
|
||||
@Autowired
|
||||
private ConfigurableEnvironment environment;
|
||||
|
||||
@Test
|
||||
public void testValue() throws NacosException, InterruptedException {
|
||||
Assert.assertEquals(APP_NAME, app.name);
|
||||
|
||||
Assert.assertEquals(APP_NAME, app.nameWithDefaultValue);
|
||||
|
||||
Assert.assertEquals(APP_NAME, app.nacosNameAutoRefreshed);
|
||||
|
||||
Assert.assertEquals(APP_NAME, app.nacosNameAutoRefreshedWithDefaultValue);
|
||||
|
||||
Assert.assertEquals(APP_NAME, app.nacosNameNotAutoRefreshed);
|
||||
|
||||
Assert.assertEquals(APP_NAME, environment.getProperty("app.name"));
|
||||
|
||||
Assert.assertEquals(VALUE_1, app.nacosFieldIntValue);
|
||||
|
||||
Assert.assertEquals(VALUE_2, app.nacosMethodIntValue);
|
||||
|
||||
Assert.assertEquals(VALUE_1, app.nacosFieldIntValueAutoRefreshed);
|
||||
|
||||
Assert.assertEquals(VALUE_2, app.nacosMethodIntValueAutoRefreshed);
|
||||
|
||||
configService.publishConfig(DATA_ID, "nacos_env_test", "app.name=" + ANOTHER_APP_NAME
|
||||
+ LINE_SEPARATOR + "app.nacosFieldIntValueAutoRefreshed=" + VALUE_3
|
||||
+ LINE_SEPARATOR + "app.nacosMethodIntValueAutoRefreshed=" + VALUE_4);
|
||||
|
||||
Thread.sleep(1000);
|
||||
|
||||
Assert.assertEquals(APP_NAME, app.name);
|
||||
|
||||
Assert.assertEquals(APP_NAME, app.nameWithDefaultValue);
|
||||
|
||||
Assert.assertEquals(ANOTHER_APP_NAME, app.nacosNameAutoRefreshed);
|
||||
|
||||
Assert.assertEquals(ANOTHER_APP_NAME, app.nacosNameAutoRefreshedWithDefaultValue);
|
||||
|
||||
Assert.assertEquals(APP_NAME, app.nacosNameNotAutoRefreshed);
|
||||
|
||||
Assert.assertEquals(ANOTHER_APP_NAME, environment.getProperty("app.name"));
|
||||
|
||||
Assert.assertEquals(VALUE_1, app.nacosFieldIntValue);
|
||||
|
||||
Assert.assertEquals(VALUE_2, app.nacosMethodIntValue);
|
||||
|
||||
Assert.assertEquals(VALUE_3, app.nacosFieldIntValueAutoRefreshed);
|
||||
|
||||
Assert.assertEquals(VALUE_4, app.nacosMethodIntValueAutoRefreshed);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -16,8 +16,10 @@
|
|||
*/
|
||||
package com.alibaba.nacos.spring.context.annotation.config;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import static com.alibaba.nacos.api.common.Constants.DEFAULT_GROUP;
|
||||
import static com.alibaba.nacos.embedded.web.server.NacosConfigHttpHandler.CONTENT_PARAM_NAME;
|
||||
import static com.alibaba.nacos.embedded.web.server.NacosConfigHttpHandler.DATA_ID_PARAM_NAME;
|
||||
import static com.alibaba.nacos.embedded.web.server.NacosConfigHttpHandler.GROUP_ID_PARAM_NAME;
|
||||
|
||||
import com.alibaba.nacos.api.annotation.NacosInjected;
|
||||
import com.alibaba.nacos.api.annotation.NacosProperties;
|
||||
|
@ -25,12 +27,13 @@ import com.alibaba.nacos.api.config.ConfigService;
|
|||
import com.alibaba.nacos.api.config.annotation.NacosValue;
|
||||
import com.alibaba.nacos.api.exception.NacosException;
|
||||
import com.alibaba.nacos.embedded.web.server.EmbeddedNacosHttpServer;
|
||||
import com.alibaba.nacos.spring.context.annotation.EnableNacos;
|
||||
import com.alibaba.nacos.spring.test.AbstractNacosHttpServerTestExecutionListener;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
|
@ -42,11 +45,6 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
|||
import org.springframework.test.context.support.DependencyInjectionTestExecutionListener;
|
||||
import org.springframework.test.context.support.DirtiesContextTestExecutionListener;
|
||||
|
||||
import static com.alibaba.nacos.api.common.Constants.DEFAULT_GROUP;
|
||||
import static com.alibaba.nacos.embedded.web.server.NacosConfigHttpHandler.CONTENT_PARAM_NAME;
|
||||
import static com.alibaba.nacos.embedded.web.server.NacosConfigHttpHandler.DATA_ID_PARAM_NAME;
|
||||
import static com.alibaba.nacos.embedded.web.server.NacosConfigHttpHandler.GROUP_ID_PARAM_NAME;
|
||||
|
||||
/**
|
||||
* {@link NacosPropertySource} {@link Value} Test
|
||||
*
|
||||
|
@ -61,26 +59,32 @@ import static com.alibaba.nacos.embedded.web.server.NacosConfigHttpHandler.GROUP
|
|||
DirtiesContextTestExecutionListener.class, NacosPropertySourceTest.class })
|
||||
@NacosPropertySources({
|
||||
@NacosPropertySource(dataId = NacosPropertySourceTest.DATA_ID, autoRefreshed = true) })
|
||||
@EnableNacos(globalProperties = @NacosProperties(serverAddr = "${server.addr}", enableRemoteSyncConfig = "true", maxRetry = "5", configRetryTime = "2600", configLongPollTimeout = "26000"))
|
||||
@EnableNacosConfig(globalProperties = @NacosProperties(serverAddr = "${server.addr}", enableRemoteSyncConfig = "true", maxRetry = "5", configRetryTime = "2600", configLongPollTimeout = "26000"))
|
||||
@Component
|
||||
public class NacosPropertySourceTest
|
||||
extends AbstractNacosHttpServerTestExecutionListener {
|
||||
|
||||
private static final String LINE_SEPARATOR = System.getProperty("line.separator");
|
||||
|
||||
public static final String DATA_ID = "app";
|
||||
|
||||
private static final String LINE_SEPARATOR = System.getProperty("line.separator");
|
||||
private static final String APP_NAME = "Nacos-Spring";
|
||||
|
||||
private static final String ANOTHER_APP_NAME = "Nacos-Spring-1";
|
||||
|
||||
private static final int VALUE_1 = 1;
|
||||
|
||||
private static final int VALUE_2 = 2;
|
||||
|
||||
private static final int VALUE_3 = 3;
|
||||
|
||||
private static final int VALUE_4 = 4;
|
||||
private static final String VALUE_5 = "zhangsan";
|
||||
private static final String VALUE_6 = "lisi";
|
||||
private static final String VALUE_7 = "wangwu";
|
||||
private static final String VALUE_8 = "zhaoliu";
|
||||
private static final String DEFAULT_JSON_VALUE = "{\"0\":\"1\",\"10\":\"13\"}";
|
||||
private static final String NEW_STR_VALUE = "new json value";
|
||||
|
||||
@NacosInjected
|
||||
private ConfigService configService;
|
||||
@Autowired
|
||||
private App app;
|
||||
@Autowired
|
||||
private Environment environment;
|
||||
|
||||
@Override
|
||||
public void init(EmbeddedNacosHttpServer httpServer) {
|
||||
|
@ -90,7 +94,8 @@ public class NacosPropertySourceTest
|
|||
|
||||
config.put(CONTENT_PARAM_NAME, "app.name=" + APP_NAME + LINE_SEPARATOR
|
||||
+ "app.nacosFieldIntValueAutoRefreshed=" + VALUE_1 + LINE_SEPARATOR
|
||||
+ "app.nacosMethodIntValueAutoRefreshed=" + VALUE_2);
|
||||
+ "app.nacosMethodIntValueAutoRefreshed=" + VALUE_2 + LINE_SEPARATOR
|
||||
+ "app.nacosFieldListValueAutoRefreshed=" + VALUE_5 + "," + VALUE_6);
|
||||
httpServer.initConfig(config);
|
||||
}
|
||||
|
||||
|
@ -99,6 +104,78 @@ public class NacosPropertySourceTest
|
|||
return "server.addr";
|
||||
}
|
||||
|
||||
@Bean
|
||||
public App app() {
|
||||
return new App();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValue() throws NacosException, InterruptedException {
|
||||
Assert.assertEquals(APP_NAME, app.name);
|
||||
|
||||
Assert.assertEquals(APP_NAME, app.nameWithDefaultValue);
|
||||
|
||||
Assert.assertEquals(APP_NAME, app.nacosNameAutoRefreshed);
|
||||
|
||||
Assert.assertEquals(APP_NAME, app.nacosNameAutoRefreshedWithDefaultValue);
|
||||
|
||||
Assert.assertEquals(APP_NAME, app.nacosNameNotAutoRefreshed);
|
||||
|
||||
Assert.assertEquals(APP_NAME, environment.getProperty("app.name"));
|
||||
|
||||
Assert.assertEquals(VALUE_1, app.nacosFieldIntValue);
|
||||
|
||||
Assert.assertEquals(VALUE_2, app.nacosMethodIntValue);
|
||||
|
||||
Assert.assertEquals(VALUE_5, app.nacosFieldListValue.get(0));
|
||||
Assert.assertEquals(VALUE_6, app.nacosFieldListValue.get(1));
|
||||
|
||||
Assert.assertEquals(VALUE_1, app.nacosFieldIntValueAutoRefreshed);
|
||||
|
||||
Assert.assertEquals(VALUE_2, app.nacosMethodIntValueAutoRefreshed);
|
||||
|
||||
Assert.assertEquals(VALUE_5, app.nacosFieldListValueAutoRefreshed.get(0));
|
||||
Assert.assertEquals(VALUE_6, app.nacosFieldListValueAutoRefreshed.get(1));
|
||||
|
||||
Assert.assertEquals(DEFAULT_JSON_VALUE, app.strWithDefaultJsonValue);
|
||||
|
||||
configService.publishConfig(DATA_ID, DEFAULT_GROUP, "app.name=" + ANOTHER_APP_NAME
|
||||
+ LINE_SEPARATOR + "app.nacosFieldIntValueAutoRefreshed=" + VALUE_3
|
||||
+ LINE_SEPARATOR + "app.nacosMethodIntValueAutoRefreshed=" + VALUE_4
|
||||
+ LINE_SEPARATOR + "app.nacosFieldListValueAutoRefreshed=" + VALUE_7 + "," + VALUE_8
|
||||
+ LINE_SEPARATOR + "app.strWithDefaultJsonValue=" + NEW_STR_VALUE);
|
||||
|
||||
Thread.sleep(1000);
|
||||
|
||||
Assert.assertEquals(APP_NAME, app.name);
|
||||
|
||||
Assert.assertEquals(APP_NAME, app.nameWithDefaultValue);
|
||||
|
||||
Assert.assertEquals(ANOTHER_APP_NAME, app.nacosNameAutoRefreshed);
|
||||
|
||||
Assert.assertEquals(ANOTHER_APP_NAME, app.nacosNameAutoRefreshedWithDefaultValue);
|
||||
|
||||
Assert.assertEquals(APP_NAME, app.nacosNameNotAutoRefreshed);
|
||||
|
||||
Assert.assertEquals(ANOTHER_APP_NAME, environment.getProperty("app.name"));
|
||||
|
||||
Assert.assertEquals(VALUE_1, app.nacosFieldIntValue);
|
||||
|
||||
Assert.assertEquals(VALUE_2, app.nacosMethodIntValue);
|
||||
|
||||
Assert.assertEquals(VALUE_5, app.nacosFieldListValue.get(0));
|
||||
Assert.assertEquals(VALUE_6, app.nacosFieldListValue.get(1));
|
||||
|
||||
Assert.assertEquals(VALUE_3, app.nacosFieldIntValueAutoRefreshed);
|
||||
|
||||
Assert.assertEquals(VALUE_4, app.nacosMethodIntValueAutoRefreshed);
|
||||
|
||||
Assert.assertEquals(VALUE_7, app.nacosFieldListValueAutoRefreshed.get(0));
|
||||
Assert.assertEquals(VALUE_8, app.nacosFieldListValueAutoRefreshed.get(1));
|
||||
|
||||
Assert.assertEquals(NEW_STR_VALUE, app.strWithDefaultJsonValue);
|
||||
}
|
||||
|
||||
public static class App {
|
||||
|
||||
@Value("${app.name}")
|
||||
|
@ -123,14 +200,22 @@ public class NacosPropertySourceTest
|
|||
private int nacosFieldIntValueAutoRefreshed;
|
||||
|
||||
private int nacosMethodIntValue;
|
||||
private int nacosMethodIntValueAutoRefreshed;
|
||||
|
||||
@NacosValue(value = "#{'${app.nacosFieldListValue:" + VALUE_5 + "," + VALUE_6 + "}'.split(',')}")
|
||||
private List nacosFieldListValue;
|
||||
|
||||
@NacosValue(value = "#{'${app.nacosFieldListValueAutoRefreshed}'.split(',')}", autoRefreshed = true)
|
||||
private List nacosFieldListValueAutoRefreshed;
|
||||
|
||||
@NacosValue(value = "${app.strWithDefaultJsonValue:" + DEFAULT_JSON_VALUE + "}", autoRefreshed = true)
|
||||
private String strWithDefaultJsonValue;
|
||||
|
||||
@NacosValue("${app.nacosMethodIntValue:" + VALUE_2 + "}")
|
||||
public void setNacosMethodIntValue(int nacosMethodIntValue) {
|
||||
this.nacosMethodIntValue = nacosMethodIntValue;
|
||||
}
|
||||
|
||||
private int nacosMethodIntValueAutoRefreshed;
|
||||
|
||||
@NacosValue(value = "${app.nacosMethodIntValueAutoRefreshed}", autoRefreshed = true)
|
||||
public void setNacosMethodIntValueAutoRefreshed(
|
||||
int nacosMethodIntValueAutoRefreshed) {
|
||||
|
@ -138,67 +223,4 @@ public class NacosPropertySourceTest
|
|||
}
|
||||
}
|
||||
|
||||
@Bean
|
||||
public App app() {
|
||||
return new App();
|
||||
}
|
||||
|
||||
@NacosInjected
|
||||
private ConfigService configService;
|
||||
|
||||
@Autowired
|
||||
private App app;
|
||||
|
||||
@Autowired
|
||||
private Environment environment;
|
||||
|
||||
@Test
|
||||
public void testValue() throws NacosException, InterruptedException {
|
||||
Assert.assertEquals(APP_NAME, app.name);
|
||||
|
||||
Assert.assertEquals(APP_NAME, app.nameWithDefaultValue);
|
||||
|
||||
Assert.assertEquals(APP_NAME, app.nacosNameAutoRefreshed);
|
||||
|
||||
Assert.assertEquals(APP_NAME, app.nacosNameAutoRefreshedWithDefaultValue);
|
||||
|
||||
Assert.assertEquals(APP_NAME, app.nacosNameNotAutoRefreshed);
|
||||
|
||||
Assert.assertEquals(APP_NAME, environment.getProperty("app.name"));
|
||||
|
||||
Assert.assertEquals(VALUE_1, app.nacosFieldIntValue);
|
||||
|
||||
Assert.assertEquals(VALUE_2, app.nacosMethodIntValue);
|
||||
|
||||
Assert.assertEquals(VALUE_1, app.nacosFieldIntValueAutoRefreshed);
|
||||
|
||||
Assert.assertEquals(VALUE_2, app.nacosMethodIntValueAutoRefreshed);
|
||||
|
||||
configService.publishConfig(DATA_ID, DEFAULT_GROUP, "app.name=" + ANOTHER_APP_NAME
|
||||
+ LINE_SEPARATOR + "app.nacosFieldIntValueAutoRefreshed=" + VALUE_3
|
||||
+ LINE_SEPARATOR + "app.nacosMethodIntValueAutoRefreshed=" + VALUE_4);
|
||||
|
||||
Thread.sleep(1000);
|
||||
|
||||
Assert.assertEquals(APP_NAME, app.name);
|
||||
|
||||
Assert.assertEquals(APP_NAME, app.nameWithDefaultValue);
|
||||
|
||||
Assert.assertEquals(ANOTHER_APP_NAME, app.nacosNameAutoRefreshed);
|
||||
|
||||
Assert.assertEquals(ANOTHER_APP_NAME, app.nacosNameAutoRefreshedWithDefaultValue);
|
||||
|
||||
Assert.assertEquals(APP_NAME, app.nacosNameNotAutoRefreshed);
|
||||
|
||||
Assert.assertEquals(ANOTHER_APP_NAME, environment.getProperty("app.name"));
|
||||
|
||||
Assert.assertEquals(VALUE_1, app.nacosFieldIntValue);
|
||||
|
||||
Assert.assertEquals(VALUE_2, app.nacosMethodIntValue);
|
||||
|
||||
Assert.assertEquals(VALUE_3, app.nacosFieldIntValueAutoRefreshed);
|
||||
|
||||
Assert.assertEquals(VALUE_4, app.nacosMethodIntValueAutoRefreshed);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -16,21 +16,19 @@
|
|||
*/
|
||||
package com.alibaba.nacos.spring.context.annotation.config;
|
||||
|
||||
import static com.alibaba.nacos.api.common.Constants.DEFAULT_GROUP;
|
||||
import static com.alibaba.nacos.embedded.web.server.NacosConfigHttpHandler.CONTENT_PARAM_NAME;
|
||||
import static com.alibaba.nacos.embedded.web.server.NacosConfigHttpHandler.DATA_ID_PARAM_NAME;
|
||||
import static com.alibaba.nacos.embedded.web.server.NacosConfigHttpHandler.GROUP_ID_PARAM_NAME;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import com.alibaba.nacos.api.annotation.NacosInjected;
|
||||
import com.alibaba.nacos.api.annotation.NacosProperties;
|
||||
import com.alibaba.nacos.api.config.ConfigService;
|
||||
import com.alibaba.nacos.api.exception.NacosException;
|
||||
import com.alibaba.nacos.embedded.web.server.EmbeddedNacosHttpServer;
|
||||
import com.alibaba.nacos.spring.context.annotation.EnableNacos;
|
||||
import com.alibaba.nacos.spring.test.AbstractNacosHttpServerTestExecutionListener;
|
||||
import com.alibaba.nacos.spring.test.XmlApp;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Assert;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
@ -40,10 +38,14 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
|||
import org.springframework.test.context.support.DependencyInjectionTestExecutionListener;
|
||||
import org.springframework.test.context.support.DirtiesContextTestExecutionListener;
|
||||
|
||||
import static com.alibaba.nacos.api.common.Constants.DEFAULT_GROUP;
|
||||
import static com.alibaba.nacos.embedded.web.server.NacosConfigHttpHandler.CONTENT_PARAM_NAME;
|
||||
import static com.alibaba.nacos.embedded.web.server.NacosConfigHttpHandler.DATA_ID_PARAM_NAME;
|
||||
import static com.alibaba.nacos.embedded.web.server.NacosConfigHttpHandler.GROUP_ID_PARAM_NAME;
|
||||
import com.alibaba.nacos.api.annotation.NacosInjected;
|
||||
import com.alibaba.nacos.api.annotation.NacosProperties;
|
||||
import com.alibaba.nacos.api.config.ConfigService;
|
||||
import com.alibaba.nacos.api.exception.NacosException;
|
||||
import com.alibaba.nacos.embedded.web.server.EmbeddedNacosHttpServer;
|
||||
import com.alibaba.nacos.spring.test.AbstractNacosHttpServerTestExecutionListener;
|
||||
import com.alibaba.nacos.spring.test.XmlApp;
|
||||
import com.alibaba.nacos.spring.util.NacosUtils;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:liaochunyhm@live.com">liaochuntao</a>
|
||||
|
@ -53,23 +55,26 @@ import static com.alibaba.nacos.embedded.web.server.NacosConfigHttpHandler.GROUP
|
|||
@ContextConfiguration(classes = { NacosPropertySourceXmlTest.class })
|
||||
@TestExecutionListeners({ DependencyInjectionTestExecutionListener.class,
|
||||
DirtiesContextTestExecutionListener.class, NacosPropertySourceXmlTest.class })
|
||||
@EnableNacos(globalProperties = @NacosProperties(serverAddr = "${server.addr}"))
|
||||
@EnableNacosConfig(globalProperties = @NacosProperties(serverAddr = "${server.addr}"))
|
||||
@Component
|
||||
public class NacosPropertySourceXmlTest
|
||||
extends AbstractNacosHttpServerTestExecutionListener {
|
||||
|
||||
@Override
|
||||
protected String getServerAddressPropertyName() {
|
||||
return "server.addr";
|
||||
}
|
||||
|
||||
private final String except = "XmlApp{students=[Student{name='lct-1', num='1006010022'}, Student{name='lct-3', num='1006010044'}, Student{name='lct-4', num='1006010055'}]}";
|
||||
private String xml = "<students>" + "<student>" + "<name>lct-1</name>"
|
||||
+ "<num>1006010022</num>" + "</student>" + "<student>" + "<name>lct-2</name>"
|
||||
+ "<num>1006010033</num>" + "</student>" + "<student>" + "<name>lct-3</name>"
|
||||
+ "<num>1006010044</num>" + "</student>" + "<student>" + "<name>lct-4</name>"
|
||||
+ "<num>1006010055</num>" + "</student>" + "</students>";
|
||||
@NacosInjected
|
||||
private ConfigService configService;
|
||||
@Autowired
|
||||
private XmlApp xmlApp;
|
||||
|
||||
private final String except = "XmlApp{students=[Student{name='lct-1', num='1006010022'}, Student{name='lct-3', num='1006010044'}, Student{name='lct-4', num='1006010055'}]}";
|
||||
@Override
|
||||
protected String getServerAddressPropertyName() {
|
||||
return "server.addr";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(EmbeddedNacosHttpServer httpServer) {
|
||||
|
@ -86,12 +91,6 @@ public class NacosPropertySourceXmlTest
|
|||
return new XmlApp();
|
||||
}
|
||||
|
||||
@NacosInjected
|
||||
private ConfigService configService;
|
||||
|
||||
@Autowired
|
||||
private XmlApp xmlApp;
|
||||
|
||||
@Test
|
||||
public void testValue() throws NacosException, InterruptedException {
|
||||
|
||||
|
|
|
@ -16,21 +16,21 @@
|
|||
*/
|
||||
package com.alibaba.nacos.spring.context.annotation.config;
|
||||
|
||||
import com.alibaba.nacos.api.annotation.NacosInjected;
|
||||
import com.alibaba.nacos.api.annotation.NacosProperties;
|
||||
import com.alibaba.nacos.api.config.ConfigService;
|
||||
import com.alibaba.nacos.api.config.annotation.NacosValue;
|
||||
import com.alibaba.nacos.api.exception.NacosException;
|
||||
import com.alibaba.nacos.embedded.web.server.EmbeddedNacosHttpServer;
|
||||
import com.alibaba.nacos.spring.context.annotation.EnableNacos;
|
||||
import com.alibaba.nacos.spring.test.AbstractNacosHttpServerTestExecutionListener;
|
||||
import com.alibaba.nacos.spring.test.YamlApp;
|
||||
import static com.alibaba.nacos.api.common.Constants.DEFAULT_GROUP;
|
||||
import static com.alibaba.nacos.embedded.web.server.NacosConfigHttpHandler.CONTENT_PARAM_NAME;
|
||||
import static com.alibaba.nacos.embedded.web.server.NacosConfigHttpHandler.DATA_ID_PARAM_NAME;
|
||||
import static com.alibaba.nacos.embedded.web.server.NacosConfigHttpHandler.GROUP_ID_PARAM_NAME;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Assert;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
|
@ -39,95 +39,99 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
|||
import org.springframework.test.context.support.DependencyInjectionTestExecutionListener;
|
||||
import org.springframework.test.context.support.DirtiesContextTestExecutionListener;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static com.alibaba.nacos.api.common.Constants.DEFAULT_GROUP;
|
||||
import static com.alibaba.nacos.embedded.web.server.NacosConfigHttpHandler.CONTENT_PARAM_NAME;
|
||||
import static com.alibaba.nacos.embedded.web.server.NacosConfigHttpHandler.DATA_ID_PARAM_NAME;
|
||||
import static com.alibaba.nacos.embedded.web.server.NacosConfigHttpHandler.GROUP_ID_PARAM_NAME;
|
||||
import com.alibaba.nacos.api.annotation.NacosInjected;
|
||||
import com.alibaba.nacos.api.annotation.NacosProperties;
|
||||
import com.alibaba.nacos.api.config.ConfigService;
|
||||
import com.alibaba.nacos.api.config.annotation.NacosValue;
|
||||
import com.alibaba.nacos.api.exception.NacosException;
|
||||
import com.alibaba.nacos.embedded.web.server.EmbeddedNacosHttpServer;
|
||||
import com.alibaba.nacos.spring.test.AbstractNacosHttpServerTestExecutionListener;
|
||||
import com.alibaba.nacos.spring.test.YamlApp;
|
||||
import com.alibaba.nacos.spring.util.NacosUtils;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:liaochunyhm@live.com">liaochuntao</a>
|
||||
* @since 0.3.0
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration(classes = {NacosPropertySourceYamlTest.class})
|
||||
@TestExecutionListeners({DependencyInjectionTestExecutionListener.class,
|
||||
DirtiesContextTestExecutionListener.class, NacosPropertySourceYamlTest.class})
|
||||
|
||||
@ContextConfiguration(classes = { NacosPropertySourceYamlTest.class })
|
||||
@TestExecutionListeners({ DependencyInjectionTestExecutionListener.class,
|
||||
DirtiesContextTestExecutionListener.class, NacosPropertySourceYamlTest.class })
|
||||
@NacosPropertySources(value = {
|
||||
@NacosPropertySource(dataId = YamlApp.DATA_ID_YAML
|
||||
+ "_not_exist.yaml", autoRefreshed = true),
|
||||
@NacosPropertySource(dataId = YamlApp.DATA_ID_YAML
|
||||
+ ".yml", autoRefreshed = true)})
|
||||
@EnableNacos(globalProperties = @NacosProperties(serverAddr = "${server.addr}"))
|
||||
@NacosPropertySource(dataId = YamlApp.DATA_ID_YAML
|
||||
+ "_not_exist.yaml", autoRefreshed = true),
|
||||
@NacosPropertySource(dataId = YamlApp.DATA_ID_YAML
|
||||
+ ".yml", autoRefreshed = true) })
|
||||
@EnableNacosConfig(globalProperties = @NacosProperties(serverAddr = "${server.addr}"))
|
||||
@Component
|
||||
public class NacosPropertySourceYamlTest
|
||||
extends AbstractNacosHttpServerTestExecutionListener {
|
||||
extends AbstractNacosHttpServerTestExecutionListener {
|
||||
|
||||
private String yaml = "students:\n" + " - {name: lct-1,num: 12}\n"
|
||||
+ " - {name: lct-2,num: 13}\n" + " - {name: lct-3,num: 14}";
|
||||
private String yaml = "students:\n" + " - {name: lct-1,num: 12}\n"
|
||||
+ " - {name: lct-2,num: 13}\n" + " - {name: lct-3,num: 14}";
|
||||
private String configStr = "people:\n" + " a: 1\n" + " b: 1";
|
||||
private String except = "YamlApp{students=[Student{name='lct-1', num='12'}, Student{name='lct-2', num='13'}, Student{name='lct-3', num='14'}]}";
|
||||
@NacosInjected
|
||||
private ConfigService configService;
|
||||
@Autowired
|
||||
private YamlApp yamlApp;
|
||||
@Autowired
|
||||
@Qualifier(value = "myApp")
|
||||
private App app;
|
||||
|
||||
private String configStr = "people:\n" + " a: 1\n" + " b: 1";
|
||||
@BeforeClass
|
||||
public static void beforeClass() {
|
||||
}
|
||||
|
||||
private String except = "YamlApp{students=[Student{name='lct-1', num='12'}, Student{name='lct-2', num='13'}, Student{name='lct-3', num='14'}]}";
|
||||
@AfterClass
|
||||
public static void afterClass() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(EmbeddedNacosHttpServer httpServer) {
|
||||
Map<String, String> config = new HashMap<String, String>(1);
|
||||
config.put(DATA_ID_PARAM_NAME, YamlApp.DATA_ID_YAML + ".yml");
|
||||
config.put(GROUP_ID_PARAM_NAME, DEFAULT_GROUP);
|
||||
config.put(CONTENT_PARAM_NAME, configStr);
|
||||
@Override
|
||||
public void init(EmbeddedNacosHttpServer httpServer) {
|
||||
Map<String, String> config = new HashMap<String, String>(1);
|
||||
config.put(DATA_ID_PARAM_NAME, YamlApp.DATA_ID_YAML + ".yml");
|
||||
config.put(GROUP_ID_PARAM_NAME, DEFAULT_GROUP);
|
||||
config.put(CONTENT_PARAM_NAME, configStr);
|
||||
|
||||
httpServer.initConfig(config);
|
||||
}
|
||||
httpServer.initConfig(config);
|
||||
}
|
||||
|
||||
private static class App {
|
||||
@Bean(name = "myApp")
|
||||
public App app() {
|
||||
return new App();
|
||||
}
|
||||
|
||||
@Value("${people.a}")
|
||||
private String a;
|
||||
@NacosValue("${people.b}")
|
||||
private String b;
|
||||
@Bean
|
||||
public YamlApp yamlApp() {
|
||||
return new YamlApp();
|
||||
}
|
||||
|
||||
}
|
||||
@Override
|
||||
protected String getServerAddressPropertyName() {
|
||||
return "server.addr";
|
||||
}
|
||||
|
||||
@Bean(name = "myApp")
|
||||
public App app() {
|
||||
return new App();
|
||||
}
|
||||
@Test
|
||||
public void testValue() throws NacosException, InterruptedException {
|
||||
|
||||
@Bean
|
||||
public YamlApp yamlApp() {
|
||||
return new YamlApp();
|
||||
}
|
||||
Assert.assertEquals("1", app.a);
|
||||
Assert.assertEquals("1", app.b);
|
||||
|
||||
@NacosInjected
|
||||
private ConfigService configService;
|
||||
configService.publishConfig(YamlApp.DATA_ID_YAML + ".yml", DEFAULT_GROUP, yaml);
|
||||
|
||||
@Autowired
|
||||
private YamlApp yamlApp;
|
||||
Thread.sleep(2000);
|
||||
|
||||
@Autowired
|
||||
@Qualifier(value = "myApp")
|
||||
private App app;
|
||||
Assert.assertEquals(except, yamlApp.toString());
|
||||
|
||||
@Override
|
||||
protected String getServerAddressPropertyName() {
|
||||
return "server.addr";
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValue() throws NacosException, InterruptedException {
|
||||
private static class App {
|
||||
|
||||
Assert.assertEquals("1", app.a);
|
||||
Assert.assertEquals("1", app.b);
|
||||
@NacosValue("${people.a}")
|
||||
private String a;
|
||||
@NacosValue("${people.b}")
|
||||
private String b;
|
||||
|
||||
configService.publishConfig(YamlApp.DATA_ID_YAML + ".yml", DEFAULT_GROUP, yaml);
|
||||
|
||||
Thread.sleep(2000);
|
||||
|
||||
Assert.assertEquals(except, yamlApp.toString());
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
*
|
||||
* * Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* * contributor license agreements. See the NOTICE file distributed with
|
||||
* * this work for additional information regarding copyright ownership.
|
||||
* * The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* * (the "License"); you may not use this file except in compliance with
|
||||
* * the License. You may obtain a copy of the License at
|
||||
* *
|
||||
* * http://www.apache.org/licenses/LICENSE-2.0
|
||||
* *
|
||||
* * Unless required by applicable law or agreed to in writing, software
|
||||
* * distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* * See the License for the specific language governing permissions and
|
||||
* * limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.spring.context.annotation.config;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.TypeConverter;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
/**
|
||||
* {@link NacosValueAnnotationBeanPostProcessor} Test
|
||||
* @author SuperZ1999
|
||||
* @date 2023/9/28
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration(classes = NacosValueAnnotationBeanPostProcessorTest.class)
|
||||
public class NacosValueAnnotationBeanPostProcessorTest {
|
||||
|
||||
@Autowired
|
||||
private ConfigurableListableBeanFactory beanFactory;
|
||||
|
||||
@Bean
|
||||
public NacosValueAnnotationBeanPostProcessor nacosValueAnnotationBeanPostProcessor() {
|
||||
return new NacosValueAnnotationBeanPostProcessor();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConvertIfNecessary() throws NoSuchMethodException {
|
||||
TypeConverter converter = beanFactory.getTypeConverter();
|
||||
Method method = NacosValueAnnotationBeanPostProcessorTest.class.getMethod("testMethodParameter", Integer.class);
|
||||
Integer integer = converter.convertIfNecessary("12", Integer.class, new MethodParameter(method, 0));
|
||||
System.out.println(integer);
|
||||
Assert.assertEquals(integer, Integer.valueOf(12));
|
||||
}
|
||||
|
||||
public void testMethodParameter(Integer i) {
|
||||
System.out.println(i);
|
||||
}
|
||||
}
|
|
@ -1,15 +1,15 @@
|
|||
package com.alibaba.nacos.spring.context.annotation.config;
|
||||
|
||||
import com.alibaba.nacos.api.annotation.NacosInjected;
|
||||
import com.alibaba.nacos.api.annotation.NacosProperties;
|
||||
import com.alibaba.nacos.api.config.ConfigService;
|
||||
import com.alibaba.nacos.api.exception.NacosException;
|
||||
import com.alibaba.nacos.embedded.web.server.EmbeddedNacosHttpServer;
|
||||
import com.alibaba.nacos.spring.context.annotation.EnableNacos;
|
||||
import com.alibaba.nacos.spring.test.AbstractNacosHttpServerTestExecutionListener;
|
||||
import com.alibaba.nacos.spring.test.YamlApp;
|
||||
import com.alibaba.nacos.spring.test.YamlMap;
|
||||
import org.junit.Assert;
|
||||
import static com.alibaba.nacos.api.common.Constants.DEFAULT_GROUP;
|
||||
import static com.alibaba.nacos.embedded.web.server.NacosConfigHttpHandler.CONTENT_PARAM_NAME;
|
||||
import static com.alibaba.nacos.embedded.web.server.NacosConfigHttpHandler.DATA_ID_PARAM_NAME;
|
||||
import static com.alibaba.nacos.embedded.web.server.NacosConfigHttpHandler.GROUP_ID_PARAM_NAME;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
@ -21,90 +21,74 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
|||
import org.springframework.test.context.support.DependencyInjectionTestExecutionListener;
|
||||
import org.springframework.test.context.support.DirtiesContextTestExecutionListener;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static com.alibaba.nacos.api.common.Constants.DEFAULT_GROUP;
|
||||
import static com.alibaba.nacos.embedded.web.server.NacosConfigHttpHandler.CONTENT_PARAM_NAME;
|
||||
import static com.alibaba.nacos.embedded.web.server.NacosConfigHttpHandler.DATA_ID_PARAM_NAME;
|
||||
import static com.alibaba.nacos.embedded.web.server.NacosConfigHttpHandler.GROUP_ID_PARAM_NAME;
|
||||
import com.alibaba.nacos.api.annotation.NacosInjected;
|
||||
import com.alibaba.nacos.api.annotation.NacosProperties;
|
||||
import com.alibaba.nacos.api.config.ConfigService;
|
||||
import com.alibaba.nacos.api.exception.NacosException;
|
||||
import com.alibaba.nacos.embedded.web.server.EmbeddedNacosHttpServer;
|
||||
import com.alibaba.nacos.spring.test.AbstractNacosHttpServerTestExecutionListener;
|
||||
import com.alibaba.nacos.spring.test.YamlMap;
|
||||
import com.alibaba.nacos.spring.util.NacosUtils;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:liaochuntao@youzan.com">liaochuntao</a>
|
||||
* @Created at 2020/1/12 3:55 下午
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration(classes = {NacosYamlMapTest.class})
|
||||
@TestExecutionListeners({DependencyInjectionTestExecutionListener.class,
|
||||
DirtiesContextTestExecutionListener.class, NacosYamlMapTest.class})
|
||||
@ContextConfiguration(classes = { NacosYamlMapTest.class })
|
||||
@TestExecutionListeners({ DependencyInjectionTestExecutionListener.class,
|
||||
DirtiesContextTestExecutionListener.class, NacosYamlMapTest.class })
|
||||
|
||||
@NacosPropertySources(value = {
|
||||
@NacosPropertySource(dataId = "yaml_map"
|
||||
+ "_not_exist.yaml", autoRefreshed = true),
|
||||
@NacosPropertySource(dataId = "yaml_map"
|
||||
+ ".yml", autoRefreshed = true)})
|
||||
@EnableNacos(globalProperties = @NacosProperties(serverAddr = "${server.addr}"))
|
||||
@NacosPropertySource(dataId = "yaml_map"
|
||||
+ "_not_exist.yaml", autoRefreshed = true),
|
||||
@NacosPropertySource(dataId = "yaml_map" + ".yml", autoRefreshed = true) })
|
||||
@EnableNacosConfig(globalProperties = @NacosProperties(serverAddr = "${server.addr}"))
|
||||
@Component
|
||||
public class NacosYamlMapTest extends AbstractNacosHttpServerTestExecutionListener {
|
||||
|
||||
private String configStr = "routingMap:\n" +
|
||||
" - aaa\n" +
|
||||
" - bbb\n" +
|
||||
" - ccc\n" +
|
||||
" - ddd\n" +
|
||||
" - eee\n" +
|
||||
"endPointMap:\n" +
|
||||
" - fff\n" +
|
||||
"testMap:\n" +
|
||||
" abc: def1";
|
||||
private String configStr = "routingMap:\n" + " - aaa\n" + " - bbb\n" + " - ccc\n"
|
||||
+ " - ddd\n" + " - eee\n" + "endPointMap:\n" + " - fff\n" + "testMap:\n"
|
||||
+ " abc: def1";
|
||||
private String newConfigStr = "routingMap:\n" + " - aaa\n" + " - bbb\n"
|
||||
+ " - ccc\n" + " - ddd\n" + "endPointMap:\n" + " - fff\n" + "testMap:\n"
|
||||
+ " liaochuntao: def1";
|
||||
@Autowired
|
||||
private YamlMap yamlMap;
|
||||
@NacosInjected
|
||||
private ConfigService configService;
|
||||
|
||||
private String newConfigStr = "routingMap:\n" +
|
||||
" - aaa\n" +
|
||||
" - bbb\n" +
|
||||
" - ccc\n" +
|
||||
" - ddd\n" +
|
||||
"endPointMap:\n" +
|
||||
" - fff\n" +
|
||||
"testMap:\n" +
|
||||
" liaochuntao: def1";
|
||||
@Override
|
||||
protected String getServerAddressPropertyName() {
|
||||
return "server.addr";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getServerAddressPropertyName() {
|
||||
return "server.addr";
|
||||
}
|
||||
@Override
|
||||
public void init(EmbeddedNacosHttpServer httpServer) {
|
||||
Map<String, String> config = new HashMap<String, String>(1);
|
||||
config.put(DATA_ID_PARAM_NAME, "yaml_map" + ".yml");
|
||||
config.put(GROUP_ID_PARAM_NAME, DEFAULT_GROUP);
|
||||
config.put(CONTENT_PARAM_NAME, configStr);
|
||||
|
||||
@Override
|
||||
public void init(EmbeddedNacosHttpServer httpServer) {
|
||||
Map<String, String> config = new HashMap<String, String>(1);
|
||||
config.put(DATA_ID_PARAM_NAME, "yaml_map" + ".yml");
|
||||
config.put(GROUP_ID_PARAM_NAME, DEFAULT_GROUP);
|
||||
config.put(CONTENT_PARAM_NAME, configStr);
|
||||
httpServer.initConfig(config);
|
||||
}
|
||||
|
||||
httpServer.initConfig(config);
|
||||
}
|
||||
@Bean
|
||||
public YamlMap yamlMap() {
|
||||
return new YamlMap();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public YamlMap yamlMap() {
|
||||
return new YamlMap();
|
||||
}
|
||||
@Test
|
||||
public void testValue() throws NacosException, InterruptedException {
|
||||
|
||||
@Autowired
|
||||
private YamlMap yamlMap;
|
||||
System.out.println(yamlMap);
|
||||
|
||||
@NacosInjected
|
||||
private ConfigService configService;
|
||||
configService.publishConfig("yaml_map" + ".yml", DEFAULT_GROUP, newConfigStr);
|
||||
|
||||
@Test
|
||||
public void testValue() throws NacosException, InterruptedException {
|
||||
Thread.sleep(2000);
|
||||
|
||||
System.out.println(yamlMap);
|
||||
System.out.println(yamlMap);
|
||||
|
||||
configService.publishConfig("yaml_map" + ".yml", DEFAULT_GROUP, newConfigStr);
|
||||
|
||||
Thread.sleep(2000);
|
||||
|
||||
System.out.println(yamlMap);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -16,11 +16,6 @@
|
|||
*/
|
||||
package com.alibaba.nacos.spring.context.annotation.discovery;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.mock.env.MockEnvironment;
|
||||
|
||||
import static com.alibaba.nacos.spring.context.annotation.discovery.EnableNacosDiscovery.ACCESS_KEY_PLACEHOLDER;
|
||||
import static com.alibaba.nacos.spring.context.annotation.discovery.EnableNacosDiscovery.CLUSTER_NAME_PLACEHOLDER;
|
||||
import static com.alibaba.nacos.spring.context.annotation.discovery.EnableNacosDiscovery.CONTEXT_PATH_PLACEHOLDER;
|
||||
|
@ -30,6 +25,10 @@ import static com.alibaba.nacos.spring.context.annotation.discovery.EnableNacosD
|
|||
import static com.alibaba.nacos.spring.context.annotation.discovery.EnableNacosDiscovery.SECRET_KEY_PLACEHOLDER;
|
||||
import static com.alibaba.nacos.spring.context.annotation.discovery.EnableNacosDiscovery.SERVER_ADDR_PLACEHOLDER;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.springframework.mock.env.MockEnvironment;
|
||||
|
||||
/**
|
||||
* {@link EnableNacosDiscovery} Test
|
||||
*
|
||||
|
|
|
@ -16,19 +16,6 @@
|
|||
*/
|
||||
package com.alibaba.nacos.spring.context.config.xml;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Assert;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
import static com.alibaba.nacos.api.PropertyKeyConst.ACCESS_KEY;
|
||||
import static com.alibaba.nacos.api.PropertyKeyConst.CLUSTER_NAME;
|
||||
import static com.alibaba.nacos.api.PropertyKeyConst.CONTEXT_PATH;
|
||||
|
@ -39,6 +26,18 @@ import static com.alibaba.nacos.api.PropertyKeyConst.SECRET_KEY;
|
|||
import static com.alibaba.nacos.api.PropertyKeyConst.SERVER_ADDR;
|
||||
import static com.alibaba.nacos.spring.util.NacosBeanUtils.GLOBAL_NACOS_PROPERTIES_BEAN_NAME;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Assert;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
/**
|
||||
* {@link GlobalNacosPropertiesBeanDefinitionParser} Test
|
||||
*
|
||||
|
@ -50,6 +49,10 @@ import static com.alibaba.nacos.spring.util.NacosBeanUtils.GLOBAL_NACOS_PROPERTI
|
|||
@ContextConfiguration(locations = { "classpath:/META-INF/nacos-global-properties.xml" })
|
||||
public class GlobalNacosPropertiesBeanDefinitionParserTest {
|
||||
|
||||
@Autowired
|
||||
@Qualifier(GLOBAL_NACOS_PROPERTIES_BEAN_NAME)
|
||||
private Properties globalNacosProperties;
|
||||
|
||||
@BeforeClass
|
||||
public static void init() {
|
||||
System.setProperty("nacos.server-addr", "127.0.0.1:8080");
|
||||
|
@ -60,10 +63,6 @@ public class GlobalNacosPropertiesBeanDefinitionParserTest {
|
|||
System.getProperties().remove("nacos.server-addr");
|
||||
}
|
||||
|
||||
@Autowired
|
||||
@Qualifier(GLOBAL_NACOS_PROPERTIES_BEAN_NAME)
|
||||
private Properties globalNacosProperties;
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
Assert.assertNull(globalNacosProperties.get(ENDPOINT));
|
||||
|
|
|
@ -18,6 +18,16 @@ package com.alibaba.nacos.spring.context.config.xml;
|
|||
|
||||
import java.util.Properties;
|
||||
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Assert;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
import com.alibaba.nacos.api.annotation.NacosInjected;
|
||||
import com.alibaba.nacos.api.config.ConfigService;
|
||||
import com.alibaba.nacos.spring.beans.factory.annotation.AnnotationNacosInjectedBeanPostProcessor;
|
||||
|
@ -26,16 +36,7 @@ import com.alibaba.nacos.spring.context.properties.config.NacosConfigurationProp
|
|||
import com.alibaba.nacos.spring.core.env.NacosPropertySourcePostProcessor;
|
||||
import com.alibaba.nacos.spring.factory.ApplicationContextHolder;
|
||||
import com.alibaba.nacos.spring.util.NacosBeanUtils;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Assert;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import com.alibaba.nacos.spring.util.NacosUtils;
|
||||
|
||||
/**
|
||||
* {@link NacosAnnotationDrivenBeanDefinitionParser} Test
|
||||
|
@ -48,6 +49,27 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
|||
@ContextConfiguration(locations = { "classpath:/META-INF/nacos-context.xml" })
|
||||
public class NacosAnnotationDrivenBeanDefinitionParserTest {
|
||||
|
||||
@Autowired
|
||||
@Qualifier(NacosBeanUtils.GLOBAL_NACOS_PROPERTIES_BEAN_NAME)
|
||||
private Properties globalProperties;
|
||||
@Autowired
|
||||
@Qualifier(ApplicationContextHolder.BEAN_NAME)
|
||||
private ApplicationContextHolder applicationContextHolder;
|
||||
@Autowired
|
||||
@Qualifier(AnnotationNacosInjectedBeanPostProcessor.BEAN_NAME)
|
||||
private AnnotationNacosInjectedBeanPostProcessor annotationNacosInjectedBeanPostProcessor;
|
||||
@Autowired
|
||||
@Qualifier(NacosConfigurationPropertiesBindingPostProcessor.BEAN_NAME)
|
||||
private NacosConfigurationPropertiesBindingPostProcessor nacosConfigurationPropertiesBindingPostProcessor;
|
||||
@Autowired
|
||||
@Qualifier(NacosConfigListenerMethodProcessor.BEAN_NAME)
|
||||
private NacosConfigListenerMethodProcessor nacosConfigListenerMethodProcessor;
|
||||
@Autowired
|
||||
@Qualifier(NacosPropertySourcePostProcessor.BEAN_NAME)
|
||||
private NacosPropertySourcePostProcessor nacosPropertySourcePostProcessor;
|
||||
@NacosInjected
|
||||
private ConfigService configService;
|
||||
|
||||
@BeforeClass
|
||||
public static void init() {
|
||||
System.setProperty("nacos.server-addr", "127.0.0.1:8080");
|
||||
|
@ -58,33 +80,6 @@ public class NacosAnnotationDrivenBeanDefinitionParserTest {
|
|||
System.getProperties().remove("nacos.server-addr");
|
||||
}
|
||||
|
||||
@Autowired
|
||||
@Qualifier(NacosBeanUtils.GLOBAL_NACOS_PROPERTIES_BEAN_NAME)
|
||||
private Properties globalProperties;
|
||||
|
||||
@Autowired
|
||||
@Qualifier(ApplicationContextHolder.BEAN_NAME)
|
||||
private ApplicationContextHolder applicationContextHolder;
|
||||
|
||||
@Autowired
|
||||
@Qualifier(AnnotationNacosInjectedBeanPostProcessor.BEAN_NAME)
|
||||
private AnnotationNacosInjectedBeanPostProcessor annotationNacosInjectedBeanPostProcessor;
|
||||
|
||||
@Autowired
|
||||
@Qualifier(NacosConfigurationPropertiesBindingPostProcessor.BEAN_NAME)
|
||||
private NacosConfigurationPropertiesBindingPostProcessor nacosConfigurationPropertiesBindingPostProcessor;
|
||||
|
||||
@Autowired
|
||||
@Qualifier(NacosConfigListenerMethodProcessor.BEAN_NAME)
|
||||
private NacosConfigListenerMethodProcessor nacosConfigListenerMethodProcessor;
|
||||
|
||||
@Autowired
|
||||
@Qualifier(NacosPropertySourcePostProcessor.BEAN_NAME)
|
||||
private NacosPropertySourcePostProcessor nacosPropertySourcePostProcessor;
|
||||
|
||||
@NacosInjected
|
||||
private ConfigService configService;
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
Assert.assertNotNull(globalProperties);
|
||||
|
|
|
@ -16,16 +16,19 @@
|
|||
*/
|
||||
package com.alibaba.nacos.spring.context.config.xml;
|
||||
|
||||
import static com.alibaba.nacos.api.common.Constants.DEFAULT_GROUP;
|
||||
import static com.alibaba.nacos.embedded.web.server.NacosConfigHttpHandler.CONTENT_PARAM_NAME;
|
||||
import static com.alibaba.nacos.embedded.web.server.NacosConfigHttpHandler.DATA_ID_PARAM_NAME;
|
||||
import static com.alibaba.nacos.embedded.web.server.NacosConfigHttpHandler.GROUP_ID_PARAM_NAME;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import com.alibaba.nacos.embedded.web.server.EmbeddedNacosHttpServer;
|
||||
import com.alibaba.nacos.spring.test.AbstractNacosHttpServerTestExecutionListener;
|
||||
import com.alibaba.nacos.spring.test.User;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Assert;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
|
@ -34,10 +37,10 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
|||
import org.springframework.test.context.support.DependencyInjectionTestExecutionListener;
|
||||
import org.springframework.test.context.support.DirtiesContextTestExecutionListener;
|
||||
|
||||
import static com.alibaba.nacos.api.common.Constants.DEFAULT_GROUP;
|
||||
import static com.alibaba.nacos.embedded.web.server.NacosConfigHttpHandler.CONTENT_PARAM_NAME;
|
||||
import static com.alibaba.nacos.embedded.web.server.NacosConfigHttpHandler.DATA_ID_PARAM_NAME;
|
||||
import static com.alibaba.nacos.embedded.web.server.NacosConfigHttpHandler.GROUP_ID_PARAM_NAME;
|
||||
import com.alibaba.nacos.embedded.web.server.EmbeddedNacosHttpServer;
|
||||
import com.alibaba.nacos.spring.test.AbstractNacosHttpServerTestExecutionListener;
|
||||
import com.alibaba.nacos.spring.test.User;
|
||||
import com.alibaba.nacos.spring.util.NacosUtils;
|
||||
|
||||
/**
|
||||
* {@link NacosPropertySourceBeanDefinitionParser} Test
|
||||
|
@ -59,6 +62,8 @@ public class NacosPropertySourceBeanDefinitionParserTest
|
|||
|
||||
private static final Long USER_ID = 1991L;
|
||||
private static final String USER_NAME = "hxy";
|
||||
@Autowired
|
||||
private User user;
|
||||
|
||||
@Override
|
||||
protected void init(EmbeddedNacosHttpServer server) {
|
||||
|
@ -74,9 +79,6 @@ public class NacosPropertySourceBeanDefinitionParserTest
|
|||
return "nacos.server-addr";
|
||||
}
|
||||
|
||||
@Autowired
|
||||
private User user;
|
||||
|
||||
@Test
|
||||
public void testGetConfig() {
|
||||
Assert.assertEquals(USER_ID, user.getId());
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
*
|
||||
* * Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* * contributor license agreements. See the NOTICE file distributed with
|
||||
* * this work for additional information regarding copyright ownership.
|
||||
* * The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* * (the "License"); you may not use this file except in compliance with
|
||||
* * the License. You may obtain a copy of the License at
|
||||
* *
|
||||
* * http://www.apache.org/licenses/LICENSE-2.0
|
||||
* *
|
||||
* * Unless required by applicable law or agreed to in writing, software
|
||||
* * distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* * See the License for the specific language governing permissions and
|
||||
* * limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.spring.context.config.xml;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* {@link NacosPropertySourceXmlBeanDefinition} Test
|
||||
* @author SuperZ1999
|
||||
* @date 2023/9/28
|
||||
*/
|
||||
public class NacosPropertySourceXmlBeanDefinitionTest {
|
||||
@Test
|
||||
public void test() {
|
||||
NacosPropertySourceXmlBeanDefinition beanDefinition = new NacosPropertySourceXmlBeanDefinition();
|
||||
Assert.assertNotNull(beanDefinition);
|
||||
}
|
||||
}
|
|
@ -16,28 +16,28 @@
|
|||
*/
|
||||
package com.alibaba.nacos.spring.context.event.config;
|
||||
|
||||
import static com.alibaba.nacos.spring.test.MockConfigService.TIMEOUT_ERROR_MESSAGE;
|
||||
import static com.alibaba.nacos.spring.test.MockNacosServiceFactory.CONTENT;
|
||||
import static com.alibaba.nacos.spring.test.MockNacosServiceFactory.DATA_ID;
|
||||
import static com.alibaba.nacos.spring.test.MockNacosServiceFactory.GROUP_ID;
|
||||
|
||||
import java.util.Properties;
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.context.ApplicationListener;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.context.support.GenericApplicationContext;
|
||||
|
||||
import com.alibaba.nacos.api.config.ConfigService;
|
||||
import com.alibaba.nacos.api.config.listener.AbstractListener;
|
||||
import com.alibaba.nacos.api.config.listener.Listener;
|
||||
import com.alibaba.nacos.api.exception.NacosException;
|
||||
import com.alibaba.nacos.spring.metadata.NacosServiceMetaData;
|
||||
import com.alibaba.nacos.spring.test.MockConfigService;
|
||||
import org.junit.After;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.context.ApplicationListener;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.context.support.GenericApplicationContext;
|
||||
|
||||
import static com.alibaba.nacos.spring.test.MockConfigService.TIMEOUT_ERROR_MESSAGE;
|
||||
import static com.alibaba.nacos.spring.test.MockNacosServiceFactory.CONTENT;
|
||||
import static com.alibaba.nacos.spring.test.MockNacosServiceFactory.DATA_ID;
|
||||
import static com.alibaba.nacos.spring.test.MockNacosServiceFactory.GROUP_ID;
|
||||
|
||||
/**
|
||||
* {@link EventPublishingConfigService} Test
|
||||
|
|
|
@ -16,17 +16,18 @@
|
|||
*/
|
||||
package com.alibaba.nacos.spring.context.event.config;
|
||||
|
||||
import static com.alibaba.nacos.spring.context.annotation.config.NacosPropertySourceTest.DATA_ID;
|
||||
import static com.alibaba.nacos.spring.test.MockNacosServiceFactory.GROUP_ID;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.alibaba.nacos.api.config.ConfigService;
|
||||
import com.alibaba.nacos.api.config.listener.Listener;
|
||||
import com.alibaba.nacos.api.exception.NacosException;
|
||||
import com.alibaba.nacos.spring.test.MockConfigService;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import static com.alibaba.nacos.spring.context.annotation.config.NacosPropertySourceTest.DATA_ID;
|
||||
import static com.alibaba.nacos.spring.test.MockNacosServiceFactory.GROUP_ID;
|
||||
|
||||
/**
|
||||
* {@link TimeoutNacosConfigListener} Test
|
||||
|
@ -38,6 +39,19 @@ public class TimeoutNacosConfigListenerTest {
|
|||
|
||||
private final ConfigService configService = new MockConfigService();
|
||||
|
||||
private static void doWait(long millis) {
|
||||
|
||||
long startTime = System.currentTimeMillis();
|
||||
|
||||
while (true) {
|
||||
long costTime = System.currentTimeMillis() - startTime;
|
||||
if (costTime > millis) {
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private String receiveConfig(final long executionTime, long timeout, String content)
|
||||
throws NacosException {
|
||||
|
||||
|
@ -80,17 +94,4 @@ public class TimeoutNacosConfigListenerTest {
|
|||
|
||||
}
|
||||
|
||||
private static void doWait(long millis) {
|
||||
|
||||
long startTime = System.currentTimeMillis();
|
||||
|
||||
while (true) {
|
||||
long costTime = System.currentTimeMillis() - startTime;
|
||||
if (costTime > millis) {
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,107 @@
|
|||
package com.alibaba.nacos.spring.context.properties.config;
|
||||
|
||||
import com.alibaba.nacos.api.annotation.NacosInjected;
|
||||
import com.alibaba.nacos.api.annotation.NacosProperties;
|
||||
import com.alibaba.nacos.api.config.ConfigService;
|
||||
import com.alibaba.nacos.api.config.ConfigType;
|
||||
import com.alibaba.nacos.api.config.annotation.NacosConfigurationProperties;
|
||||
import com.alibaba.nacos.api.config.annotation.NacosValue;
|
||||
import com.alibaba.nacos.api.exception.NacosException;
|
||||
import com.alibaba.nacos.embedded.web.server.EmbeddedNacosHttpServer;
|
||||
import com.alibaba.nacos.spring.context.annotation.EnableNacos;
|
||||
import com.alibaba.nacos.spring.context.annotation.config.NacosPropertySource;
|
||||
import com.alibaba.nacos.spring.context.annotation.config.NacosPropertySources;
|
||||
import com.alibaba.nacos.spring.test.AbstractNacosHttpServerTestExecutionListener;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.TestExecutionListeners;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.test.context.support.DependencyInjectionTestExecutionListener;
|
||||
import org.springframework.test.context.support.DirtiesContextTestExecutionListener;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static com.alibaba.nacos.api.common.Constants.DEFAULT_GROUP;
|
||||
import static com.alibaba.nacos.embedded.web.server.NacosConfigHttpHandler.CONTENT_PARAM_NAME;
|
||||
import static com.alibaba.nacos.embedded.web.server.NacosConfigHttpHandler.DATA_ID_PARAM_NAME;
|
||||
import static com.alibaba.nacos.embedded.web.server.NacosConfigHttpHandler.GROUP_ID_PARAM_NAME;
|
||||
|
||||
/**
|
||||
* Chinese in test configuration.
|
||||
*
|
||||
* @author klw(213539 @ qq.com)
|
||||
* @date 2021/4/13 14:14
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration(classes = {ChineseConfigTest.class})
|
||||
@TestExecutionListeners({ DependencyInjectionTestExecutionListener.class,
|
||||
DirtiesContextTestExecutionListener.class, ChineseConfigTest.class })
|
||||
@NacosPropertySources(value = { @NacosPropertySource(dataId = ChineseConfigTest.DATA_ID, autoRefreshed = true) })
|
||||
@EnableNacos(globalProperties = @NacosProperties(serverAddr = "${server.addr}", enableRemoteSyncConfig = "true", maxRetry = "5", configRetryTime = "2600", configLongPollTimeout = "26000"))
|
||||
@Component
|
||||
public class ChineseConfigTest extends AbstractNacosHttpServerTestExecutionListener {
|
||||
|
||||
public static final String DATA_ID = "chinese-config-test";
|
||||
|
||||
private static final String LINE_SEPARATOR = System.getProperty("line.separator");
|
||||
|
||||
private static final String CH1_VALUE= "测试111";
|
||||
|
||||
private static final String CH2_VALUE= "测试222";
|
||||
|
||||
@NacosInjected
|
||||
private ConfigService configService;
|
||||
|
||||
@Autowired
|
||||
private CfgBean cfgBean;
|
||||
|
||||
@Bean
|
||||
public CfgBean cfgBean() {
|
||||
return new CfgBean();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValue() throws InterruptedException, NacosException {
|
||||
configService.publishConfig(DATA_ID, DEFAULT_GROUP, "cfg.ch1=" + CH1_VALUE + LINE_SEPARATOR
|
||||
+ "cfg.ch2=" + CH2_VALUE);
|
||||
|
||||
Thread.sleep(1000);
|
||||
|
||||
Assert.assertEquals(CH1_VALUE, cfgBean.ch1);
|
||||
Assert.assertEquals(CH2_VALUE, cfgBean.ch2);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(EmbeddedNacosHttpServer httpServer) {
|
||||
Map<String, String> config = new HashMap<String, String>(1);
|
||||
config.put(DATA_ID_PARAM_NAME, DATA_ID);
|
||||
config.put(GROUP_ID_PARAM_NAME, DEFAULT_GROUP);
|
||||
|
||||
config.put(CONTENT_PARAM_NAME, "cfg.ch1=测试1" + LINE_SEPARATOR
|
||||
+ "cfg.ch2=测试2");
|
||||
httpServer.initConfig(config);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getServerAddressPropertyName() {
|
||||
return "server.addr";
|
||||
}
|
||||
|
||||
@NacosConfigurationProperties(dataId = DATA_ID, autoRefreshed = true, type = ConfigType.PROPERTIES)
|
||||
public class CfgBean {
|
||||
|
||||
@NacosValue(value = "${cfg.ch1:中文1}", autoRefreshed = true)
|
||||
private String ch1;
|
||||
|
||||
@NacosValue(value = "${cfg.ch2:中文2}", autoRefreshed = true)
|
||||
private String ch2;
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,79 @@
|
|||
/*
|
||||
*
|
||||
* * Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* * contributor license agreements. See the NOTICE file distributed with
|
||||
* * this work for additional information regarding copyright ownership.
|
||||
* * The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* * (the "License"); you may not use this file except in compliance with
|
||||
* * the License. You may obtain a copy of the License at
|
||||
* *
|
||||
* * http://www.apache.org/licenses/LICENSE-2.0
|
||||
* *
|
||||
* * Unless required by applicable law or agreed to in writing, software
|
||||
* * distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* * See the License for the specific language governing permissions and
|
||||
* * limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.spring.context.properties.config;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.springframework.beans.MutablePropertyValues;
|
||||
import org.springframework.validation.BindException;
|
||||
import org.springframework.validation.DataBinder;
|
||||
|
||||
/**
|
||||
* {@link DataBinder} Test
|
||||
* @author SuperZ1999
|
||||
* @date 2023/9/28
|
||||
*/
|
||||
public class DataBinderTest {
|
||||
@Test
|
||||
public void test() throws BindException {
|
||||
People people = new People();
|
||||
MutablePropertyValues propertyValues = new MutablePropertyValues();
|
||||
propertyValues.add("name", "SuperZ1999");
|
||||
propertyValues.add("age", 24);
|
||||
DataBinder dataBinder = new DataBinder(people);
|
||||
dataBinder.setAutoGrowNestedPaths(false);
|
||||
dataBinder.setIgnoreInvalidFields(false);
|
||||
dataBinder.setIgnoreUnknownFields(true);
|
||||
dataBinder.bind(propertyValues);
|
||||
dataBinder.close();
|
||||
|
||||
Assert.assertEquals("SuperZ1999", people.getName());
|
||||
Assert.assertEquals(24, people.getAge());
|
||||
}
|
||||
|
||||
static class People {
|
||||
private String name;
|
||||
private int age;
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public int getAge() {
|
||||
return age;
|
||||
}
|
||||
|
||||
public void setAge(int age) {
|
||||
this.age = age;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "People{" +
|
||||
"name='" + name + '\'' +
|
||||
", age=" + age +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
}
|
|
@ -16,17 +16,16 @@
|
|||
*/
|
||||
package com.alibaba.nacos.spring.context.properties.config;
|
||||
|
||||
import com.alibaba.nacos.api.annotation.NacosInjected;
|
||||
import com.alibaba.nacos.api.annotation.NacosProperties;
|
||||
import com.alibaba.nacos.api.config.ConfigService;
|
||||
import com.alibaba.nacos.api.exception.NacosException;
|
||||
import com.alibaba.nacos.spring.context.annotation.EnableNacos;
|
||||
import com.alibaba.nacos.spring.test.AbstractNacosHttpServerTestExecutionListener;
|
||||
import com.alibaba.nacos.spring.test.Config;
|
||||
import static com.alibaba.nacos.spring.test.MockNacosServiceFactory.DATA_ID;
|
||||
import static com.alibaba.nacos.spring.test.MockNacosServiceFactory.GROUP_ID;
|
||||
import static com.alibaba.nacos.spring.test.TestConfiguration.MODIFIED_TEST_CONTEXT;
|
||||
import static com.alibaba.nacos.spring.test.TestConfiguration.TEST_CONFIG;
|
||||
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Assert;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
|
@ -35,10 +34,14 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
|||
import org.springframework.test.context.support.DependencyInjectionTestExecutionListener;
|
||||
import org.springframework.test.context.support.DirtiesContextTestExecutionListener;
|
||||
|
||||
import static com.alibaba.nacos.spring.test.MockNacosServiceFactory.DATA_ID;
|
||||
import static com.alibaba.nacos.spring.test.MockNacosServiceFactory.GROUP_ID;
|
||||
import static com.alibaba.nacos.spring.test.TestConfiguration.MODIFIED_TEST_CONTEXT;
|
||||
import static com.alibaba.nacos.spring.test.TestConfiguration.TEST_CONFIG;
|
||||
import com.alibaba.nacos.api.annotation.NacosInjected;
|
||||
import com.alibaba.nacos.api.annotation.NacosProperties;
|
||||
import com.alibaba.nacos.api.config.ConfigService;
|
||||
import com.alibaba.nacos.api.exception.NacosException;
|
||||
import com.alibaba.nacos.spring.context.annotation.EnableNacos;
|
||||
import com.alibaba.nacos.spring.test.AbstractNacosHttpServerTestExecutionListener;
|
||||
import com.alibaba.nacos.spring.test.Config;
|
||||
import com.alibaba.nacos.spring.util.NacosUtils;
|
||||
|
||||
/**
|
||||
* {@link NacosConfigurationPropertiesBindingPostProcessor} Test
|
||||
|
@ -58,7 +61,6 @@ public class NacosConfigurationPropertiesBindingPostProcessorTest
|
|||
|
||||
@Autowired
|
||||
private Config config;
|
||||
|
||||
@NacosInjected
|
||||
private ConfigService configService;
|
||||
|
||||
|
|
|
@ -14,14 +14,15 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.spring.convert.converter.config;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.nacos.api.config.convert.NacosConfigConverter;
|
||||
import com.alibaba.nacos.common.utils.JacksonUtils;
|
||||
import com.alibaba.nacos.spring.test.User;
|
||||
|
||||
/**
|
||||
* {@link User} {@link NacosConfigConverter}
|
||||
* {@link User} {@link NacosConfigConverter}.
|
||||
*
|
||||
* @author <a href="mailto:mercyblitz@gmail.com">Mercy</a>
|
||||
* @since 0.1.0
|
||||
|
@ -34,7 +35,8 @@ public class UserNacosConfigConverter implements NacosConfigConverter<User> {
|
|||
}
|
||||
|
||||
@Override
|
||||
|
||||
public User convert(String source) {
|
||||
return JSON.parseObject(source, User.class);
|
||||
return JacksonUtils.toObj(source, User.class);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,10 +16,26 @@
|
|||
*/
|
||||
package com.alibaba.nacos.spring.factory;
|
||||
|
||||
import static com.alibaba.nacos.spring.util.NacosBeanUtils.NACOS_CONFIG_LISTENER_EXECUTOR_BEAN_NAME;
|
||||
|
||||
import java.util.Properties;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.TestExecutionListeners;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.test.context.support.DependencyInjectionTestExecutionListener;
|
||||
import org.springframework.test.context.support.DirtiesContextTestExecutionListener;
|
||||
|
||||
import com.alibaba.nacos.api.PropertyKeyConst;
|
||||
import com.alibaba.nacos.api.annotation.NacosProperties;
|
||||
import com.alibaba.nacos.api.config.ConfigService;
|
||||
|
@ -28,20 +44,7 @@ import com.alibaba.nacos.api.naming.NamingMaintainService;
|
|||
import com.alibaba.nacos.api.naming.NamingService;
|
||||
import com.alibaba.nacos.spring.context.annotation.EnableNacos;
|
||||
import com.alibaba.nacos.spring.test.AbstractNacosHttpServerTestExecutionListener;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.TestExecutionListeners;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.test.context.support.DependencyInjectionTestExecutionListener;
|
||||
import org.springframework.test.context.support.DirtiesContextTestExecutionListener;
|
||||
|
||||
import static com.alibaba.nacos.spring.util.NacosBeanUtils.NACOS_CONFIG_LISTENER_EXECUTOR_BEAN_NAME;
|
||||
import com.alibaba.nacos.spring.util.NacosUtils;
|
||||
|
||||
/**
|
||||
* {@link CacheableEventPublishingNacosServiceFactory} Test
|
||||
|
@ -59,16 +62,15 @@ import static com.alibaba.nacos.spring.util.NacosBeanUtils.NACOS_CONFIG_LISTENER
|
|||
public class CacheableEventPublishingNacosServiceFactoryTest
|
||||
extends AbstractNacosHttpServerTestExecutionListener {
|
||||
|
||||
@Autowired
|
||||
private NacosServiceFactory nacosServiceFactory;
|
||||
private Properties properties = new Properties();
|
||||
|
||||
@Bean(name = NACOS_CONFIG_LISTENER_EXECUTOR_BEAN_NAME)
|
||||
public static ExecutorService executorService() {
|
||||
return Executors.newSingleThreadExecutor();
|
||||
}
|
||||
|
||||
@Autowired
|
||||
private NacosServiceFactory nacosServiceFactory;
|
||||
|
||||
private Properties properties = new Properties();
|
||||
|
||||
@Before
|
||||
public void init() {
|
||||
properties.setProperty(PropertyKeyConst.SERVER_ADDR, "127.0.0.1");
|
||||
|
|
|
@ -16,25 +16,25 @@
|
|||
*/
|
||||
package com.alibaba.nacos.spring.factory;
|
||||
|
||||
import static com.alibaba.nacos.spring.util.NacosBeanUtils.NACOS_CONFIG_LISTENER_EXECUTOR_BEAN_NAME;
|
||||
|
||||
import java.util.Properties;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
import com.alibaba.nacos.api.PropertyKeyConst;
|
||||
import com.alibaba.nacos.api.config.ConfigService;
|
||||
import com.alibaba.nacos.api.exception.NacosException;
|
||||
import com.alibaba.nacos.api.naming.NamingService;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
import static com.alibaba.nacos.spring.util.NacosBeanUtils.NACOS_CONFIG_LISTENER_EXECUTOR_BEAN_NAME;
|
||||
import com.alibaba.nacos.api.PropertyKeyConst;
|
||||
import com.alibaba.nacos.api.config.ConfigService;
|
||||
import com.alibaba.nacos.api.exception.NacosException;
|
||||
import com.alibaba.nacos.api.naming.NamingService;
|
||||
|
||||
/**
|
||||
* CacheableEventPublishingNacosServiceFactory Test
|
||||
|
@ -47,18 +47,16 @@ import static com.alibaba.nacos.spring.util.NacosBeanUtils.NACOS_CONFIG_LISTENER
|
|||
CacheableNacosInjectedFactoryTest.class })
|
||||
public class CacheableNacosInjectedFactoryTest {
|
||||
|
||||
@Autowired
|
||||
private CacheableEventPublishingNacosServiceFactory nacosServiceFactory;
|
||||
private Properties properties = new Properties();
|
||||
private Properties properties2 = new Properties();
|
||||
|
||||
@Bean(name = NACOS_CONFIG_LISTENER_EXECUTOR_BEAN_NAME)
|
||||
public static ExecutorService executorService() {
|
||||
return Executors.newSingleThreadExecutor();
|
||||
}
|
||||
|
||||
@Autowired
|
||||
private CacheableEventPublishingNacosServiceFactory nacosServiceFactory;
|
||||
|
||||
private Properties properties = new Properties();
|
||||
|
||||
private Properties properties2 = new Properties();
|
||||
|
||||
@Before
|
||||
public void init() {
|
||||
properties.setProperty(PropertyKeyConst.NAMESPACE, "nc");
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
*
|
||||
* * Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* * contributor license agreements. See the NOTICE file distributed with
|
||||
* * this work for additional information regarding copyright ownership.
|
||||
* * The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* * (the "License"); you may not use this file except in compliance with
|
||||
* * the License. You may obtain a copy of the License at
|
||||
* *
|
||||
* * http://www.apache.org/licenses/LICENSE-2.0
|
||||
* *
|
||||
* * Unless required by applicable law or agreed to in writing, software
|
||||
* * distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* * See the License for the specific language governing permissions and
|
||||
* * limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.spring.factory;
|
||||
|
||||
import com.alibaba.nacos.api.exception.NacosException;
|
||||
import com.alibaba.nacos.api.naming.pojo.Service;
|
||||
import com.alibaba.nacos.client.naming.NacosNamingMaintainService;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* {@link DelegatingNamingMaintainService} Test
|
||||
* @author SuperZ1999
|
||||
* @date 2023/9/28
|
||||
*/
|
||||
public class DelegatingNamingMaintainServiceTest {
|
||||
@Test
|
||||
public void testNamingMaintainService() throws NacosException {
|
||||
NacosNamingMaintainService namingMaintainService = new NacosNamingMaintainService("127.0.0.1:8848");
|
||||
Service service = namingMaintainService.queryService("example");
|
||||
Assert.assertNotNull(service);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
*
|
||||
* * Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* * contributor license agreements. See the NOTICE file distributed with
|
||||
* * this work for additional information regarding copyright ownership.
|
||||
* * The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* * (the "License"); you may not use this file except in compliance with
|
||||
* * the License. You may obtain a copy of the License at
|
||||
* *
|
||||
* * http://www.apache.org/licenses/LICENSE-2.0
|
||||
* *
|
||||
* * Unless required by applicable law or agreed to in writing, software
|
||||
* * distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* * See the License for the specific language governing permissions and
|
||||
* * limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.spring.factory;
|
||||
|
||||
import com.alibaba.nacos.api.exception.NacosException;
|
||||
import com.alibaba.nacos.api.naming.pojo.Instance;
|
||||
import com.alibaba.nacos.client.naming.NacosNamingService;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* {@link DelegatingNamingService} Test
|
||||
* @author SuperZ1999
|
||||
* @date 2023/9/28
|
||||
*/
|
||||
public class DelegatingNamingServiceTest {
|
||||
@Test
|
||||
public void testNamingService() throws NacosException {
|
||||
NacosNamingService nacosNamingService = new NacosNamingService("127.0.0.1:8848");
|
||||
List<Instance> instances = nacosNamingService.getAllInstances("example");
|
||||
System.out.println(instances);
|
||||
Assert.assertNotNull(instances);
|
||||
}
|
||||
}
|
|
@ -16,13 +16,13 @@
|
|||
*/
|
||||
package com.alibaba.nacos.spring.test;
|
||||
|
||||
import com.alibaba.nacos.api.annotation.NacosProperties;
|
||||
import com.alibaba.nacos.embedded.web.server.EmbeddedNacosHttpServer;
|
||||
|
||||
import org.springframework.test.context.TestContext;
|
||||
import org.springframework.test.context.TestExecutionListener;
|
||||
import org.springframework.test.context.support.AbstractTestExecutionListener;
|
||||
|
||||
import com.alibaba.nacos.api.annotation.NacosProperties;
|
||||
import com.alibaba.nacos.embedded.web.server.EmbeddedNacosHttpServer;
|
||||
|
||||
/**
|
||||
* Abstract Nacos HTTP Server {@link TestExecutionListener}
|
||||
*
|
||||
|
@ -32,12 +32,12 @@ import org.springframework.test.context.support.AbstractTestExecutionListener;
|
|||
public abstract class AbstractNacosHttpServerTestExecutionListener
|
||||
extends AbstractTestExecutionListener {
|
||||
|
||||
private EmbeddedNacosHttpServer httpServer;
|
||||
|
||||
static {
|
||||
System.setProperty("nacos.standalone", "true");
|
||||
}
|
||||
|
||||
private EmbeddedNacosHttpServer httpServer;
|
||||
|
||||
@Override
|
||||
public void beforeTestClass(TestContext testContext) throws Exception {
|
||||
initEnvironment(testContext);
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue