Compare commits

...

87 Commits

Author SHA1 Message Date
胡俊 08657b90b3
fix #https://github.com/alibaba/nacos/issues/12478 (#344) 2024-11-04 09:26:54 +08:00
Lemon eaf15a6e6e
Fix using dataids field causes NullPointerException (#321) 2023-12-29 20:49:09 +08:00
胡俊 5a97a9dd6b
2.1.0-RC 2023-12-06 17:21:07 +08:00
胡俊 6c29062a1c
0.3.0-RC 2023-12-03 13:31:58 +08:00
胡俊 a5aa9f70bb
Summer ospp#10375 (#312)
* [ISSUE #10375] Support springboot3 and native-image (#306)

* [ISSUE #10375] Support SpringBoot3

* [ISSUE #10375] Support native-image

* [ISSUE #10375] Update document and add AOT sample (#307)

Update document and add AOT sample

---------

Co-authored-by: SuperZ1999 <34301918+SuperZ1999@users.noreply.github.com>
2023-12-03 11:25:29 +08:00
胡俊 82caa209b3
add user guide link 2023-07-15 15:12:55 +08:00
Guocheng Tang 71db41f853
[ISSUE #293] Fixed yaml configuration not working (#293)
Fixed configuration not working
2023-07-06 20:23:14 +08:00
slatonwu a5ba72ac01
支持修改context-path (#290)
Co-authored-by: wuhui <wuhui@88.com>
2023-07-01 14:55:51 +08:00
slatonwu df0f68fcfa
增加 nacos.config.bootstrap.snapshot-enable 配置,用于关闭,开启是否保存快照 (#295)
Co-authored-by: wuhui <wuhui@88.com>
2023-07-01 14:54:53 +08:00
HPxianliru 7144598c21
1 solve startup project logger error,not set nacos.config.data-ids value #174 (#175) 2023-06-04 12:00:21 +08:00
chenhao26 c080c91c15
add some junit test (#262)
add some junit test
2022-08-15 19:25:31 +08:00
realJackSun 8b2621bc29
Add the <configuration> to fix the javadoc problem (#259) 2022-07-21 12:10:55 +08:00
realJackSun 6b626f364c Change to version 0.2.12 2022-07-21 11:39:10 +08:00
qyqcswill 6771d1b311
fix security issue of exposing ak ,sk in log print. (#257) 2022-07-21 10:54:22 +08:00
yanglulu 008ae0bce7
[ISSUE#226] yaml multi profiles support (#227)
* yaml multi profiles support

* add License

* yaml multi profiles support

* fix: more unit test
2022-06-30 16:52:49 +08:00
胡俊 a9d0ea104a
changer version to 0.2.11 (#250)
Co-authored-by: hujun3 <hujun3@xiaomi.com>
2022-06-24 13:00:17 +08:00
dependabot[bot] c682961079
chore(deps): bump junit from 4.12 to 4.13.1 in /nacos-spring-boot-parent (#235)
Bumps [junit](https://github.com/junit-team/junit4) from 4.12 to 4.13.1.
- [Release notes](https://github.com/junit-team/junit4/releases)
- [Changelog](https://github.com/junit-team/junit4/blob/main/doc/ReleaseNotes4.12.md)
- [Commits](https://github.com/junit-team/junit4/compare/r4.12...r4.13.1)

---
updated-dependencies:
- dependency-name: junit:junit
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-05-28 14:19:53 +08:00
dependabot[bot] af106fc5da
chore(deps): bump spring-boot-starter-web (#236)
Bumps [spring-boot-starter-web](https://github.com/spring-projects/spring-boot) from 2.1.6.RELEASE to 2.5.12.
- [Release notes](https://github.com/spring-projects/spring-boot/releases)
- [Commits](https://github.com/spring-projects/spring-boot/compare/v2.1.6.RELEASE...v2.5.12)

---
updated-dependencies:
- dependency-name: org.springframework.boot:spring-boot-starter-web
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-05-28 14:14:53 +08:00
Oliver 3e50f33fe7
Fix printing log style (#240) 2022-05-13 09:42:00 +08:00
liaochuntao b1a19f679f
Merge pull request #238 from hujun-w-2/fix_log_auto
[ISSUE#242]modify log overload method
2022-05-11 11:30:35 +08:00
realJackSun e5ada95281 Change version to 0.2.11-beta 2022-05-06 12:04:09 +08:00
liaochuntao 3ecc302443
Merge pull request #239 from Oliverwqcwrw/master-replace-deprecated-method-1
Replace deprecated method to officially recommended api
2022-04-30 11:26:08 +08:00
liaochuntao 04e84c2b42
Merge pull request #243 from chenhao26-nineteen/buildNacosProperties_method_enhance_readability
Increase method readability
2022-04-30 11:25:46 +08:00
hujun3 02236568b4 adapt test 2022-04-29 19:42:47 +08:00
hujun3 b6da64e902 modify log overload method 2022-04-29 14:34:53 +08:00
chaos f0cc777109 Increase method readability 2022-04-28 14:58:38 +08:00
hujun 35e9c3e7c1 dependency nacos-client 2.1.0 2022-04-28 09:54:44 +08:00
hujun 40035fa032 Merge remote-tracking branch 'origin/fix_log_auto' into fix_log_auto
# Conflicts:
#	nacos-config-spring-boot-autoconfigure/src/main/java/com/alibaba/boot/nacos/config/util/log/LogAutoFreshProcess.java
2022-04-27 23:54:56 +08:00
hujun 2d257777c2 Optimize configuration reset logic. 2022-04-27 23:52:51 +08:00
hujun3 f9efddfb44 Optimize configuration reset logic. 2022-04-27 23:28:57 +08:00
hujun ca9a90543a Optimize configuration reset logic. 2022-04-27 23:23:36 +08:00
hujun 979c01702d Optimize configuration reset logic. 2022-04-27 23:20:19 +08:00
hujun a09746f41e Optimize configuration reset logic. 2022-04-27 23:15:42 +08:00
Oliver bfecd49e33
Update modifiers order (#241) 2022-04-26 09:59:28 +08:00
hujun3 cd810f4d25 启动依然沿用springboot 2022-04-25 13:31:41 +08:00
hujun3 aec14871ca fix nacos logs bug 2022-04-25 13:00:43 +08:00
Oliver 9a27a58a00 Replace deprecated method to officially recommended api 2022-04-25 10:33:14 +08:00
hujun3 e725f83cdc fix nacos logs bug 2022-04-24 14:34:40 +08:00
hujun3 d1575460b8 fix nacos logs bug 2022-04-22 22:25:38 +08:00
hujun3 b2649223da fix nacos logs bug 2022-04-22 22:11:30 +08:00
hujun3 1ef681c7d6 fix nacos logs bug 2022-04-22 21:47:48 +08:00
胡俊 e54e0cdd0d
Feature change version (#234)
* change springboot version

* change springboot version

Co-authored-by: hujun3 <hujun3@xiaomi.com>
2022-03-21 17:47:15 +08:00
胡俊 a8d6a80dd8
[ISSUEhttps://github.com/alibaba/nacos/issues/6999]Managed log framework (#228)
* Managed log framework

* Managed log framework-update

* Managed log framework -update

Co-authored-by: hujun3 <hujun3@xiaomi.com>
2022-03-14 09:52:08 +08:00
liaochuntao dbde2edc24
Merge pull request #230 from onewe/fix/issue-229
[ISSUE#229] add config type default value
2022-03-10 21:45:25 +08:00
liaochuntao 147829ac05
Merge pull request #232 from shouyuwang/master
fix: nacos property arg bug
2022-03-07 14:30:10 +08:00
王守钰 a981cc9de9 fix nacos property arg bug 2022-03-04 22:45:52 +08:00
onewe 0bf34babc6 [ISSUE#229] add config type default value
Close#229
2022-02-18 10:29:27 +08:00
胡俊 3e70665970
[ISSUE#223]update nacos-client version #223 (#224)
* update nacos-client version #223

* .
2022-01-24 16:16:53 +08:00
liaochuntao f9c1d281ad
Merge pull request #225 from hujun-w-2/develop-bug#215
[ISSUE#215]fix bug(When a key is deleted from the map attribute of the configuration center, it is not actually deleted in the business system)
2022-01-21 12:02:05 +08:00
hujun 03ec22f997 fix bug#215 2022-01-16 13:11:14 +08:00
胡俊 ed5843c16b
Code optimization (#220)
Co-authored-by: hujun3 <Hujun123>
2021-12-13 16:00:27 +08:00
zhanyao f401521964
去除spring boot 2.4以上版本ConfigurationBeanFactoryMetadata不兼容代码 (#194) 2021-12-13 11:45:03 +08:00
realJackSun 1bdd5a2e1a
Upgrade to 0.2.10: upgrade the nacos-spring dependency to 1.1.1, nacos-client dependency version to 2.0.2 (#206) 2021-07-19 17:57:23 +08:00
yanlinly b2fb611d4c
Merge pull request #205 from realJackSun/0.2.8-bugfix
release 0.2.8-bugfix, Fix the thread-safety problem in NacosConfigurationPropertiesBinder
2021-07-15 01:44:06 +08:00
realJackSun b87a4136f0 Release 0.2.8-bugfix, upgrade the nacos-spring-project denpendency to 1.1.1, add synchronized in NacosBootConfigurationPropertiesBinder:doBind 2021-07-15 01:39:42 +08:00
realJackSun 1ffd948f90
Update Nacos-client dependency to 2.0.2 (#203) 2021-07-12 14:42:46 +08:00
realJackSun d363a2b86d
Change the version to 0.2.8 (#198) 2021-06-24 09:28:58 +08:00
JackSun-Developer 1285740ecf
Change the dependency nacos-client to 1.4.2 (#196) 2021-06-04 15:41:25 +08:00
JackSun-Developer d9086a3e1c
Change the version to 0.2.5 (#193) 2021-05-25 19:56:28 +08:00
邪影oO 6b50bc39df
Merge pull request #191 from JackSun-Developer/20210524_1725
[master] upgrade spring-nacos-context version to 1.1.0
2021-05-24 17:30:24 +08:00
JackSun-Developer 437f1e579a [master] upgrade spring-nacos-context version to 1.1.0 2021-05-24 17:17:17 +08:00
mai.jh 93641fbbc5
Add a reset Nacos Log Config listener. (#183)
* for: nacos issue#4567 ,Add a reset Nacos Log Config listener.

* Remove redundant dependency
2021-04-16 10:27:38 +08:00
dependabot[bot] 446278b767
chore(deps): bump log4j (#137)
Bumps log4j from 2.11.2 to 2.13.2.

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-04-15 16:16:39 +08:00
Xiaoshuang Li d77d02926d
fix default value (#173)
Co-authored-by: 李晓双 <lixiaoshuang@172-15-67-144.lightspeed.miamfl.sbcglobal.net>
2021-03-04 11:04:52 +08:00
shalk(xiao kun) 39efc09c56
Update NacosPropertiesBuilder.java (#178)
fix https://github.com/alibaba/nacos/issues/3845
2021-03-04 11:00:33 +08:00
邪影oO 8a89b5f1df
版本号由0.2.7升级到2.0.0 (#166)
* 版本号由0.2.7升级到2.0.0

* readme中增加版本号与spring boot对应关系
2020-12-07 12:43:35 +08:00
赵延 256a35cbd9
upgrade spring-nacos-context version to 1.0.0 (#155) 2020-11-23 10:57:05 +08:00
liaochuntao e9290b86b8
Merge pull request #116 from chuntaojun/feature_remote_first
Feature remote first
2020-03-17 13:39:35 +08:00
chuntaojun 9e20b30214 feat: support remote config Take precedence over local configuration 2020-03-17 13:34:59 +08:00
chuntaojun 6ce80631a7 refactor(config): Adjust the position 2020-03-16 18:15:02 +08:00
chuntaojun 7a762603b7 refactor(config): Remote configuration support has a higher priority than application.proprties 2020-03-16 17:57:03 +08:00
liaochuntao f4a6216bab
Update README.md 2020-03-09 21:07:57 +08:00
liaochuntao f887cf4870
Merge pull request #113 from chuntaojun/feature_auth_master
support nacos auth sys
2020-03-09 21:01:21 +08:00
chuntaojun fb58598ff1 fix: fix test bug 2020-03-09 20:57:41 +08:00
chuntaojun a759ddac7c feat: support nacos auth sys 2020-03-09 20:26:24 +08:00
chuntaojun a993a173ad refactor: update nacos-client version to 1.2.0 2020-03-09 20:17:39 +08:00
liaochuntao 7cb8a79bc4
Merge pull request #104 from ZShUn/master
1.添加username password参数
2020-03-09 18:16:20 +08:00
liaochuntao d48c075941
Merge pull request #111 from mayyamus/fix/log_info
增加toString()方法,解决打印日志时显示对象的内存地址
2020-03-07 22:30:01 +08:00
jh.ma 9d4ad10765 增加toString()方法,解决打印日志时显示对象的内存地址 2020-03-07 20:58:10 +08:00
ZShUn 246d3ba599 1.格式化代码 2020-02-11 14:58:29 +08:00
ZShUn 5ef932023c 1.修复nacos.config.bootstrap.enable=true时执行SecurityProxy.login方法username、password属性值未初始化问题 2020-02-11 14:42:12 +08:00
ZShUn 499785909f 1.移除NacosConfigProperties.Config.serverAddr默认值
2.添加NacosConfigProperties.Config username password属性
2020-02-11 12:44:11 +08:00
ZShUn e3c30a6d30 1.添加username password参数 2020-02-10 23:42:38 +08:00
liaochuntao 213755347a
Merge pull request #101 from ZShUn/master
1.取消NacosDiscoveryAutoDeregister和NacosDiscoveryAutoRegister中applicati…
2020-01-19 13:05:05 +08:00
ZShUn 1d8b73be35 Revert "1.删除eclipse配置文件"
This reverts commit fa0f5bf9
2020-01-19 12:36:37 +08:00
ZShUn fa0f5bf96a 1.删除eclipse配置文件 2020-01-18 23:07:34 +08:00
ZShUn dbd76289cd 1.取消NacosDiscoveryAutoDeregister和NacosDiscoveryAutoRegister中applicationName默认值
2.修复NacosDiscoveryAutoDeregister和NacosDiscoveryAutoRegister日志打印serviceName可能为空情况
3.修复nacos-discovery-example pom文件packaging配置问题
2020-01-18 23:05:54 +08:00
97 changed files with 8630 additions and 512 deletions

1
.gitignore vendored
View File

@ -30,3 +30,4 @@ hs_err_pid*
target
.DS_Store
.flattened-pom.xml

206
NACOS-AOT-QUICK-START.md Normal file
View File

@ -0,0 +1,206 @@
## Nacos AOT
### prerequisites
- GraalVM22.0+ (JDK17)
- native-image
- Nacos Server
If you haven't downloaded GraalVM, you can download it from [Download GraalVM](https://www.graalvm.org/downloads/).
If you don't have a native-image environment, you can configure according to [Native Image](https://www.graalvm.org/latest/reference-manual/native-image/).
You have to start a Nacos Server in backend , If you don't know steps, you can learn about [quick start](https://nacos.io/en-us/docs/quick-start.html).
### Quick Start
The complete code for this example can be found at: [`nacos-aot-sample`](nacos-spring-boot-samples/nacos-aot-sample)
1. Because SpringBoot2 does not support aot, you must specify SpringBoot as SpringBoot3 in dependency management:
```xml
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>3.0.6</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
```
2. You would add [`nacos-config-spring-boot-starter`](nacos-config-spring-boot-starter) or [`nacos-discovery-spring-boot-starter`](nacos-discovery-spring-boot-starter) in your Spring application's dependencies :
```xml
<dependencies>
<dependency>
<groupId>com.alibaba.boot</groupId>
<artifactId>nacos-config-spring-boot-starter</artifactId>
<version>${latest.version}</version>
</dependency>
<dependency>
<groupId>com.alibaba.boot</groupId>
<artifactId>nacos-discovery-spring-boot-starter</artifactId>
<version>${latest.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
```
3. In order to use the process-aot feature of SpringBoot and more conveniently compile native-image programs, we also need `spring-boot-maven-plugin` and `native-maven-plugin`:
```xml
<profiles>
<profile>
<id>native</id>
<build>
<plugins>
<plugin>
<groupId>org.graalvm.buildtools</groupId>
<artifactId>native-maven-plugin</artifactId>
<version>0.9.25</version>
<executions>
<execution>
<id>compile</id>
<goals>
<goal>compile</goal>
</goals>
</execution>
</executions>
<configuration>
<classesDirectory>${project.build.outputDirectory}</classesDirectory>
<mainClass>com.alibaba.boot.nacos.sample.AotApplication</mainClass>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<id>process-aot</id>
<goals>
<goal>process-aot</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
```
4. You could define some configurations in `application.properties`:
```properties
nacos.config.server-addr=localhost:8848
nacos.discovery.server-addr=localhost:8848
```
> `nacos.config.server-addr` and `nacos.discovery.server-addr` attribute configure "\${host}:${port}" of your Nacos Server
5. You could using `@SpringBootApplication` to annotate main class like normal SpringBoot Application and startup:
```java
@SpringBootApplication
@NacosPropertySource(dataId = "example", autoRefreshed = true)
public class AotApplication {
public static void main(String[] args) {
SpringApplication.run(AotApplication.class, args);
}
}
```
Note: `@NacosPropertySource` is used to specify the data-id of the configuration.
6. Let's try the functions of `@NacosInjected` and `@NacosValue`, for more usage, see [Nacos Spring Project](https://github.com/nacos-group/nacos-spring-project).
```java
@Controller
public class AotController {
@NacosInjected
private ConfigService configService;
@NacosInjected
private NamingService namingService;
@NacosValue(value = "${flag:false}", autoRefreshed = true)
private boolean flag;
@ResponseBody
@RequestMapping(value = "/config/get", method = GET)
public String getConfig() throws NacosException {
return configService.getConfig("example", "DEFAULT_GROUP", 5000);
}
@ResponseBody
@RequestMapping(value = "/naming/get", method = GET)
public List<Instance> getNaming(@RequestParam("serviceName") String serviceName) throws NacosException {
return namingService.getAllInstances(serviceName);
}
@ResponseBody
@RequestMapping(value = "/flag/get", method = GET)
public boolean getFlag() {
return flag;
}
}
```
7. Publish the configuration to the Nacos Server by calling the Nacos Open API, with dataId of example and content of `flag=true`
```shell
curl -X POST "http://127.0.0.1:8848/nacos/v1/cs/configs?dataId=example&group=DEFAULT_GROUP&content=flag=true"
```
8. Enable the tracing agent on the command line with the `java` command from the GraalVM JDK:
```shell
$JAVA_HOME/bin/java -agentlib:native-image-agent=config-output-dir=/path/to/config-dir/ ...
```
Note: For more information about tracing agent, see [Collect Metadata with the Tracing Agent](https://www.graalvm.org/latest/reference-manual/native-image/metadata/AutomaticMetadataCollection/).
9. Run the java program and follow the steps below to use the program:
1. Open `localhost:8080/config/get` with a browser, and the browser responds with `flag=true`.
2. Open `localhost:8080/flag/get` with a browser, and the browser responds with `true`.
3. Publish the configuration to the Nacos Server by calling the Nacos Open API, with dataId of example and content of `flag=false`
```shell
curl -X POST "http://127.0.0.1:8848/nacos/v1/cs/configs?dataId=example&group=DEFAULT_GROUP&content=flag=false"
```
4. Open `localhost:8080/flag/get` with a browser, and the browser responds with `false`.
5. Register a service named example with Nacos server by calling Nacos Open API.
```shell
curl -X POST 'http://127.0.0.1:8848/nacos/v1/ns/instance?serviceName=example&ip=127.0.0.1&port=8080'
```
6. Open `localhost:8080/naming/get?serviceName=example` with a browser, and the browser responds with information about the service you just registered.
10. Close the program and copy the file just generated to the `classpath:META-INF/native-image/` folder, The file path is specified in step 8.
Note: [`nacos-aot-sample`](nacos-spring-boot-samples/nacos-aot-sample) already includes these files, but you can still use the files you just generated.
11. Run the following command and you will find the compiled executable program in the `target` folder.
```shell
mvn -DskipTests=true clean package -Pnative
```
12. This executable program is what we want! Run the program and try step 9 again.
## Relative Projects
* [Alibaba Nacos](https://github.com/alibaba/nacos)
* [Alibaba Spring Context Support](https://github.com/alibaba/spring-context-support)
* [Nacos Spring Project](https://github.com/nacos-group/nacos-spring-project)
* [Nacos Spring Cloud Project](https://github.com/spring-cloud-incubator/spring-cloud-alibaba)

View File

@ -18,10 +18,10 @@ Suppose your Nacos Server is startup, you would add [`nacos-config-spring-boot-s
</dependencies>
```
Note: Version [0.2.x.RELEASE](https://mvnrepository.com/artifact/com.alibaba.boot/nacos-config-spring-boot-starter) is compatible with the Spring Boot 2.x. Version [0.1.x.RELEASE](https://mvnrepository.com/artifact/com.alibaba.boot/nacos-config-spring-boot-starter) is compatible with the Spring Boot 1.x.
Note: Version [0.2.x.RELEASE](https://mvnrepository.com/artifact/com.alibaba.boot/nacos-config-spring-boot-starter) is compatible with the Spring Boot 2.x and the Spring Boot 3.x. Version [0.1.x.RELEASE](https://mvnrepository.com/artifact/com.alibaba.boot/nacos-config-spring-boot-starter) is compatible with the Spring Boot 1.x.
After that, you could define some configurations in `application.properties`:
```properties
nacos.config.server-addr=localhost:8848
```
@ -98,7 +98,7 @@ Then Configure your endpoint security strategy.
management.security.enabled=false
```
* Spring Boot2.x
* Spring Boot2.x or Spring Boot3.x
```properties
management.endpoints.web.exposure.include=*
@ -107,7 +107,7 @@ management.endpoints.web.exposure.include=*
To view the endpoint information, visit the following URLS:
* Spring Boot1.x: URL is http://127.0.0.1:10011/nacos-config.
* Spring Boot2.x: URL is http://127.0.0.1:10011/actuator/nacos-config.
* Spring Boot2.x or Spring Boot3.x: URL is http://127.0.0.1:10011/actuator/nacos-config.
## Health Checks

View File

@ -18,10 +18,10 @@ Suppose your Nacos Server is startup, you would add [`nacos-discovery-spring-boo
</dependencies>
```
Note: Version [0.2.x.RELEASE](https://mvnrepository.com/artifact/com.alibaba.boot/nacos-discovery-spring-boot-starter) is compatible with the Spring Boot 2.x. Version [0.1.x.RELEASE](https://mvnrepository.com/artifact/com.alibaba.boot/nacos-discovery-spring-boot-starter) is compatible with the Spring Boot 1.x.
Note: Version [0.2.x.RELEASE](https://mvnrepository.com/artifact/com.alibaba.boot/nacos-discovery-spring-boot-starter) is compatible with the Spring Boot 2.x and the Spring Boot 3.x. Version [0.1.x.RELEASE](https://mvnrepository.com/artifact/com.alibaba.boot/nacos-discovery-spring-boot-starter) is compatible with the Spring Boot 1.x.
After that, you could define some configurations in `application.properties`:
```properties
nacos.discovery.server-addr=localhost:8848
```
@ -93,7 +93,7 @@ Then Configure your endpoint security strategy.
management.security.enabled=false
```
* Spring Boot2.x
* Spring Boot2.x or Spring Boot3.x
```properties
management.endpoints.web.exposure.include=*
@ -102,7 +102,7 @@ management.endpoints.web.exposure.include=*
To view the endpoint information, visit the following URLS:
* Spring Boot1.x: URL is http://127.0.0.1:10012/nacos-discovery.
* Spring Boot2.x: URL is http://127.0.0.1:10012/actuator/nacos-discovery.
* Spring Boot2.x or Spring Boot3.x: URL is http://127.0.0.1:10012/actuator/nacos-discovery.
## Health Checks

View File

@ -18,30 +18,33 @@ Nacos Spring Boot Project consist of two parts: `nacos-config-spring-boot` and `
`nacos-discovery-spring-boot` module is using for Service Discovery, Service Health Check and Dynamic DNS Service.
Additionally, Nacos Spring Boot Project already supports native-image.
## Samples
- [Nacos Config Sample](https://github.com/nacos-group/nacos-spring-boot-project/tree/master/nacos-spring-boot-samples/nacos-config-sample)
- [Nacos Discovery Sample](https://github.com/nacos-group/nacos-spring-boot-project/tree/master/nacos-spring-boot-samples/nacos-discovery-sample)
- [Nacos AOT Sample](https://github.com/nacos-group/nacos-spring-boot-project/tree/master/nacos-spring-boot-samples/nacos-aot-sample)
## Dependencies & Compatibility
**master branch**
**Version: 0.2.x / 2.x.x ( branch master )**
| Dependencies | Compatibility |
| -------------- | ------------- |
| Java | 1.8+ |
| Spring Boot | 2.0.3.RELEASE |
| Nacos-Spring-Context | 0.3.4 |
| Nacos-Spring-Context | 1.1.0 |
**1.x branch**
**Version: 0.1.x / 1.x.x ( branch: 1.x )**
| Dependencies | Compatibility |
| -------------- | ------------- |
| Java | 1.7+ |
| Spring Boot | 1.4.1.RELEASE |
| Nacos-Spring-Context | 0.3.4 |
| Nacos-Spring-Context | 1.1.0 |
## Quick Start
@ -51,9 +54,12 @@ Nacos Spring Boot Project consist of two parts: `nacos-config-spring-boot` and `
- [Nacos Discovery Quick Start](https://github.com/nacos-group/nacos-spring-boot-project/blob/master/NACOS-DISCOVERY-QUICK-START.md)
- [Nacos AOT Quick Start](https://github.com/nacos-group/nacos-spring-boot-project/blob/master/NACOS-AOT-QUICK-START.md)
For more information about Nacos Spring, see [Nacos Spring Project](https://github.com/nacos-group/nacos-spring-project).
For more information about user guide, see [User Guide](https://github.com/nacos-group/nacos-spring-boot-project/wiki/%E7%94%A8%E6%88%B7%E4%BD%BF%E7%94%A8%E6%96%87%E6%A1%A3).
## Relative Projects
* [Alibaba Nacos](https://github.com/alibaba/nacos)

View File

@ -18,7 +18,7 @@
<parent>
<artifactId>nacos-spring-boot-parent</artifactId>
<groupId>com.alibaba.boot</groupId>
<version>0.2.4</version>
<version>${revision}</version>
<relativePath>../nacos-spring-boot-parent/pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
@ -81,8 +81,20 @@
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-spring-context</artifactId>
<optional>true</optional>
<exclusions>
<exclusion>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-client</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-client</artifactId>
<version>${nacos.version}</version>
</dependency>
<!-- Test Dependencies -->
<dependency>
<groupId>org.springframework.boot</groupId>

View File

@ -17,8 +17,7 @@
package com.alibaba.boot.nacos.actuate.autoconfigure;
import com.alibaba.boot.nacos.actuate.endpoint.NacosConfigEndpoint;
import org.springframework.boot.actuate.autoconfigure.endpoint.condition.ConditionalOnEnabledEndpoint;
import org.springframework.boot.actuate.autoconfigure.endpoint.condition.ConditionalOnAvailableEndpoint;
import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
@ -35,7 +34,7 @@ public class NacosConfigEndpointAutoConfiguration {
@Bean
@ConditionalOnMissingBean
@ConditionalOnEnabledEndpoint
@ConditionalOnAvailableEndpoint
public NacosConfigEndpoint nacosEndpoint() {
return new NacosConfigEndpoint();
}

View File

@ -23,11 +23,13 @@ import java.util.Properties;
import com.alibaba.boot.nacos.common.PropertiesUtils;
import com.alibaba.boot.nacos.config.NacosConfigConstants;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.nacos.api.config.annotation.NacosConfigListener;
import com.alibaba.nacos.api.config.annotation.NacosConfigurationProperties;
import com.alibaba.nacos.common.utils.JacksonUtils;
import com.alibaba.nacos.spring.context.event.config.NacosConfigMetadataEvent;
import com.alibaba.nacos.spring.util.NacosUtils;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.apache.commons.lang3.ClassUtils;
import org.apache.commons.lang3.StringUtils;
import org.w3c.dom.Element;
@ -55,7 +57,7 @@ public class NacosConfigEndpoint
@Autowired
private ApplicationContext applicationContext;
private Map<String, JSONObject> nacosConfigMetadataMap = new HashMap<>(8);
private Map<String, JsonNode> nacosConfigMetadataMap = new HashMap<>(8);
@ReadOperation
public Map<String, Object> invoke() {
@ -82,37 +84,37 @@ public class NacosConfigEndpoint
public void onApplicationEvent(NacosConfigMetadataEvent event) {
String key = buildMetadataKey(event);
if (StringUtils.isNotEmpty(key) && !nacosConfigMetadataMap.containsKey(key)) {
JSONObject jsonObject = new JSONObject();
jsonObject.put("groupId", event.getGroupId());
jsonObject.put("dataId", event.getDataId());
ObjectNode jsonNode = JacksonUtils.createEmptyJsonNode();
jsonNode.put("groupId", event.getGroupId());
jsonNode.put("dataId", event.getDataId());
if (ClassUtils.isAssignable(event.getSource().getClass(),
AnnotationMetadata.class)) {
jsonObject.put("origin", "NacosPropertySource");
jsonObject.put("target",
jsonNode.put("origin", "NacosPropertySource");
jsonNode.put("target",
((AnnotationMetadata) event.getSource()).getClassName());
}
else if (ClassUtils.isAssignable(event.getSource().getClass(),
NacosConfigListener.class)) {
jsonObject.put("origin", "NacosConfigListener");
jsonNode.put("origin", "NacosConfigListener");
Method configListenerMethod = (Method) event.getAnnotatedElement();
jsonObject.put("target",
jsonNode.put("target",
configListenerMethod.getDeclaringClass().getName() + ":"
+ configListenerMethod.toString());
}
else if (ClassUtils.isAssignable(event.getSource().getClass(),
NacosConfigurationProperties.class)) {
jsonObject.put("origin", "NacosConfigurationProperties");
jsonObject.put("target", event.getBeanType().getName());
jsonNode.put("origin", "NacosConfigurationProperties");
jsonNode.put("target", event.getBeanType().getName());
}
else if (ClassUtils.isAssignable(event.getSource().getClass(),
Element.class)) {
jsonObject.put("origin", "NacosPropertySource");
jsonObject.put("target", event.getXmlResource().toString());
jsonNode.put("origin", "NacosPropertySource");
jsonNode.put("target", event.getXmlResource().toString());
}
else {
throw new RuntimeException("unknown NacosConfigMetadataEvent");
}
nacosConfigMetadataMap.put(key, jsonObject);
nacosConfigMetadataMap.put(key, jsonNode);
}
}

View File

@ -19,8 +19,8 @@ package com.alibaba.boot.nacos.actuate.health;
import java.util.Properties;
import com.alibaba.boot.nacos.common.PropertiesUtils;
import com.alibaba.fastjson.JSON;
import com.alibaba.nacos.api.config.ConfigService;
import com.alibaba.nacos.common.utils.JacksonUtils;
import com.alibaba.nacos.spring.factory.CacheableEventPublishingNacosServiceFactory;
import com.alibaba.nacos.spring.factory.NacosServiceFactory;
import com.alibaba.nacos.spring.metadata.NacosServiceMetaData;
@ -54,7 +54,7 @@ public class NacosConfigHealthIndicator extends AbstractHealthIndicator {
NacosServiceMetaData nacosServiceMetaData = (NacosServiceMetaData) configService;
Properties properties = nacosServiceMetaData.getProperties();
builder.withDetail(
JSON.toJSONString(
JacksonUtils.toJson(
PropertiesUtils.extractSafeProperties(properties)),
configService.getServerStatus());
}

View File

@ -0,0 +1,56 @@
[
{
"name": "org.springframework.core.env.ConfigurableEnvironment",
"allDeclaredMethods": true,
"allDeclaredFields": true,
"allDeclaredConstructors": true,
"allPublicMethods": true,
"allPublicFields": true,
"allPublicConstructors": true
},
{
"name": "java.util.Properties",
"allDeclaredMethods": true,
"allDeclaredFields": true,
"allDeclaredConstructors": true,
"allPublicMethods": true,
"allPublicFields": true,
"allPublicConstructors": true
},
{
"name": "org.springframework.core.type.AnnotationMetadata",
"allDeclaredMethods": true,
"allDeclaredFields": true,
"allDeclaredConstructors": true,
"allPublicMethods": true,
"allPublicFields": true,
"allPublicConstructors": true
},
{
"name": "com.alibaba.nacos.api.config.annotation.NacosConfigListener",
"allDeclaredMethods": true,
"allDeclaredFields": true,
"allDeclaredConstructors": true,
"allPublicMethods": true,
"allPublicFields": true,
"allPublicConstructors": true
},
{
"name": "com.alibaba.nacos.api.config.annotation.NacosConfigurationProperties",
"allDeclaredMethods": true,
"allDeclaredFields": true,
"allDeclaredConstructors": true,
"allPublicMethods": true,
"allPublicFields": true,
"allPublicConstructors": true
},
{
"name": "org.w3c.dom.Element",
"allDeclaredMethods": true,
"allDeclaredFields": true,
"allDeclaredConstructors": true,
"allPublicMethods": true,
"allPublicFields": true,
"allPublicConstructors": true
}
]

View File

@ -0,0 +1,2 @@
com.alibaba.boot.nacos.actuate.autoconfigure.NacosConfigEndpointAutoConfiguration
com.alibaba.boot.nacos.actuate.autoconfigure.NacosConfigHealthIndicatorAutoConfiguration

View File

@ -0,0 +1,51 @@
/*
*
* * 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.boot.nacos.actuate.autoconfigure;
import com.alibaba.boot.nacos.actuate.endpoint.NacosConfigEndpoint;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.ApplicationContext;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
/**
* {@link NacosConfigEndpointAutoConfiguration} Test
* @ClassName: NacosConfigEndpointAutoConfigurationTest
* @Author: SuperZ1999
* @Date: 2023/9/28
*/
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = {NacosConfigEndpointAutoConfiguration.class})
@TestPropertySource(properties = {
"management.endpoints.web.exposure.include=nacos-config"
})
public class NacosConfigEndpointAutoConfigurationTest {
@Autowired
private ApplicationContext context;
@Test
public void testNacosConfigEndpointBean() {
Assert.assertNotNull(context.getBean(NacosConfigEndpoint.class));
}
}

View File

@ -0,0 +1,47 @@
/*
*
* * 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.boot.nacos.actuate.autoconfigure;
import com.alibaba.boot.nacos.actuate.health.NacosConfigHealthIndicator;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.ApplicationContext;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
/**
* {@link NacosConfigHealthIndicatorAutoConfiguration} Test
* @ClassName: NacosConfigHealthIndicatorAutoConfigurationTest
* @Author: SuperZ1999
* @Date: 2023/9/28
*/
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = {NacosConfigHealthIndicatorAutoConfiguration.class})
public class NacosConfigHealthIndicatorAutoConfigurationTest {
@Autowired
private ApplicationContext context;
@Test
public void testNacosConfigHealthIndicatorBean() {
Assert.assertNotNull(context.getBean(NacosConfigHealthIndicator.class));
}
}

View File

@ -18,7 +18,7 @@
<parent>
<groupId>com.alibaba.boot</groupId>
<artifactId>nacos-spring-boot-parent</artifactId>
<version>0.2.4</version>
<version>${revision}</version>
<relativePath>../nacos-spring-boot-parent</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
@ -66,11 +66,30 @@
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-spring-context</artifactId>
<optional>true</optional>
<exclusions>
<exclusion>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-client</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-client</artifactId>
<version>${nacos.version}</version>
</dependency>
<dependency>
<groupId>com.alibaba.boot</groupId>
<artifactId>nacos-spring-boot-base</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.alibaba.boot</groupId>
<artifactId>nacos-spring-boot-base</artifactId>
<artifactId>nacos-spring-boot-aot</artifactId>
<optional>true</optional>
</dependency>

View File

@ -20,14 +20,18 @@ import java.util.Properties;
import java.util.function.Function;
import com.alibaba.boot.nacos.config.properties.NacosConfigProperties;
import com.alibaba.boot.nacos.config.util.NacosConfigLoader;
import com.alibaba.boot.nacos.config.util.NacosConfigLoaderFactory;
import com.alibaba.boot.nacos.config.util.NacosConfigPropertiesUtils;
import com.alibaba.boot.nacos.config.util.NacosConfigUtils;
import com.alibaba.nacos.api.config.ConfigService;
import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.client.config.utils.SnapShotSwitch;
import com.alibaba.nacos.spring.factory.CacheableEventPublishingNacosServiceFactory;
import com.alibaba.nacos.spring.util.NacosBeanUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.context.ApplicationContextInitializer;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.env.ConfigurableEnvironment;
@ -41,11 +45,19 @@ public class NacosConfigApplicationContextInitializer
private final Logger logger = LoggerFactory
.getLogger(NacosConfigApplicationContextInitializer.class);
private ConfigurableEnvironment environment;
private final NacosConfigEnvironmentProcessor processor;
private final CacheableEventPublishingNacosServiceFactory singleton = CacheableEventPublishingNacosServiceFactory
.getSingleton();
private final Function<Properties, ConfigService> builder = properties -> {
try {
return singleton.createConfigService(properties);
}
catch (NacosException e) {
throw new NacosBootConfigException(
"ConfigService can't be created with properties : " + properties, e);
}
};
private ConfigurableEnvironment environment;
private NacosConfigProperties nacosConfigProperties;
public NacosConfigApplicationContextInitializer(
@ -55,41 +67,32 @@ public class NacosConfigApplicationContextInitializer
@Override
public void initialize(ConfigurableApplicationContext context) {
CacheableEventPublishingNacosServiceFactory singleton = CacheableEventPublishingNacosServiceFactory
.getSingleton();
singleton.setApplicationContext(context);
environment = context.getEnvironment();
nacosConfigProperties = NacosConfigPropertiesUtils
.buildNacosConfigProperties(environment);
processor.publishDeferService(context);
final NacosConfigLoader configLoader = NacosConfigLoaderFactory.getSingleton(builder);
if (!processor.snapshotEnable()){
SnapShotSwitch.setIsSnapShot(false);
}
if (!enable()) {
logger.info("[Nacos Config Boot] : The preload configuration is not enabled");
}
else {
Function<Properties, ConfigService> builder = properties -> {
try {
return singleton.createConfigService(properties);
}
catch (NacosException e) {
throw new NacosBootConfigException(
"ConfigService can't be created with properties : "
+ properties,
e);
}
};
NacosConfigUtils configUtils = new NacosConfigUtils(nacosConfigProperties,
environment, builder);
// If it opens the log level loading directly will cache
// DeferNacosPropertySource release
if (processor.enable()) {
configUtils
processor.publishDeferService(context);
configLoader
.addListenerIfAutoRefreshed(processor.getDeferPropertySources());
}
else {
configUtils.loadConfig();
configUtils.addListenerIfAutoRefreshed();
configLoader.loadConfig(environment, nacosConfigProperties);
configLoader.addListenerIfAutoRefreshed();
}
}
}

View File

@ -16,6 +16,7 @@
*/
package com.alibaba.boot.nacos.config.autoconfigure;
import com.alibaba.boot.nacos.aot.context.EnableNacosConfigAotProcessor;
import com.alibaba.boot.nacos.config.NacosConfigConstants;
import com.alibaba.boot.nacos.config.properties.NacosConfigProperties;
import com.alibaba.nacos.spring.context.annotation.config.EnableNacosConfig;
@ -38,7 +39,7 @@ import static com.alibaba.nacos.spring.util.NacosBeanUtils.CONFIG_GLOBAL_NACOS_P
@ConditionalOnMissingBean(name = CONFIG_GLOBAL_NACOS_PROPERTIES_BEAN_NAME)
@EnableConfigurationProperties(value = NacosConfigProperties.class)
@ConditionalOnClass(name = "org.springframework.boot.context.properties.bind.Binder")
@Import(value = { NacosConfigBootBeanDefinitionRegistrar.class })
@Import(value = { NacosConfigBootBeanDefinitionRegistrar.class, EnableNacosConfigAotProcessor.class })
@EnableNacosConfig
public class NacosConfigAutoConfiguration {

View File

@ -16,9 +16,17 @@
*/
package com.alibaba.boot.nacos.config.autoconfigure;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;
import java.util.Properties;
import java.util.function.Function;
import com.alibaba.boot.nacos.config.properties.NacosConfigProperties;
import com.alibaba.boot.nacos.config.util.NacosConfigLoader;
import com.alibaba.boot.nacos.config.util.NacosConfigLoaderFactory;
import com.alibaba.boot.nacos.config.util.NacosConfigPropertiesUtils;
import com.alibaba.boot.nacos.config.util.NacosConfigUtils;
import com.alibaba.boot.nacos.config.util.log.LogAutoFreshProcess;
import com.alibaba.nacos.api.NacosFactory;
import com.alibaba.nacos.api.config.ConfigService;
import com.alibaba.nacos.api.exception.NacosException;
@ -26,18 +34,13 @@ import com.alibaba.nacos.spring.factory.CacheableEventPublishingNacosServiceFact
import com.alibaba.nacos.spring.util.NacosUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.env.EnvironmentPostProcessor;
import org.springframework.context.ApplicationContext;
import org.springframework.core.Ordered;
import org.springframework.core.env.ConfigurableEnvironment;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;
import java.util.Properties;
import java.util.function.Function;
/**
* In the Context to create premise before loading the log configuration information
*
@ -45,78 +48,85 @@ import java.util.function.Function;
* @since 0.2.3
*/
public class NacosConfigEnvironmentProcessor
implements EnvironmentPostProcessor, Ordered {
implements EnvironmentPostProcessor, Ordered {
private final Logger logger = LoggerFactory
.getLogger(NacosConfigEnvironmentProcessor.class);
private final Logger logger = LoggerFactory
.getLogger(NacosConfigEnvironmentProcessor.class);
private final CacheableEventPublishingNacosServiceFactory nacosServiceFactory = CacheableEventPublishingNacosServiceFactory
.getSingleton();
private final Map<String, ConfigService> serviceCache = new HashMap<>(8);
private final LinkedList<NacosConfigLoader.DeferNacosPropertySource> deferPropertySources = new LinkedList<>();
private NacosConfigProperties nacosConfigProperties;
private final CacheableEventPublishingNacosServiceFactory nacosServiceFactory = CacheableEventPublishingNacosServiceFactory
.getSingleton();
private NacosConfigProperties nacosConfigProperties;
private final Map<String, ConfigService> serviceCache = new HashMap<>(8);
// Because ApplicationContext has not been injected at preload time, need to manually
// cache the created Service to prevent duplicate creation
private final Function<Properties, ConfigService> builder = properties -> {
try {
final String key = NacosUtils.identify(properties);
if (serviceCache.containsKey(key)) {
return serviceCache.get(key);
}
final ConfigService configService = NacosFactory
.createConfigService(properties);
serviceCache.put(key, configService);
return nacosServiceFactory.deferCreateService(configService, properties);
}
catch (NacosException e) {
throw new NacosBootConfigException(
"ConfigService can't be created with properties : " + properties, e);
}
};
private final LinkedList<NacosConfigUtils.DeferNacosPropertySource> deferPropertySources = new LinkedList<>();
@Override
public void postProcessEnvironment(ConfigurableEnvironment environment,
SpringApplication application) {
application.addInitializers(new NacosConfigApplicationContextInitializer(this));
nacosConfigProperties = NacosConfigPropertiesUtils
.buildNacosConfigProperties(environment);
if (enable()) {
System.out.println(
"[Nacos Config Boot] : The preload log configuration is enabled");
NacosConfigLoader nacosConfigLoader = NacosConfigLoaderFactory.getSingleton(builder);
loadConfig(nacosConfigLoader, environment, nacosConfigProperties);
LogAutoFreshProcess.build(environment, nacosConfigProperties, nacosConfigLoader, builder).process();
}
}
// Because ApplicationContext has not been injected at preload time, need to manually cache the created Service to prevent duplicate creation
private void loadConfig(NacosConfigLoader configLoader, ConfigurableEnvironment environment, NacosConfigProperties nacosConfigProperties) {
configLoader.loadConfig(environment, nacosConfigProperties);
// set defer NacosPropertySource
deferPropertySources.addAll(configLoader.getNacosPropertySources());
}
private Function<Properties, ConfigService> builder = properties -> {
try {
final String key = NacosUtils.identify(properties);
if (serviceCache.containsKey(key)) {
return serviceCache.get(key);
}
final ConfigService configService = NacosFactory
.createConfigService(properties);
serviceCache.put(key, configService);
return nacosServiceFactory.deferCreateService(configService, properties);
} catch (NacosException e) {
throw new NacosBootConfigException(
"ConfigService can't be created with properties : " + properties, e);
}
};
boolean enable() {
return nacosConfigProperties != null
&& nacosConfigProperties.getBootstrap().isLogEnable();
}
@Override
public void postProcessEnvironment(ConfigurableEnvironment environment,
SpringApplication application) {
application.addInitializers(new NacosConfigApplicationContextInitializer(this));
nacosConfigProperties = NacosConfigPropertiesUtils
.buildNacosConfigProperties(environment);
if (enable()) {
System.out.println(
"[Nacos Config Boot] : The preload log configuration is enabled");
loadConfig(environment);
}
}
boolean snapshotEnable() {
return nacosConfigProperties != null
&& nacosConfigProperties.getBootstrap().isSnapshotEnable();
}
private void loadConfig(ConfigurableEnvironment environment) {
NacosConfigUtils configUtils = new NacosConfigUtils(nacosConfigProperties,
environment, builder);
configUtils.loadConfig();
// set defer NacosPropertySource
deferPropertySources.addAll(configUtils.getNacosPropertySources());
}
LinkedList<NacosConfigLoader.DeferNacosPropertySource> getDeferPropertySources() {
return deferPropertySources;
}
boolean enable() {
return nacosConfigProperties != null
&& nacosConfigProperties.getBootstrap().isLogEnable();
}
// Do not set the minimum priority for future expansion needs
LinkedList<NacosConfigUtils.DeferNacosPropertySource> getDeferPropertySources() {
return deferPropertySources;
}
@Override
public int getOrder() {
return Ordered.LOWEST_PRECEDENCE - 5;
}
@Override
public int getOrder() {
return Ordered.LOWEST_PRECEDENCE;
}
void publishDeferService(ApplicationContext context) {
try {
nacosServiceFactory.publishDeferService(context);
serviceCache.clear();
} catch (Exception e) {
logger.error("publish defer ConfigService has some error : {}", e);
}
}
void publishDeferService(ApplicationContext context) {
try {
nacosServiceFactory.publishDeferService(context);
serviceCache.clear();
}
catch (Exception e) {
logger.error("publish defer ConfigService has some error", e);
}
}
}

View File

@ -22,10 +22,10 @@ import com.alibaba.nacos.api.config.ConfigService;
import com.alibaba.nacos.api.config.annotation.NacosConfigurationProperties;
import com.alibaba.nacos.spring.context.properties.config.NacosConfigurationPropertiesBinder;
import com.alibaba.nacos.spring.core.env.NacosPropertySource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.context.properties.ConfigurationBeanFactoryMetadata;
import com.alibaba.nacos.spring.util.ObjectUtils;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.boot.context.properties.bind.Bindable;
import org.springframework.boot.context.properties.bind.Binder;
import org.springframework.context.ConfigurableApplicationContext;
@ -39,44 +39,51 @@ import org.springframework.core.env.StandardEnvironment;
public class NacosBootConfigurationPropertiesBinder
extends NacosConfigurationPropertiesBinder {
private final Logger logger = LoggerFactory
.getLogger(NacosBootConfigurationPropertiesBinder.class);
private final ConfigurableApplicationContext applicationContext;
private ConfigurationBeanFactoryMetadata beanFactoryMetadata;
private StandardEnvironment environment = new StandardEnvironment();
private final StandardEnvironment environment = new StandardEnvironment();
public NacosBootConfigurationPropertiesBinder(
ConfigurableApplicationContext applicationContext) {
super(applicationContext);
this.beanFactoryMetadata = applicationContext.getBean(
ConfigurationBeanFactoryMetadata.BEAN_NAME,
ConfigurationBeanFactoryMetadata.class);
this.applicationContext = applicationContext;
}
@Override
protected void doBind(Object bean, String beanName, String dataId, String groupId,
String configType, NacosConfigurationProperties properties, String content,
ConfigService configService) {
String name = "nacos-bootstrap-" + beanName;
NacosPropertySource propertySource = new NacosPropertySource(name, dataId,
groupId, content, configType);
environment.getPropertySources().addLast(propertySource);
Binder binder = Binder.get(environment);
ResolvableType type = getBeanType(bean, beanName);
Bindable<?> target = Bindable.of(type).withExistingValue(bean);
binder.bind(properties.prefix(), target);
publishBoundEvent(bean, beanName, dataId, groupId, properties, content,
configService);
publishMetadataEvent(bean, beanName, dataId, groupId, properties);
environment.getPropertySources().remove(name);
synchronized (this) {
String name = "nacos-bootstrap-" + beanName;
NacosPropertySource propertySource = new NacosPropertySource(dataId, groupId, name, content, configType);
environment.getPropertySources().addLast(propertySource);
ObjectUtils.cleanMapOrCollectionField(bean);
Binder binder = Binder.get(environment);
ResolvableType type = getBeanType(bean, beanName);
Bindable<?> target = Bindable.of(type).withExistingValue(bean);
binder.bind(properties.prefix(), target);
publishBoundEvent(bean, beanName, dataId, groupId, properties, content, configService);
publishMetadataEvent(bean, beanName, dataId, groupId, properties);
environment.getPropertySources().remove(name);
}
}
private ResolvableType getBeanType(Object bean, String beanName) {
Method factoryMethod = this.beanFactoryMetadata.findFactoryMethod(beanName);
Method factoryMethod = findFactoryMethod(beanName);
if (factoryMethod != null) {
return ResolvableType.forMethodReturnType(factoryMethod);
}
return ResolvableType.forClass(bean.getClass());
}
public Method findFactoryMethod(String beanName) {
ConfigurableListableBeanFactory beanFactory = this.applicationContext.getBeanFactory();
if (beanFactory.containsBeanDefinition(beanName)) {
BeanDefinition beanDefinition = beanFactory.getMergedBeanDefinition(beanName);
if (beanDefinition instanceof RootBeanDefinition) {
return ((RootBeanDefinition) beanDefinition).getResolvedFactoryMethod();
}
}
return null;
}
}

View File

@ -0,0 +1,67 @@
/*
* Copyright 2013-2018 the original author or authors.
*
* Licensed 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
*
* https://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.boot.nacos.config.logging;
import com.alibaba.boot.nacos.config.properties.NacosConfigProperties;
import com.alibaba.boot.nacos.config.util.NacosConfigPropertiesUtils;
import com.alibaba.nacos.client.logging.NacosLogging;
import org.springframework.boot.context.event.ApplicationEnvironmentPreparedEvent;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.event.GenericApplicationListener;
import org.springframework.core.Ordered;
import org.springframework.core.ResolvableType;
/**
* Reload nacos log configuration file, after
* {@link org.springframework.boot.context.logging.LoggingApplicationListener}.
*
* @author mai.jh
*/
public class NacosLoggingListener implements GenericApplicationListener {
@Override
public boolean supportsEventType(ResolvableType resolvableType) {
Class<?> type = resolvableType.getRawClass();
if (type != null) {
return ApplicationEnvironmentPreparedEvent.class.isAssignableFrom(type);
}
return false;
}
@Override
public boolean supportsSourceType(Class<?> aClass) {
return true;
}
@Override
public void onApplicationEvent(ApplicationEvent applicationEvent) {
//If the managed log is enabled, load your own log configuration after loading the user log configuration
ApplicationEnvironmentPreparedEvent applicationEnvironmentPreparedEvent = (ApplicationEnvironmentPreparedEvent) applicationEvent;
NacosConfigProperties nacosConfigProperties = NacosConfigPropertiesUtils.buildNacosConfigProperties(
applicationEnvironmentPreparedEvent.getEnvironment());
if(nacosConfigProperties.getBootstrap().isLogEnable()){
NacosLogging.getInstance().loadConfiguration();
}
}
@Override
public int getOrder() {
return Ordered.HIGHEST_PRECEDENCE + 21;
}
}

View File

@ -18,12 +18,13 @@ package com.alibaba.boot.nacos.config.properties;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import com.alibaba.boot.nacos.config.NacosConfigConstants;
import com.alibaba.fastjson.annotation.JSONField;
import com.alibaba.nacos.api.common.Constants;
import com.alibaba.nacos.api.config.ConfigType;
import com.fasterxml.jackson.annotation.JsonIgnore;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.NestedConfigurationProperty;
import org.springframework.util.Assert;
@ -60,7 +61,7 @@ public class NacosConfigProperties {
private String group = Constants.DEFAULT_GROUP;
private ConfigType type;
private ConfigType type = ConfigType.PROPERTIES;
private String maxRetry;
@ -70,12 +71,34 @@ public class NacosConfigProperties {
private boolean enableRemoteSyncConfig = false;
@JSONField(serialize = false)
private String username;
private String password;
private boolean remoteFirst = false;
@JsonIgnore
private List<Config> extConfig = new ArrayList<>();
@NestedConfigurationProperty
private Bootstrap bootstrap = new Bootstrap();
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getServerAddr() {
return serverAddr;
}
@ -213,6 +236,14 @@ public class NacosConfigProperties {
this.enableRemoteSyncConfig = enableRemoteSyncConfig;
}
public boolean isRemoteFirst() {
return remoteFirst;
}
public void setRemoteFirst(boolean remoteFirst) {
this.remoteFirst = remoteFirst;
}
public List<Config> getExtConfig() {
return extConfig;
}
@ -229,12 +260,40 @@ public class NacosConfigProperties {
this.bootstrap = bootstrap;
}
@Override
public String toString() {
final StringBuffer sb = new StringBuffer("NacosConfigProperties{");
sb.append("serverAddr='").append(serverAddr).append('\'');
sb.append(", contextPath='").append(contextPath).append('\'');
sb.append(", encode='").append(encode).append('\'');
sb.append(", endpoint='").append(endpoint).append('\'');
sb.append(", namespace='").append(namespace).append('\'');
sb.append(", accessKey='").append(Objects.isNull(accessKey) ? null : "******").append('\'');
sb.append(", secretKey='").append(Objects.isNull(secretKey) ? null : "******").append('\'');
sb.append(", ramRoleName='").append(ramRoleName).append('\'');
sb.append(", autoRefresh=").append(autoRefresh);
sb.append(", dataId='").append(dataId).append('\'');
sb.append(", dataIds='").append(dataIds).append('\'');
sb.append(", group='").append(group).append('\'');
sb.append(", type=").append(type);
sb.append(", maxRetry='").append(maxRetry).append('\'');
sb.append(", configLongPollTimeout='").append(configLongPollTimeout).append('\'');
sb.append(", configRetryTime='").append(configRetryTime).append('\'');
sb.append(", enableRemoteSyncConfig=").append(enableRemoteSyncConfig);
sb.append(", extConfig=").append(extConfig);
sb.append(", bootstrap=").append(bootstrap);
sb.append('}');
return sb.toString();
}
public static class Bootstrap {
private boolean enable;
private boolean logEnable;
private boolean snapshotEnable;
public boolean isEnable() {
return enable;
}
@ -250,11 +309,29 @@ public class NacosConfigProperties {
public void setLogEnable(boolean logEnable) {
this.logEnable = logEnable;
}
public boolean isSnapshotEnable() {
return snapshotEnable;
}
public void setSnapshotEnable(boolean snapshotEnable) {
this.snapshotEnable = snapshotEnable;
}
@Override
public String toString() {
final StringBuffer sb = new StringBuffer("Bootstrap{");
sb.append("enable=").append(enable);
sb.append(", snapshotEnable=").append(snapshotEnable);
sb.append(", logEnable=").append(logEnable);
sb.append('}');
return sb.toString();
}
}
public static class Config {
private String serverAddr = "127.0.0.1:8848";
private String serverAddr;
private String endpoint;
@ -284,6 +361,26 @@ public class NacosConfigProperties {
private boolean enableRemoteSyncConfig = false;
private String username;
private String password;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getServerAddr() {
return serverAddr;
}
@ -403,5 +500,28 @@ public class NacosConfigProperties {
public void setEnableRemoteSyncConfig(boolean enableRemoteSyncConfig) {
this.enableRemoteSyncConfig = enableRemoteSyncConfig;
}
@Override
public String toString() {
final StringBuffer sb = new StringBuffer("Config{");
sb.append("serverAddr='").append(serverAddr).append('\'');
sb.append(", endpoint='").append(endpoint).append('\'');
sb.append(", namespace='").append(namespace).append('\'');
sb.append(", accessKey='").append(Objects.isNull(accessKey) ? null : "******").append('\'');
sb.append(", secretKey='").append(Objects.isNull(secretKey) ? null : "******").append('\'');
sb.append(", ramRoleName='").append(ramRoleName).append('\'');
sb.append(", dataId='").append(dataId).append('\'');
sb.append(", dataIds='").append(dataIds).append('\'');
sb.append(", group='").append(group).append('\'');
sb.append(", type=").append(type);
sb.append(", maxRetry='").append(maxRetry).append('\'');
sb.append(", configLongPollTimeout='").append(configLongPollTimeout)
.append('\'');
sb.append(", configRetryTime='").append(configRetryTime).append('\'');
sb.append(", autoRefresh=").append(autoRefresh);
sb.append(", enableRemoteSyncConfig=").append(enableRemoteSyncConfig);
sb.append('}');
return sb.toString();
}
}
}

View File

@ -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.boot.nacos.config.support;
import com.alibaba.nacos.spring.core.env.AbstractNacosPropertySourceBuilder;
import com.alibaba.nacos.spring.core.env.NacosPropertySource;
import com.alibaba.nacos.spring.util.parse.DefaultYamlConfigParse;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.env.EnvironmentPostProcessor;
import org.springframework.core.env.ConfigurableEnvironment;
import java.util.Map;
import java.util.concurrent.atomic.AtomicReference;
/**
* yaml multi profiles.
* <p>
* read nacos propertysource:
* <p>
* 1. {@link AbstractNacosPropertySourceBuilder#doBuild(String, BeanDefinition, Map)}<br/>
* 2. {@link NacosPropertySource#NacosPropertySource(String, String, String, String, String)}<br/>
* 3. {@link com.alibaba.nacos.spring.util.NacosUtils#toProperties(String, String, String, String)}<br/>
* 4. {@link com.alibaba.nacos.spring.util.ConfigParseUtils#toProperties(String, String, String, String)}<br/>
*
* @author <a href="mailto:yanglu_u@126.com">dbses</a>
*/
public class MultiProfilesYamlConfigParseSupport extends DefaultYamlConfigParse implements EnvironmentPostProcessor {
private static final String SPRING_PROFILES = "spring.profiles";
private static String[] profileArray = {};
@Override
public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
String[] profiles = environment.getActiveProfiles();
// fall back to default profiles
if (profiles.length == 0) {
profiles = environment.getDefaultProfiles();
}
// set once
if (profileArray.length == 0) {
profileArray = profiles;
}
}
@Override
public Map<String, Object> parse(String configText) {
final AtomicReference<Map<String, Object>> result = new AtomicReference<>();
process(map -> {
// first block
if (result.get() == null) {
result.set(map);
} else {
setFromOtherBlock(result, map);
}
}, createYaml(), configText);
return result.get();
}
private void setFromOtherBlock(AtomicReference<Map<String, Object>> result, Map<String, Object> map) {
if (map.get(SPRING_PROFILES) == null) {
result.get().putAll(map);
return;
}
for (String profile : profileArray) {
if (profile.equals(map.get(SPRING_PROFILES))) {
result.get().putAll(map);
}
}
}
/**
* for unit test
*/
static void setProfileArray(String[] profiles) {
profileArray = profiles;
}
}

View File

@ -0,0 +1,233 @@
/*
* 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.boot.nacos.config.util;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;
import java.util.Properties;
import java.util.function.Function;
import java.util.stream.Collectors;
import com.alibaba.boot.nacos.config.properties.NacosConfigProperties;
import com.alibaba.nacos.api.config.ConfigService;
import com.alibaba.nacos.api.config.ConfigType;
import com.alibaba.nacos.spring.core.env.NacosPropertySource;
import com.alibaba.nacos.spring.core.env.NacosPropertySourcePostProcessor;
import com.alibaba.nacos.spring.util.NacosUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.MutablePropertySources;
import org.springframework.core.env.StandardEnvironment;
import org.springframework.util.StringUtils;
import static com.alibaba.nacos.spring.util.NacosUtils.buildDefaultPropertySourceName;
/**
* @author <a href="mailto:liaochunyhm@live.com">liaochuntao</a>
* @author <a href="mailto:guofuyinan@gmail.com">guofuyinan</a>
* @since 0.2.3
*/
public class NacosConfigLoader {
private final Logger logger = LoggerFactory.getLogger(NacosConfigLoader.class);
private Properties globalProperties = new Properties();
private final Function<Properties, ConfigService> builder;
private final List<DeferNacosPropertySource> nacosPropertySources = new LinkedList<>();
public NacosConfigLoader(Function<Properties, ConfigService> builder) {
this.builder = builder;
}
public void loadConfig(ConfigurableEnvironment environment, NacosConfigProperties nacosConfigProperties) {
globalProperties = buildGlobalNacosProperties(environment, nacosConfigProperties);
MutablePropertySources mutablePropertySources = environment.getPropertySources();
List<NacosPropertySource> sources = reqGlobalNacosConfig(environment, globalProperties, nacosConfigProperties);
for (NacosConfigProperties.Config config : nacosConfigProperties.getExtConfig()) {
List<NacosPropertySource> elements = reqSubNacosConfig(environment, config,
globalProperties, config.getType());
sources.addAll(elements);
}
if (nacosConfigProperties.isRemoteFirst()) {
for (ListIterator<NacosPropertySource> itr = sources.listIterator(sources.size()); itr.hasPrevious();) {
mutablePropertySources.addAfter(
StandardEnvironment.SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME, itr.previous());
}
} else {
for (NacosPropertySource propertySource : sources) {
mutablePropertySources.addLast(propertySource);
}
}
}
public Properties buildGlobalNacosProperties(ConfigurableEnvironment environment, NacosConfigProperties nacosConfigProperties) {
return NacosPropertiesBuilder.buildNacosProperties(environment,
nacosConfigProperties.getServerAddr(),
nacosConfigProperties.getNamespace(), nacosConfigProperties.getEndpoint(),
nacosConfigProperties.getSecretKey(),
nacosConfigProperties.getAccessKey(),
nacosConfigProperties.getRamRoleName(),
nacosConfigProperties.getConfigLongPollTimeout(),
nacosConfigProperties.getConfigRetryTime(),
nacosConfigProperties.getMaxRetry(),
nacosConfigProperties.getContextPath(),
nacosConfigProperties.isEnableRemoteSyncConfig(),
nacosConfigProperties.getUsername(), nacosConfigProperties.getPassword());
}
private Properties buildSubNacosProperties(ConfigurableEnvironment environment, Properties globalProperties,
NacosConfigProperties.Config config) {
Properties sub = NacosPropertiesBuilder.buildNacosProperties(environment,
config.getServerAddr(), config.getNamespace(), config.getEndpoint(),
config.getSecretKey(), config.getAccessKey(), config.getRamRoleName(),
config.getConfigLongPollTimeout(), config.getConfigRetryTime(),
config.getMaxRetry(),null, config.isEnableRemoteSyncConfig(),
config.getUsername(), config.getPassword());
NacosPropertiesBuilder.merge(sub, globalProperties);
return sub;
}
private List<NacosPropertySource> reqGlobalNacosConfig(ConfigurableEnvironment environment, Properties globalProperties,
NacosConfigProperties nacosConfigProperties) {
List<String> dataIds = new ArrayList<>();
// Loads all data-id information into the list in the list
if (!StringUtils.hasLength(nacosConfigProperties.getDataId())) {
final String ids = environment
.resolvePlaceholders(nacosConfigProperties.getDataIds());
if(StringUtils.hasText(ids)){
dataIds.addAll(Arrays.stream(ids.split(","))
.filter(StringUtils::hasText)
.collect(Collectors.toList()));
}
}
else {
dataIds.add(nacosConfigProperties.getDataId());
}
final String groupName = environment
.resolvePlaceholders(nacosConfigProperties.getGroup());
final boolean isAutoRefresh = nacosConfigProperties.isAutoRefresh();
return new ArrayList<>(Arrays.asList(reqNacosConfig(environment, globalProperties,
dataIds.toArray(new String[0]), groupName, nacosConfigProperties.getType(), isAutoRefresh)));
}
private List<NacosPropertySource> reqSubNacosConfig(ConfigurableEnvironment environment,
NacosConfigProperties.Config config, Properties globalProperties,
ConfigType type) {
Properties subConfigProperties = buildSubNacosProperties(environment, globalProperties,
config);
ArrayList<String> dataIds = new ArrayList<>();
if (!StringUtils.hasLength(config.getDataId())) {
final String ids = environment.resolvePlaceholders(config.getDataIds());
dataIds.addAll(Arrays.asList(ids.split(",")));
}
else {
dataIds.add(config.getDataId());
}
final String groupName = environment.resolvePlaceholders(config.getGroup());
final boolean isAutoRefresh = config.isAutoRefresh();
return new ArrayList<>(Arrays.asList(reqNacosConfig(environment, subConfigProperties,
dataIds.toArray(new String[0]), groupName, type, isAutoRefresh)));
}
private NacosPropertySource[] reqNacosConfig(ConfigurableEnvironment environment, Properties configProperties,
String[] dataIds, String groupId, ConfigType type, boolean isAutoRefresh) {
final NacosPropertySource[] propertySources = new NacosPropertySource[dataIds.length];
for (int i = 0; i < dataIds.length; i++) {
if (!StringUtils.hasLength(dataIds[i])) {
continue;
}
// Remove excess Spaces
final String dataId = environment.resolvePlaceholders(dataIds[i].trim());
final String config = NacosUtils.getContent(builder.apply(configProperties),
dataId, groupId);
final NacosPropertySource nacosPropertySource = new NacosPropertySource(
dataId, groupId,
buildDefaultPropertySourceName(dataId, groupId, configProperties),
config, type.getType());
nacosPropertySource.setDataId(dataId);
nacosPropertySource.setType(type.getType());
nacosPropertySource.setGroupId(groupId);
nacosPropertySource.setAutoRefreshed(isAutoRefresh);
logger.info("load config from nacos, data-id is : {}, group is : {}",
nacosPropertySource.getDataId(), nacosPropertySource.getGroupId());
propertySources[i] = nacosPropertySource;
DeferNacosPropertySource defer = new DeferNacosPropertySource(
nacosPropertySource, configProperties, environment);
nacosPropertySources.add(defer);
}
return propertySources;
}
public void addListenerIfAutoRefreshed() {
addListenerIfAutoRefreshed(nacosPropertySources);
}
public void addListenerIfAutoRefreshed(
final List<DeferNacosPropertySource> deferNacosPropertySources) {
for (DeferNacosPropertySource deferNacosPropertySource : deferNacosPropertySources) {
NacosPropertySourcePostProcessor.addListenerIfAutoRefreshed(
deferNacosPropertySource.getNacosPropertySource(),
deferNacosPropertySource.getProperties(),
deferNacosPropertySource.getEnvironment());
}
}
public List<DeferNacosPropertySource> getNacosPropertySources() {
return nacosPropertySources;
}
public Properties getGlobalProperties() {
return globalProperties;
}
// Delay Nacos configuration data source object, used for log level of loading time,
// the cache configuration, wait for after the completion of the Spring Context
// created in the release
public static class DeferNacosPropertySource {
private final NacosPropertySource nacosPropertySource;
private final ConfigurableEnvironment environment;
private final Properties properties;
DeferNacosPropertySource(NacosPropertySource nacosPropertySource,
Properties properties, ConfigurableEnvironment environment) {
this.nacosPropertySource = nacosPropertySource;
this.properties = properties;
this.environment = environment;
}
NacosPropertySource getNacosPropertySource() {
return nacosPropertySource;
}
ConfigurableEnvironment getEnvironment() {
return environment;
}
public Properties getProperties() {
return properties;
}
}
}

View File

@ -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.boot.nacos.config.util;
import com.alibaba.boot.nacos.config.properties.NacosConfigProperties;
import com.alibaba.nacos.api.config.ConfigService;
import org.springframework.core.env.ConfigurableEnvironment;
import java.util.Properties;
import java.util.function.Function;
/**
* NacosConfigLoaderFactory.
* @author hujun
*/
public class NacosConfigLoaderFactory {
private static volatile NacosConfigLoader nacosConfigLoader;
public static NacosConfigLoader getSingleton(Function<Properties, ConfigService> builder) {
if (nacosConfigLoader == null) {
synchronized (NacosConfigLoaderFactory.class) {
if (nacosConfigLoader == null) {
nacosConfigLoader = new NacosConfigLoader(builder);
}
}
}
return nacosConfigLoader;
}
}

View File

@ -18,6 +18,7 @@ package com.alibaba.boot.nacos.config.util;
import com.alibaba.boot.nacos.config.NacosConfigConstants;
import com.alibaba.boot.nacos.config.properties.NacosConfigProperties;
import com.alibaba.nacos.api.config.ConfigService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -26,6 +27,9 @@ import org.springframework.boot.context.properties.bind.Binder;
import org.springframework.core.ResolvableType;
import org.springframework.core.env.ConfigurableEnvironment;
import java.util.Properties;
import java.util.function.Function;
/**
* Springboot used to own property binding configured binding
*

View File

@ -1,212 +0,0 @@
/*
* 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.boot.nacos.config.util;
import com.alibaba.boot.nacos.config.properties.NacosConfigProperties;
import com.alibaba.nacos.api.config.ConfigService;
import com.alibaba.nacos.api.config.ConfigType;
import com.alibaba.nacos.spring.core.env.NacosPropertySource;
import com.alibaba.nacos.spring.core.env.NacosPropertySourcePostProcessor;
import com.alibaba.nacos.spring.util.NacosUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.MutablePropertySources;
import org.springframework.util.StringUtils;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.Properties;
import java.util.function.Function;
import static com.alibaba.nacos.spring.util.NacosUtils.buildDefaultPropertySourceName;
/**
* @author <a href="mailto:liaochunyhm@live.com">liaochuntao</a>
* @since 0.2.3
*/
public class NacosConfigUtils {
private final Logger logger = LoggerFactory.getLogger(NacosConfigUtils.class);
private final NacosConfigProperties nacosConfigProperties;
private final ConfigurableEnvironment environment;
private Function<Properties, ConfigService> builder;
private List<DeferNacosPropertySource> nacosPropertySources = new LinkedList<>();
public NacosConfigUtils(NacosConfigProperties nacosConfigProperties,
ConfigurableEnvironment environment,
Function<Properties, ConfigService> builder) {
this.nacosConfigProperties = nacosConfigProperties;
this.environment = environment;
this.builder = builder;
}
public void loadConfig() {
Properties globalProperties = buildGlobalNacosProperties();
MutablePropertySources mutablePropertySources = environment.getPropertySources();
List<NacosPropertySource> sources = reqGlobalNacosConfig(globalProperties,
nacosConfigProperties.getType());
for (NacosConfigProperties.Config config : nacosConfigProperties.getExtConfig()) {
List<NacosPropertySource> elements = reqSubNacosConfig(config,
globalProperties, config.getType());
sources.addAll(elements);
}
for (NacosPropertySource propertySource : sources) {
mutablePropertySources.addLast(propertySource);
}
}
private Properties buildGlobalNacosProperties() {
return NacosPropertiesBuilder.buildNacosProperties(environment,
nacosConfigProperties.getServerAddr(),
nacosConfigProperties.getNamespace(), nacosConfigProperties.getEndpoint(),
nacosConfigProperties.getSecretKey(),
nacosConfigProperties.getAccessKey(),
nacosConfigProperties.getRamRoleName(),
nacosConfigProperties.getConfigLongPollTimeout(),
nacosConfigProperties.getConfigRetryTime(),
nacosConfigProperties.getMaxRetry(),
nacosConfigProperties.isEnableRemoteSyncConfig());
}
private Properties buildSubNacosProperties(Properties globalProperties,
NacosConfigProperties.Config config) {
Properties sub = NacosPropertiesBuilder.buildNacosProperties(environment,
config.getServerAddr(), config.getNamespace(), config.getEndpoint(),
config.getSecretKey(), config.getAccessKey(), config.getRamRoleName(),
config.getConfigLongPollTimeout(), config.getConfigRetryTime(),
config.getMaxRetry(), config.isEnableRemoteSyncConfig());
NacosPropertiesBuilder.merge(sub, globalProperties);
return sub;
}
private List<NacosPropertySource> reqGlobalNacosConfig(Properties globalProperties,
ConfigType type) {
List<String> dataIds = new ArrayList<>();
// Loads all data-id information into the list in the list
if (StringUtils.isEmpty(nacosConfigProperties.getDataId())) {
final String ids = environment
.resolvePlaceholders(nacosConfigProperties.getDataIds());
dataIds.addAll(Arrays.asList(ids.split(",")));
} else {
dataIds.add(nacosConfigProperties.getDataId());
}
final String groupName = environment
.resolvePlaceholders(nacosConfigProperties.getGroup());
final boolean isAutoRefresh = nacosConfigProperties.isAutoRefresh();
return new ArrayList<>(Arrays.asList(reqNacosConfig(globalProperties,
dataIds.toArray(new String[0]), groupName, type, isAutoRefresh)));
}
private List<NacosPropertySource> reqSubNacosConfig(
NacosConfigProperties.Config config, Properties globalProperties,
ConfigType type) {
Properties subConfigProperties = buildSubNacosProperties(globalProperties,
config);
ArrayList<String> dataIds = new ArrayList<>();
if (StringUtils.isEmpty(config.getDataId())) {
final String ids = environment.resolvePlaceholders(config.getDataIds());
dataIds.addAll(Arrays.asList(ids.split(",")));
} else {
dataIds.add(config.getDataId());
}
final String groupName = environment.resolvePlaceholders(config.getGroup());
final boolean isAutoRefresh = config.isAutoRefresh();
return new ArrayList<>(Arrays.asList(reqNacosConfig(subConfigProperties,
dataIds.toArray(new String[0]), groupName, type, isAutoRefresh)));
}
private NacosPropertySource[] reqNacosConfig(Properties configProperties,
String[] dataIds, String groupId, ConfigType type, boolean isAutoRefresh) {
final NacosPropertySource[] propertySources = new NacosPropertySource[dataIds.length];
for (int i = 0; i < dataIds.length; i++) {
if (StringUtils.isEmpty(dataIds[i])) {
continue;
}
// Remove excess Spaces
final String dataId = environment.resolvePlaceholders(dataIds[i].trim());
final String config = NacosUtils.getContent(builder.apply(configProperties),
dataId, groupId);
final NacosPropertySource nacosPropertySource = new NacosPropertySource(
dataId, groupId,
buildDefaultPropertySourceName(dataId, groupId, configProperties),
config, type.getType());
nacosPropertySource.setDataId(dataId);
nacosPropertySource.setType(type.getType());
nacosPropertySource.setGroupId(groupId);
nacosPropertySource.setAutoRefreshed(isAutoRefresh);
logger.info("load config from nacos, data-id is : {}, group is : {}",
nacosPropertySource.getDataId(), nacosPropertySource.getGroupId());
propertySources[i] = nacosPropertySource;
DeferNacosPropertySource defer = new DeferNacosPropertySource(
nacosPropertySource, configProperties, environment);
nacosPropertySources.add(defer);
}
return propertySources;
}
public void addListenerIfAutoRefreshed() {
addListenerIfAutoRefreshed(nacosPropertySources);
}
public void addListenerIfAutoRefreshed(
final List<DeferNacosPropertySource> deferNacosPropertySources) {
for (DeferNacosPropertySource deferNacosPropertySource : deferNacosPropertySources) {
NacosPropertySourcePostProcessor.addListenerIfAutoRefreshed(
deferNacosPropertySource.getNacosPropertySource(),
deferNacosPropertySource.getProperties(),
deferNacosPropertySource.getEnvironment());
}
}
public List<DeferNacosPropertySource> getNacosPropertySources() {
return nacosPropertySources;
}
// Delay Nacos configuration data source object, used for log level of loading time,
// the cache configuration, wait for after the completion of the Spring Context
// created in the release
public static class DeferNacosPropertySource {
private final NacosPropertySource nacosPropertySource;
private final ConfigurableEnvironment environment;
private final Properties properties;
DeferNacosPropertySource(NacosPropertySource nacosPropertySource,
Properties properties, ConfigurableEnvironment environment) {
this.nacosPropertySource = nacosPropertySource;
this.properties = properties;
this.environment = environment;
}
NacosPropertySource getNacosPropertySource() {
return nacosPropertySource;
}
ConfigurableEnvironment getEnvironment() {
return environment;
}
public Properties getProperties() {
return properties;
}
}
}

View File

@ -16,73 +16,65 @@
*/
package com.alibaba.boot.nacos.config.util;
import com.alibaba.nacos.api.PropertyKeyConst;
import org.apache.commons.lang3.StringUtils;
import org.springframework.core.env.Environment;
import org.springframework.util.CollectionUtils;
import java.util.Map;
import java.util.Properties;
import com.alibaba.nacos.api.PropertyKeyConst;
import org.apache.commons.lang3.StringUtils;
import org.springframework.core.env.Environment;
import org.springframework.util.CollectionUtils;
/**
* @author <a href="mailto:liaochunyhm@live.com">liaochuntao</a>
* @since 0.2.3
*/
public class NacosPropertiesBuilder {
public static Properties buildNacosProperties(Environment environment, String serverAddr, String namespaceId,
String endpoint, String secretKey, String accessKey, String ramRoleName,
String configLongPollTimeout, String configRetryTimeout, String maxRetry,
boolean enableRemoteSyncConfig) {
public static Properties buildNacosProperties(Environment environment,
String serverAddr, String namespaceId, String endpoint, String secretKey,
String accessKey, String ramRoleName, String configLongPollTimeout,
String configRetryTimeout, String maxRetry,String contextPath, boolean enableRemoteSyncConfig,
String username, String password) {
Properties properties = new Properties();
processPropertiesData(properties,environment,serverAddr,PropertyKeyConst.SERVER_ADDR);
processPropertiesData(properties,environment,namespaceId,PropertyKeyConst.NAMESPACE);
processPropertiesData(properties,environment,endpoint,PropertyKeyConst.ENDPOINT);
processPropertiesData(properties,environment,secretKey,PropertyKeyConst.SECRET_KEY);
processPropertiesData(properties,environment,accessKey,PropertyKeyConst.ACCESS_KEY);
processPropertiesData(properties,environment,ramRoleName,PropertyKeyConst.RAM_ROLE_NAME);
processPropertiesData(properties,environment,configLongPollTimeout,PropertyKeyConst.CONFIG_LONG_POLL_TIMEOUT);
processPropertiesData(properties,environment,configRetryTimeout,PropertyKeyConst.CONFIG_RETRY_TIME);
processPropertiesData(properties,environment,contextPath,PropertyKeyConst.CONTEXT_PATH);
processPropertiesData(properties,environment,maxRetry,PropertyKeyConst.MAX_RETRY);
processPropertiesData(properties,environment,username,PropertyKeyConst.USERNAME);
processPropertiesData(properties,environment,password,PropertyKeyConst.PASSWORD);
properties.put(PropertyKeyConst.ENABLE_REMOTE_SYNC_CONFIG,
String.valueOf(enableRemoteSyncConfig));
return properties;
}
private static void processPropertiesData(Properties properties,Environment environment,String keyword,String key) {
if (StringUtils.isNotBlank(keyword)) {
properties.put(key ,environment.resolvePlaceholders(keyword));
}
}
Properties properties = new Properties();
if (StringUtils.isNotEmpty(serverAddr)) {
properties.put(PropertyKeyConst.SERVER_ADDR, serverAddr);
}
if (StringUtils.isNotEmpty(namespaceId)) {
properties.put(PropertyKeyConst.NAMESPACE, namespaceId);
}
if (StringUtils.isNotEmpty(endpoint)) {
properties.put(PropertyKeyConst.ENDPOINT, endpoint);
}
if (StringUtils.isNotEmpty(secretKey)) {
properties.put(PropertyKeyConst.SECRET_KEY, secretKey);
}
if (StringUtils.isNotEmpty(accessKey)) {
properties.put(PropertyKeyConst.ACCESS_KEY, accessKey);
}
if (StringUtils.isNoneEmpty(ramRoleName)) {
properties.put(PropertyKeyConst.RAM_ROLE_NAME, ramRoleName);
}
if (StringUtils.isNotEmpty(configLongPollTimeout)) {
properties.put(PropertyKeyConst.CONFIG_LONG_POLL_TIMEOUT,
configLongPollTimeout);
}
if (StringUtils.isNotEmpty(configRetryTimeout)) {
properties.put(PropertyKeyConst.CONFIG_RETRY_TIME, configRetryTimeout);
}
if (StringUtils.isNotEmpty(maxRetry)) {
properties.put(PropertyKeyConst.MAX_RETRY, maxRetry);
}
properties.put(PropertyKeyConst.ENABLE_REMOTE_SYNC_CONFIG,
String.valueOf(enableRemoteSyncConfig));
return properties;
}
public static void merge(Properties targetProperties, Properties sourceProperties) {
public static void merge(Properties targetProperties, Properties sourceProperties) {
if (CollectionUtils.isEmpty(sourceProperties)) {
return;
}
if (CollectionUtils.isEmpty(sourceProperties)) {
return;
}
for (Map.Entry entry : sourceProperties.entrySet()) {
String propertyName = (String) entry.getKey();
if (!targetProperties.containsKey(propertyName)) {
String propertyValue = (String) entry.getValue();
targetProperties.setProperty(propertyName, propertyValue);
}
}
for (Map.Entry entry : sourceProperties.entrySet()) {
String propertyName = (String) entry.getKey();
if (!targetProperties.containsKey(propertyName)) {
String propertyValue = (String) entry.getValue();
targetProperties.setProperty(propertyName, propertyValue);
}
}
}
}
}

View File

@ -0,0 +1,149 @@
/*
* 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.boot.nacos.config.util.log;
import com.alibaba.boot.nacos.config.properties.NacosConfigProperties;
import com.alibaba.boot.nacos.config.util.NacosConfigLoader;
import com.alibaba.nacos.api.common.Constants;
import com.alibaba.nacos.api.config.ConfigService;
import com.alibaba.nacos.api.config.listener.AbstractListener;
import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.client.config.utils.ConcurrentDiskUtil;
import com.alibaba.nacos.client.config.utils.JvmUtil;
import com.alibaba.nacos.client.logging.NacosLogging;
import com.alibaba.nacos.client.utils.LogUtils;
import com.alibaba.nacos.common.utils.IoUtils;
import com.alibaba.nacos.common.utils.StringUtils;
import com.alibaba.nacos.spring.util.NacosUtils;
import org.slf4j.Logger;
import org.springframework.boot.context.logging.LoggingApplicationListener;
import org.springframework.boot.logging.LoggingInitializationContext;
import org.springframework.boot.logging.LoggingSystem;
import org.springframework.boot.logging.LoggingSystemFactory;
import org.springframework.core.env.ConfigurableEnvironment;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import java.util.function.Function;
/**
* Start:
* Step1: get the log XML configuration from the configuration center
* Step2: modify the springboot log configuration path
* Modifying log configuration during operation:
* Clean up the configuration through LoggingSystem and reload the configuration.
*
* @author <a href="mailto:hujun3@xiaomi.com">hujun</a>
*/
public class LogAutoFreshProcess {
private static final Logger LOGGER = LogUtils.logger(LogAutoFreshProcess.class);
private final NacosConfigProperties nacosConfigProperties;
private final ConfigurableEnvironment environment;
private final NacosConfigLoader nacosConfigLoader;
private final Function<Properties, ConfigService> builder;
private static final List<String> LOG_DATA_ID = new ArrayList<>();
private static final String LOG_CACHE_BASE = System.getProperty("JM.SNAPSHOT.PATH", System.getProperty("user.home")) + File.separator + "nacos"
+ File.separator + "logConfig";
static {
LOG_DATA_ID.add("logback.xml");
LOG_DATA_ID.add("log4j2.xml");
}
public static LogAutoFreshProcess build(ConfigurableEnvironment environment, NacosConfigProperties nacosConfigProperties, NacosConfigLoader nacosConfigLoader, Function<Properties, ConfigService> builder) {
return new LogAutoFreshProcess(environment, nacosConfigProperties, nacosConfigLoader, builder);
}
private LogAutoFreshProcess(ConfigurableEnvironment environment, NacosConfigProperties nacosConfigProperties, NacosConfigLoader nacosConfigLoader, Function<Properties, ConfigService> builder) {
this.nacosConfigProperties = nacosConfigProperties;
this.environment = environment;
this.nacosConfigLoader = nacosConfigLoader;
this.builder = builder;
}
public void process() {
final String groupName = environment
.resolvePlaceholders(nacosConfigProperties.getGroup());
ConfigService configService = builder.apply(nacosConfigLoader.getGlobalProperties());
for (String dataId : LOG_DATA_ID) {
String content = NacosUtils.getContent(configService, dataId, groupName);
if (StringUtils.isNotBlank(content)) {
writeLogFile(content, dataId);
System.setProperty(LoggingApplicationListener.CONFIG_PROPERTY, LOG_CACHE_BASE + File.separator + dataId);
registerListener(configService, dataId, groupName);
return;
}
}
}
private void registerListener(ConfigService configService, String dataId, String groupName) {
try {
configService.addListener(dataId, groupName, new AbstractListener() {
@Override
public void receiveConfigInfo(String configInfo) {
if (StringUtils.isNotBlank(configInfo)) {
writeLogFile(configInfo, dataId);
reloadConfig(LOG_CACHE_BASE + File.separator + dataId);
}
}
});
} catch (NacosException e) {
throw new RuntimeException("ConfigService can't add Listener with dataId : " + dataId, e);
}
}
private void writeLogFile(String content, String dataId) {
File file = new File(LOG_CACHE_BASE, dataId);
File parentFile = file.getParentFile();
if (!parentFile.exists()) {
boolean isMdOk = parentFile.mkdirs();
if (!isMdOk) {
LOGGER.error("save log cache error");
}
}
try {
if (JvmUtil.isMultiInstance()) {
ConcurrentDiskUtil.writeFileContent(file, content, Constants.ENCODE);
} else {
IoUtils.writeStringToFile(file, content, Constants.ENCODE);
}
} catch (IOException e) {
throw new RuntimeException("write log file fail");
}
}
private void reloadConfig(String logPath) {
LoggingSystem loggingSystem = LoggingSystemFactory.fromSpringFactories()
.getLoggingSystem(this.getClass().getClassLoader());
loggingSystem.cleanUp();
loggingSystem.initialize(new LoggingInitializationContext(environment),
logPath, null);
NacosLogging.getInstance().loadConfiguration();
}
}

View File

@ -0,0 +1,9 @@
{
"resources": {
"includes": [
{
"pattern": "\\QMETA-INF/services/com.alibaba.nacos.spring.util.ConfigParse\\E"
}
]
}
}

View File

@ -0,0 +1 @@
com.alibaba.boot.nacos.config.support.MultiProfilesYamlConfigParseSupport

View File

@ -3,4 +3,7 @@ org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
#org.springframework.context.ApplicationContextInitializer=\
# com.alibaba.boot.nacos.config.autoconfigure.NacosConfigApplicationContextInitializer
org.springframework.boot.env.EnvironmentPostProcessor=\
com.alibaba.boot.nacos.config.autoconfigure.NacosConfigEnvironmentProcessor
com.alibaba.boot.nacos.config.autoconfigure.NacosConfigEnvironmentProcessor,\
com.alibaba.boot.nacos.config.support.MultiProfilesYamlConfigParseSupport
org.springframework.context.ApplicationListener=\
com.alibaba.boot.nacos.config.logging.NacosLoggingListener

View File

@ -0,0 +1,4 @@
com.alibaba.boot.nacos.config.autoconfigure.NacosConfigAutoConfiguration
com.alibaba.boot.nacos.config.autoconfigure.NacosConfigEnvironmentProcessor
com.alibaba.boot.nacos.config.support.MultiProfilesYamlConfigParseSupport
com.alibaba.boot.nacos.config.logging.NacosLoggingListener

View File

@ -0,0 +1,46 @@
/*
* 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.boot.nacos.autoconfigure;
import com.alibaba.boot.nacos.config.autoconfigure.NacosBootConfigException;
import org.junit.Assert;
import org.junit.Test;
/**
* {@link NacosBootConfigException} Test
* @ClassName: NacosBootConfigExceptionTest
* @Author: ChenHao26
* @Date: 2022/8/12 15:56
*/
public class NacosBootConfigExceptionTest {
@Test
public void getCons() {
try {
testMethod("spring boot");
}catch (Exception e) {
Assert.assertTrue(e instanceof NacosBootConfigException);
}
}
private void testMethod(String str) {
if (str.startsWith("spring")) {
throw new NacosBootConfigException(new Throwable());
}
}
}

View File

@ -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.boot.nacos.autoconfigure;
import com.alibaba.boot.nacos.config.autoconfigure.NacosConfigApplicationContextInitializer;
import com.alibaba.boot.nacos.config.autoconfigure.NacosConfigAutoConfiguration;
import com.alibaba.boot.nacos.config.autoconfigure.NacosConfigBootBeanDefinitionRegistrar;
import com.alibaba.boot.nacos.config.autoconfigure.NacosConfigEnvironmentProcessor;
import com.alibaba.boot.nacos.config.properties.NacosConfigProperties;
import com.alibaba.boot.nacos.config.util.NacosConfigLoader;
import com.alibaba.boot.nacos.config.util.NacosConfigLoaderFactory;
import com.alibaba.boot.nacos.config.util.NacosConfigPropertiesUtils;
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.boot.test.context.SpringBootTest;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
/**
* {@link NacosConfigApplicationContextInitializer} Test
* @ClassName: NacosConfigApplicationContextInitializerTest
* @Author: ChenHao26
* @Date: 2022/8/12 15:25
*/
@RunWith(SpringJUnit4ClassRunner.class)
@TestPropertySource(properties = { "nacos.config.server-addr=localhost" })
@SpringBootTest(classes = { NacosConfigAutoConfiguration.class })
public class NacosConfigApplicationContextInitializerTest {
private NacosConfigApplicationContextInitializer nacosConfigApplicationContextInitializer;
@Autowired
private ConfigurableEnvironment environment;
@Autowired
private NacosConfigProperties nacosConfigProperties;
@Autowired
private ConfigurableApplicationContext context;
@Before
public void testNacosConfigApplicationContextInitializer() {
nacosConfigApplicationContextInitializer = new NacosConfigApplicationContextInitializer(new NacosConfigEnvironmentProcessor());
}
@Test
public void initialize(){
try {
nacosConfigProperties = NacosConfigPropertiesUtils
.buildNacosConfigProperties(environment);
Assert.assertNotNull(nacosConfigProperties);
NacosConfigLoader singleton = NacosConfigLoaderFactory.getSingleton(null);
Assert.assertNotNull(singleton);
nacosConfigApplicationContextInitializer.initialize(context);
} catch (Exception e) {
Assert.assertNotNull(e);
}
}
}

View File

@ -19,6 +19,7 @@ package com.alibaba.boot.nacos.autoconfigure;
import java.util.Properties;
import com.alibaba.boot.nacos.config.autoconfigure.NacosConfigAutoConfiguration;
import com.alibaba.boot.nacos.config.binder.NacosBootConfigurationPropertiesBinder;
import com.alibaba.boot.nacos.config.properties.NacosConfigProperties;
import com.alibaba.nacos.api.PropertyKeyConst;
import com.alibaba.nacos.api.annotation.NacosInjected;
@ -63,9 +64,9 @@ public class NacosConfigAutoConfigurationTest {
Assert.assertEquals("localhost", nacosConfigProperties.getServerAddr());
}
@Test(expected = NoSuchBeanDefinitionException.class)
@Test
public void testNacosConfigGlobalBean() {
Assert.assertNull(applicationContext
Assert.assertNotNull(applicationContext
.getBean(NacosBeanUtils.GLOBAL_NACOS_PROPERTIES_BEAN_NAME));
}
@ -84,4 +85,8 @@ public class NacosConfigAutoConfigurationTest {
properties.getProperty(PropertyKeyConst.SERVER_ADDR));
}
@Test
public void testNacosConfigBootBeanDefinitionRegistrar() {
Assert.assertNotNull(applicationContext.getBean(NacosBootConfigurationPropertiesBinder.BEAN_NAME));
}
}

View File

@ -0,0 +1,69 @@
/*
* 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.boot.nacos.autoconfigure;
import com.alibaba.boot.nacos.config.autoconfigure.NacosConfigAutoConfiguration;
import com.alibaba.boot.nacos.config.autoconfigure.NacosConfigBootBeanDefinitionRegistrar;
import com.alibaba.boot.nacos.config.binder.NacosBootConfigurationPropertiesBinder;
import com.alibaba.nacos.client.utils.LogUtils;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.slf4j.Logger;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
/**
* {@link NacosConfigBootBeanDefinitionRegistrar} Test
* @ClassName: NacosConfigBootBeanDefinitionRegistrarTest
* @Author: ChenHao26
* @Date: 2022/8/12 15:38
*/
@RunWith(SpringJUnit4ClassRunner.class)
@TestPropertySource(properties = { "nacos.config.server-addr=localhost" })
@SpringBootTest(classes = { NacosConfigAutoConfiguration.class })
public class NacosConfigBootBeanDefinitionRegistrarTest {
private static final Logger LOGGER = LogUtils.logger(NacosConfigBootBeanDefinitionRegistrarTest.class);
private NacosConfigBootBeanDefinitionRegistrar nacosConfigBootBeanDefinitionRegistrar;
@Before
public void setup() {
nacosConfigBootBeanDefinitionRegistrar = new NacosConfigBootBeanDefinitionRegistrar();
}
@Test
public void setBeanFactory(){
try {
BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition("beanName");
Assert.assertNotNull(builder);
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
nacosConfigBootBeanDefinitionRegistrar.setBeanFactory(beanFactory);
Assert.assertNotNull(beanFactory.getBeanDefinition(NacosBootConfigurationPropertiesBinder.BEAN_NAME));
nacosConfigBootBeanDefinitionRegistrar.setBeanFactory(beanFactory);
}catch (Exception e) {
LOGGER.error("error info: {}",e.toString());
Assert.assertNull(e);
}
}
}

View File

@ -0,0 +1,85 @@
/*
* 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.boot.nacos.autoconfigure;
import com.alibaba.boot.nacos.config.autoconfigure.NacosConfigAutoConfiguration;
import com.alibaba.boot.nacos.config.autoconfigure.NacosConfigEnvironmentProcessor;
import com.alibaba.boot.nacos.config.binder.NacosBootConfigurationPropertiesBinder;
import com.alibaba.boot.nacos.config.properties.NacosConfigProperties;
import com.alibaba.boot.nacos.config.util.NacosConfigPropertiesUtils;
import com.alibaba.nacos.client.config.NacosConfigService;
import com.alibaba.nacos.client.utils.LogUtils;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
/**
* {@link NacosBootConfigurationPropertiesBinder} Test
* @ClassName: NacosConfigEnvironmentProcessorTest
* @Author: ChenHao26
* @Date: 2022/8/12 15:43
*/
@RunWith(SpringJUnit4ClassRunner.class)
@TestPropertySource(properties = { "nacos.config.server-addr=localhost" })
@SpringBootTest(classes = { NacosConfigAutoConfiguration.class })
public class NacosConfigEnvironmentProcessorTest {
private NacosConfigEnvironmentProcessor nacosConfigEnvironmentProcessor;
@Autowired
private ConfigurableEnvironment environment;
private static final Logger LOGGER = LogUtils.logger(NacosConfigEnvironmentProcessorTest.class);
@Mock
private NacosConfigProperties nacosConfigProperties;
@Before
public void setup() {
nacosConfigEnvironmentProcessor = new NacosConfigEnvironmentProcessor();
}
@Test
public void postProcessEnvironment() {
try {
NacosConfigProperties nacosConfigProperties1 = NacosConfigPropertiesUtils.buildNacosConfigProperties(
environment);
Assert.assertFalse(nacosConfigProperties1.isEnableRemoteSyncConfig());
nacosConfigEnvironmentProcessor.postProcessEnvironment(environment, new SpringApplication());
}catch (Exception e) {
LOGGER.error("error info :{} ",e);
Assert.assertNull(e);
}
}
@Test
public void getOrder() {
int order = nacosConfigEnvironmentProcessor.getOrder();
Assert.assertNotNull(order);
}
}

View File

@ -0,0 +1,108 @@
/*
* 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.boot.nacos.binder;
import com.alibaba.boot.nacos.config.autoconfigure.NacosConfigAutoConfiguration;
import com.alibaba.boot.nacos.config.binder.NacosBootConfigurationPropertiesBinder;
import com.alibaba.nacos.api.config.ConfigService;
import com.alibaba.nacos.api.config.annotation.NacosConfigurationProperties;
import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.spring.context.event.config.EventPublishingConfigService;
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.boot.test.context.SpringBootTest;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import java.lang.reflect.Method;
/**
* {@link NacosBootConfigurationPropertiesBinder} Test
* @ClassName: NacosBootConfigurationPropertiesBinderTest
* @Author: ChenHao26
* @Date: 2022/8/12 16:00
*/
@RunWith(SpringJUnit4ClassRunner.class)
@TestPropertySource(properties = { "nacos.config.server-addr=localhost" })
@SpringBootTest(classes = { NacosConfigAutoConfiguration.class })
public class NacosBootConfigurationPropertiesBinderTest {
private Binder binder;
@Autowired
private ConfigurableApplicationContext context;
@Before
public void setup() {
binder = new Binder(context);
}
@Test
public void findFactoryMethod(){
Method beanName = binder.findFactoryMethod(NacosBootConfigurationPropertiesBinder.BEAN_NAME);
Assert.assertNull(beanName);
}
@Test
public void testDoBind() {
People people = new People();
binder.doBind(people, "people", "people", "people", "properties",
People.class.getAnnotation(NacosConfigurationProperties.class), "people.name=SuperZ1999\npeople.age=24",
new EventPublishingConfigService(null, null, context, null));
Assert.assertEquals(people.getName(), "SuperZ1999");
Assert.assertEquals(people.getAge(), 24);
}
static class Binder extends NacosBootConfigurationPropertiesBinder {
public Binder(ConfigurableApplicationContext applicationContext) {
super(applicationContext);
}
@Override
protected void doBind(Object bean, String beanName, String dataId, String groupId, String configType, NacosConfigurationProperties properties, String content, ConfigService configService) {
super.doBind(bean, beanName, dataId, groupId, configType, properties, content, configService);
}
}
@NacosConfigurationProperties(prefix = "people", dataId = "people", groupId = "people")
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;
}
}
}

View File

@ -0,0 +1,162 @@
/*
* 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.boot.nacos.config.support;
import com.alibaba.boot.nacos.config.autoconfigure.NacosConfigAutoConfiguration;
import com.alibaba.nacos.spring.util.ConfigParseUtils;
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.boot.test.context.SpringBootTest;
import org.springframework.core.env.Environment;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
/**
* {@link MultiProfilesYamlConfigParseSupport} Test
*
* @author <a href="mailto:yanglu_u@126.com">dbses</a>
*/
public class MultiProfilesYamlConfigParseSupportTest {
@RunWith(SpringJUnit4ClassRunner.class)
@ActiveProfiles({"alpha"})
@SpringBootTest(classes = {NacosConfigAutoConfiguration.class})
public static class OneProfiles {
@Autowired
private Environment environment;
@Before
public void setUp() {
// because MultiProfilesYamlConfigParseSupport # postProcessEnvironment() run once,
// so it should set profilesArray before test
MultiProfilesYamlConfigParseSupport.setProfileArray(environment.getActiveProfiles());
}
@Test
public void oneProfiles_normal() {
String content = "test1:\n" +
" config: 2\n" +
"\n" +
"---\n" +
"spring:\n" +
" profiles: alpha\n" +
"test1:\n" +
" config: alpha\n" +
"\n" +
"---\n" +
"spring:\n" +
" profiles: beta\n" +
"test1:\n" +
" config: beta";
Assert.assertEquals(environment.getActiveProfiles()[0], "alpha");
Object result = ConfigParseUtils.toProperties("test.yaml", "test", content, "yaml")
.get("test1.config");
Assert.assertEquals("alpha", result);
}
@Test
public void oneProfiles_when_content_profiles_isnull() {
String content = "test1:\n" +
" config: 2\n" +
"\n" +
"---\n" +
"test1:\n" +
" config: alpha\n" +
"\n" +
"---\n" +
"test1:\n" +
" config: beta";
Object result = ConfigParseUtils.toProperties("test.yaml", "test", content, "yaml")
.get("test1.config");
Assert.assertEquals("beta", result);
}
}
@RunWith(SpringJUnit4ClassRunner.class)
@ActiveProfiles({"alpha", "beta"})
@SpringBootTest(classes = {NacosConfigAutoConfiguration.class})
public static class TwoProfiles {
@Autowired
private Environment environment;
@Before
public void setUp() {
MultiProfilesYamlConfigParseSupport.setProfileArray(environment.getActiveProfiles());
}
@Test
public void twoProfiles_normal() {
String content = "test1:\n" +
" config: 2\n" +
"\n" +
"---\n" +
"spring:\n" +
" profiles: alpha\n" +
"test1:\n" +
" config: alpha\n" +
"\n" +
"---\n" +
"spring:\n" +
" profiles: beta\n" +
"test1:\n" +
" config: beta";
Assert.assertEquals(environment.getActiveProfiles()[0], "alpha");
Assert.assertEquals(environment.getActiveProfiles()[1], "beta");
Object result = ConfigParseUtils.toProperties("test.yaml", "test", content, "yaml")
.get("test1.config");
Assert.assertEquals("beta", result);
}
}
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = {NacosConfigAutoConfiguration.class})
public static class NoProfiles {
@Autowired
private Environment environment;
@Test
public void noProfiles_normal() {
String content = "test1:\n" +
" config: 2\n" +
"\n" +
"---\n" +
"spring:\n" +
" profiles: default\n" +
"test1:\n" +
" config: default\n" +
"\n" +
"---\n" +
"spring:\n" +
" profiles: beta\n" +
"test1:\n" +
" config: beta";
Assert.assertEquals(environment.getActiveProfiles().length, 0);
Object result = ConfigParseUtils.toProperties("test.yaml", "test", content, "yaml")
.get("test1.config");
Assert.assertEquals("default", result);
}
}
}

View File

@ -0,0 +1,59 @@
/*
* 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.boot.nacos.logging;
import com.alibaba.boot.nacos.config.logging.NacosLoggingListener;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.springframework.core.ResolvableType;
import java.lang.reflect.Type;
/**
* {@link NacosLoggingListener} Test
* @ClassName: AttributeExtractTaskTest
* @Author: ChenHao26
* @Date: 2022/8/12 15:08
*/
public class NacosLoggingListenerTest {
private NacosLoggingListener nacosLoggingListener;
@Before
public void setup() {
nacosLoggingListener = new NacosLoggingListener();
}
@Test
public void supportsEventType() {
boolean result = nacosLoggingListener.supportsEventType(ResolvableType.forType(new Type() {
@Override
public String getTypeName() {
return Type.super.getTypeName();
}
}));
Assert.assertEquals(result, false);
}
@Test
public void getOrder() {
int order = nacosLoggingListener.getOrder();
Assert.assertNotNull(order);
}
}

View File

@ -0,0 +1,65 @@
/*
* 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.boot.nacos.util;
import com.alibaba.boot.nacos.config.autoconfigure.NacosConfigAutoConfiguration;
import com.alibaba.boot.nacos.config.util.AttributeExtractTask;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.MutablePropertySources;
import org.springframework.core.env.PropertySources;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import java.util.Map;
/**
* {@link AttributeExtractTask} Test
* @ClassName: AttributeExtractTaskTest
* @Author: ChenHao26
* @Date: 2022/8/12 15:08
*/
@RunWith(SpringJUnit4ClassRunner.class)
@TestPropertySource(properties = { "nacos.config.server-addr=localhost" })
@SpringBootTest(classes = { NacosConfigAutoConfiguration.class })
public class AttributeExtractTaskTest {
private AttributeExtractTask attributeExtractTask;
@Autowired
private ConfigurableEnvironment environment ;
@Before
public void setUp() {
environment.setDefaultProfiles("prefix01");
attributeExtractTask = new AttributeExtractTask("nacos.config",environment);
}
@Test
public void call() throws Exception{
Map<String, String> map = attributeExtractTask.call();
Assert.assertEquals(map.get("nacos.config.server-addr"), "localhost");
}
}

View File

@ -0,0 +1,87 @@
/*
* 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.boot.nacos.util;
import com.alibaba.boot.nacos.config.autoconfigure.NacosConfigAutoConfiguration;
import com.alibaba.boot.nacos.config.properties.NacosConfigProperties;
import com.alibaba.boot.nacos.config.util.NacosConfigLoader;
import com.alibaba.boot.nacos.config.util.NacosConfigLoaderFactory;
import com.alibaba.nacos.api.config.ConfigService;
import com.alibaba.nacos.api.config.ConfigType;
import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.client.config.NacosConfigService;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import java.util.Properties;
import java.util.function.Function;
/**
* @ClassName: NacosConfigLoaderFactoryTest
* @Author: ChenHao26
* @Date: 2022/8/12 16:42
*/
@RunWith(SpringJUnit4ClassRunner.class)
@TestPropertySource(properties = { "nacos.config.server-addr=localhost" })
@SpringBootTest(classes = { NacosConfigAutoConfiguration.class })
public class NacosConfigLoaderFactoryTest {
private NacosConfigProperties nacosConfigProperties;
private Properties globalProperties;
private Function<Properties, ConfigService> builder;
@Before
public void setup() {
nacosConfigProperties = new NacosConfigProperties();
nacosConfigProperties.setServerAddr("localhost");
nacosConfigProperties.setUsername("nacos");
nacosConfigProperties.setPassword("nacos");
nacosConfigProperties.setMaxRetry("4");
nacosConfigProperties.setType(ConfigType.TEXT);
nacosConfigProperties.setDataId("xiaomi");
nacosConfigProperties.setGroup("group01");
nacosConfigProperties.setAutoRefresh(true);
nacosConfigProperties.setEndpoint("localhost");
globalProperties = new Properties();
globalProperties.setProperty("maxRetry","3");
globalProperties.setProperty("content","key=01");
globalProperties.setProperty("endpoint","localhost");
builder = properties -> {
try {
return new NacosConfigService(globalProperties);
} catch (NacosException e) {
throw new RuntimeException(e);
}
};
}
@Test
public void getSingleton() {
NacosConfigLoader singleton = NacosConfigLoaderFactory.getSingleton(builder);
NacosConfigLoader singleton2 = NacosConfigLoaderFactory.getSingleton(builder);
// Verify that it is the same object
Assert.assertEquals(singleton2, singleton);
}
}

View File

@ -0,0 +1,116 @@
/*
* 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.boot.nacos.util;
import com.alibaba.boot.nacos.autoconfigure.NacosConfigEnvironmentProcessorTest;
import com.alibaba.boot.nacos.config.autoconfigure.NacosConfigAutoConfiguration;
import com.alibaba.boot.nacos.config.properties.NacosConfigProperties;
import com.alibaba.boot.nacos.config.util.NacosConfigLoader;
import com.alibaba.nacos.api.config.ConfigService;
import com.alibaba.nacos.api.config.ConfigType;
import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.client.config.NacosConfigService;
import com.alibaba.nacos.client.utils.LogUtils;
import com.alibaba.nacos.spring.core.env.NacosPropertySourcePostProcessor;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import java.util.LinkedList;
import java.util.List;
import java.util.Properties;
import java.util.function.Function;
/**
* @ClassName: NacosConfigLoaderTest
* @Author: ChenHao26
* @Date: 2022/8/12 16:12
*/
@RunWith(SpringJUnit4ClassRunner.class)
@TestPropertySource(properties = { "nacos.config.server-addr=localhost" })
@SpringBootTest(classes = { NacosConfigAutoConfiguration.class })
public class NacosConfigLoaderTest {
private NacosConfigLoader nacosConfigLoader;
private NacosConfigProperties nacosConfigProperties;
private Properties globalProperties;
@Autowired
private ConfigurableEnvironment environment;
private Function<Properties, ConfigService> builder;
private List<NacosConfigLoader.DeferNacosPropertySource> nacosPropertySources;
private static final Logger LOGGER = LogUtils.logger(NacosConfigEnvironmentProcessorTest.class);
private NacosPropertySourcePostProcessor nacosPropertySourcePostProcessor;
@Before
public void setup() {
nacosConfigProperties = new NacosConfigProperties();
nacosConfigProperties.setServerAddr("localhost");
nacosConfigProperties.setUsername("nacos");
nacosConfigProperties.setPassword("nacos");
nacosConfigProperties.setMaxRetry("4");
nacosConfigProperties.setType(ConfigType.TEXT);
nacosConfigProperties.setDataId("xiaomi");
nacosConfigProperties.setGroup("group01");
nacosConfigProperties.setAutoRefresh(true);
nacosConfigProperties.setEndpoint("localhost");
globalProperties = new Properties();
globalProperties.setProperty("maxRetry","3");
globalProperties.setProperty("content","key=01");
globalProperties.setProperty("endpoint","localhost");
builder = properties -> {
try {
return new NacosConfigService(globalProperties);
} catch (NacosException e) {
throw new RuntimeException(e);
}
};
nacosPropertySources = new LinkedList<>();
nacosConfigLoader = new NacosConfigLoader(builder);
nacosPropertySourcePostProcessor = new NacosPropertySourcePostProcessor();
}
@Test
public void buildGlobalNacosProperties() {
Properties properties = nacosConfigLoader.buildGlobalNacosProperties(environment, nacosConfigProperties);
LOGGER.info("buildGlobalNacosProperties properties : {}", properties);
Assert.assertNotNull(properties);
Assert.assertEquals(properties.size(), 6);
}
@Test
public void addListenerIfAutoRefreshed() {
nacosConfigLoader.addListenerIfAutoRefreshed();
List<NacosConfigLoader.DeferNacosPropertySource> propertySources = nacosConfigLoader.getNacosPropertySources();
Assert.assertEquals(propertySources.size(), 0);
}
}

View File

@ -0,0 +1,56 @@
/*
*
* * 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.boot.nacos.util;
import com.alibaba.boot.nacos.config.autoconfigure.NacosConfigAutoConfiguration;
import com.alibaba.boot.nacos.config.properties.NacosConfigProperties;
import com.alibaba.boot.nacos.config.util.NacosConfigPropertiesUtils;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
/**
* {@link NacosConfigPropertiesUtils} Test
* @ClassName: NacosConfigPropertiesUtilsTest
* @Author: SuperZ1999
* @Date: 2023/9/28
*/
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = { NacosConfigAutoConfiguration.class })
@TestPropertySource(properties = {
"nacos.config.server-addr=8.8.8.8",
"nacos.config.password=123456"
})
public class NacosConfigPropertiesUtilsTest {
@Autowired
private ConfigurableEnvironment environment;
@Test
public void testBuildNacosConfigProperties() {
NacosConfigProperties properties = NacosConfigPropertiesUtils.buildNacosConfigProperties(environment);
Assert.assertEquals(properties.getServerAddr(), "8.8.8.8");
Assert.assertEquals(properties.getPassword(), "123456");
}
}

View File

@ -0,0 +1,78 @@
/*
* 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.boot.nacos.util;
import com.alibaba.boot.nacos.config.autoconfigure.NacosConfigAutoConfiguration;
import com.alibaba.boot.nacos.config.util.NacosPropertiesBuilder;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.core.env.Environment;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import java.util.Properties;
/**
* @ClassName: NacosPropertiesBuilderTest
* @Author: ChenHao26
* @Date: 2022/8/12 16:49
*/
@RunWith(SpringJUnit4ClassRunner.class)
@TestPropertySource(properties = { "nacos.config.server-addr=localhost" })
@SpringBootTest(classes = { NacosConfigAutoConfiguration.class })
public class NacosPropertiesBuilderTest {
@Autowired
private Environment environment;
@Test
public void testBuildNacosProperties() {
String serverAddr = "${nacos.config.server-addr}";
String namespaceId = "namespaceId";
String secretKey = "secretKey";
String ramRoleName = "ramRoleName";
String configLongPollTimeout = "configLongPollTimeout";
String configRetryTimeout = "configRetryTimeout";
String maxRetry = "maxRetry";
String enableRemoteSyncConfig = "enableRemoteSyncConfig";
String username = "nacos";
String password = "password";
Properties properties = NacosPropertiesBuilder.buildNacosProperties(environment, serverAddr, namespaceId, secretKey,
"ak", ramRoleName, configLongPollTimeout, configRetryTimeout, maxRetry, null,enableRemoteSyncConfig, true,
username, password);
Assert.assertEquals(properties.size(), 12);
Assert.assertEquals(properties.get("serverAddr"), "localhost");
}
@Test
public void testMerge() {
Properties sourceProperties = new Properties();
sourceProperties.put("name", "SuperZ1999");
sourceProperties.put("age", 24);
Properties targetProperties = new Properties();
targetProperties.put("age", 99);
NacosPropertiesBuilder.merge(targetProperties, sourceProperties);
Assert.assertEquals(targetProperties.get("name"), "SuperZ1999");
Assert.assertEquals(targetProperties.get("age"), 99);
}
}

View File

@ -0,0 +1,51 @@
/*
* 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.boot.nacos.util.editor;
import com.alibaba.boot.nacos.config.util.editor.NacosCharSequenceEditor;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
/**
* @ClassName: NacosCharSequenceEditorTest
* @Author: ChenHao26
* @Date: 2022/8/12 17:00
*/
public class NacosCharSequenceEditorTest {
public NacosCharSequenceEditor nacosCharSequenceEditor;
@Before
public void setup() {
nacosCharSequenceEditor = new NacosCharSequenceEditor();
}
@Test
public void setValue() {
nacosCharSequenceEditor.setValue("nacosTest");
String asText = nacosCharSequenceEditor.getAsText();
Assert.assertEquals(asText,"nacosTest");
}
@Test
public void getAsText() {
String str = nacosCharSequenceEditor.getAsText();
Assert.assertEquals(str, "null");
}
}

View File

@ -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.boot.nacos.util.editor;
import com.alibaba.boot.nacos.config.util.editor.NacosCustomBooleanEditor;
import org.junit.Assert;
import org.junit.Test;
/**
* {@link NacosCustomBooleanEditor} Test
* @ClassName: NacosCustomBooleanEditorTest
* @Author: SuperZ1999
* @Date: 2023/9/28
*/
public class NacosCustomBooleanEditorTest {
@Test
public void testAllowEmpty() {
NacosCustomBooleanEditor booleanEditor = new NacosCustomBooleanEditor(true);
booleanEditor.setValue("");
Assert.assertEquals(booleanEditor.getAsText(), "false");
booleanEditor.setValue("true");
Assert.assertEquals(booleanEditor.getAsText(), "true");
}
@Test(expected = IllegalArgumentException.class)
public void testNotAllowEmpty() {
NacosCustomBooleanEditor booleanEditor = new NacosCustomBooleanEditor(false);
booleanEditor.setValue("true");
Assert.assertEquals(booleanEditor.getAsText(), "true");
booleanEditor.setValue("");
}
@Test
public void testCustomBooleanString() {
NacosCustomBooleanEditor booleanEditor = new NacosCustomBooleanEditor("TRUE", "FALSE", true);
booleanEditor.setValue("");
Assert.assertEquals(booleanEditor.getAsText(), "FALSE");
booleanEditor.setValue("TRUE");
Assert.assertEquals(booleanEditor.getAsText(), "TRUE");
booleanEditor.setValue("false");
Assert.assertEquals(booleanEditor.getAsText(), "FALSE");
}
}

View File

@ -18,7 +18,7 @@
<parent>
<groupId>com.alibaba.boot</groupId>
<artifactId>nacos-spring-boot-parent</artifactId>
<version>0.2.4</version>
<version>${revision}</version>
<relativePath>../nacos-spring-boot-parent</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
@ -40,6 +40,18 @@
<dependency>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-spring-context</artifactId>
<exclusions>
<exclusion>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-client</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-client</artifactId>
<version>${nacos.version}</version>
</dependency>
<dependency>
@ -52,5 +64,10 @@
<artifactId>nacos-spring-boot-base</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.boot</groupId>
<artifactId>nacos-spring-boot-aot</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -18,7 +18,7 @@
<parent>
<artifactId>nacos-spring-boot-parent</artifactId>
<groupId>com.alibaba.boot</groupId>
<version>0.2.4</version>
<version>${revision}</version>
<relativePath>../nacos-spring-boot-parent/pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
@ -81,7 +81,20 @@
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-spring-context</artifactId>
<optional>true</optional>
<exclusions>
<exclusion>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-client</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-client</artifactId>
<version>${nacos.version}</version>
</dependency>
<!-- Test Dependencies -->
<dependency>

View File

@ -17,8 +17,7 @@
package com.alibaba.boot.nacos.discovery.actuate.autoconfigure;
import com.alibaba.boot.nacos.discovery.actuate.endpoint.NacosDiscoveryEndpoint;
import org.springframework.boot.actuate.autoconfigure.endpoint.condition.ConditionalOnEnabledEndpoint;
import org.springframework.boot.actuate.autoconfigure.endpoint.condition.ConditionalOnAvailableEndpoint;
import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
@ -35,7 +34,7 @@ public class NacosDiscoveryEndpointsAutoConfiguration {
@Bean
@ConditionalOnMissingBean
@ConditionalOnEnabledEndpoint
@ConditionalOnAvailableEndpoint
public NacosDiscoveryEndpoint nacosDiscoveryEndpoint() {
return new NacosDiscoveryEndpoint();
}

View File

@ -22,13 +22,14 @@ import java.util.Properties;
import com.alibaba.boot.nacos.common.PropertiesUtils;
import com.alibaba.boot.nacos.discovery.NacosDiscoveryConstants;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.nacos.api.naming.NamingService;
import com.alibaba.nacos.common.utils.JacksonUtils;
import com.alibaba.nacos.spring.factory.CacheableEventPublishingNacosServiceFactory;
import com.alibaba.nacos.spring.factory.NacosServiceFactory;
import com.alibaba.nacos.spring.util.NacosUtils;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
import org.springframework.boot.actuate.endpoint.annotation.ReadOperation;
@ -61,13 +62,13 @@ public class NacosDiscoveryEndpoint {
NacosServiceFactory nacosServiceFactory = CacheableEventPublishingNacosServiceFactory
.getSingleton();
JSONArray array = new JSONArray();
ArrayNode array = JacksonUtils.createEmptyArrayNode();
for (NamingService namingService : nacosServiceFactory.getNamingServices()) {
JSONObject jsonObject = new JSONObject();
ObjectNode jsonObject = JacksonUtils.createEmptyJsonNode();
try {
jsonObject.put("servicesOfServer",
jsonObject.putPOJO("servicesOfServer",
namingService.getServicesOfServer(0, PAGE_SIZE));
jsonObject.put("subscribeServices", namingService.getSubscribeServices());
jsonObject.putPOJO("subscribeServices", namingService.getSubscribeServices());
array.add(jsonObject);
}
catch (Exception e) {

View File

@ -19,8 +19,8 @@ package com.alibaba.boot.nacos.discovery.actuate.health;
import java.util.Properties;
import com.alibaba.boot.nacos.common.PropertiesUtils;
import com.alibaba.fastjson.JSON;
import com.alibaba.nacos.api.naming.NamingService;
import com.alibaba.nacos.common.utils.JacksonUtils;
import com.alibaba.nacos.spring.factory.CacheableEventPublishingNacosServiceFactory;
import com.alibaba.nacos.spring.factory.NacosServiceFactory;
import com.alibaba.nacos.spring.metadata.NacosServiceMetaData;
@ -54,7 +54,7 @@ public class NacosDiscoveryHealthIndicator extends AbstractHealthIndicator {
NacosServiceMetaData nacosServiceMetaData = (NacosServiceMetaData) namingService;
Properties properties = nacosServiceMetaData.getProperties();
builder.withDetail(
JSON.toJSONString(
JacksonUtils.toJson(
PropertiesUtils.extractSafeProperties(properties)),
namingService.getServerStatus());
}

View File

@ -0,0 +1,2 @@
com.alibaba.boot.nacos.discovery.actuate.autoconfigure.NacosDiscoveryEndpointsAutoConfiguration
com.alibaba.boot.nacos.discovery.actuate.autoconfigure.NacosDiscoveryHealthIndicatorAutoConfiguration

View File

@ -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.boot.nacos.actuate.autoconfigure;
import com.alibaba.boot.nacos.discovery.actuate.autoconfigure.NacosDiscoveryEndpointsAutoConfiguration;
import com.alibaba.boot.nacos.discovery.actuate.endpoint.NacosDiscoveryEndpoint;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.ApplicationContext;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
/**
* {@link NacosDiscoveryEndpointsAutoConfiguration} Test
* @ClassName: NacosDiscoveryEndpointsAutoConfigurationTest
* @Author: SuperZ1999
* @Date: 2023/9/28
*/
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = {NacosDiscoveryEndpointsAutoConfiguration.class})
@TestPropertySource(properties = {
"management.endpoints.web.exposure.include=nacos-discovery"
})
public class NacosDiscoveryEndpointsAutoConfigurationTest {
@Autowired
private ApplicationContext context;
@Test
public void testNacosDiscoveryEndpointBean() {
Assert.assertNotNull(context.getBean(NacosDiscoveryEndpoint.class));
}
}

View File

@ -0,0 +1,48 @@
/*
*
* * 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.boot.nacos.actuate.autoconfigure;
import com.alibaba.boot.nacos.discovery.actuate.autoconfigure.NacosDiscoveryHealthIndicatorAutoConfiguration;
import com.alibaba.boot.nacos.discovery.actuate.health.NacosDiscoveryHealthIndicator;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.ApplicationContext;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
/**
* {@link NacosDiscoveryHealthIndicatorAutoConfiguration} Test
* @ClassName: NacosDiscoveryHealthIndicatorAutoConfigurationTest
* @Author: SuperZ1999
* @Date: 2023/9/28
*/
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = {NacosDiscoveryHealthIndicatorAutoConfiguration.class})
public class NacosDiscoveryHealthIndicatorAutoConfigurationTest {
@Autowired
private ApplicationContext context;
@Test
public void testNacosConfigHealthIndicatorBean() {
Assert.assertNotNull(context.getBean(NacosDiscoveryHealthIndicator.class));
}
}

View File

@ -0,0 +1 @@
nacos.discovery.serverAddr = "127.0.0.1:8848"

View File

@ -18,7 +18,7 @@
<parent>
<groupId>com.alibaba.boot</groupId>
<artifactId>nacos-spring-boot-parent</artifactId>
<version>0.2.4</version>
<version>${revision}</version>
<relativePath>../nacos-spring-boot-parent</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
@ -54,11 +54,30 @@
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-spring-context</artifactId>
<optional>true</optional>
<exclusions>
<exclusion>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-client</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-client</artifactId>
<version>${nacos.version}</version>
</dependency>
<dependency>
<groupId>com.alibaba.boot</groupId>
<artifactId>nacos-spring-boot-base</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.alibaba.boot</groupId>
<artifactId>nacos-spring-boot-base</artifactId>
<artifactId>nacos-spring-boot-aot</artifactId>
<optional>true</optional>
</dependency>

View File

@ -22,6 +22,10 @@ package com.alibaba.boot.nacos.discovery.autoconfigure;
*/
public class AutoDeregisterException extends RuntimeException {
public AutoDeregisterException(String message) {
super(message);
}
public AutoDeregisterException(Throwable cause) {
super(cause);
}

View File

@ -22,6 +22,10 @@ package com.alibaba.boot.nacos.discovery.autoconfigure;
*/
public class AutoRegisterException extends RuntimeException {
public AutoRegisterException(String message) {
super(message);
}
public AutoRegisterException(Throwable cause) {
super(cause);
}

View File

@ -16,6 +16,7 @@
*/
package com.alibaba.boot.nacos.discovery.autoconfigure;
import com.alibaba.boot.nacos.aot.context.EnableNacosDiscoveryAotProcessor;
import com.alibaba.boot.nacos.discovery.NacosDiscoveryConstants;
import com.alibaba.boot.nacos.discovery.properties.NacosDiscoveryProperties;
import com.alibaba.nacos.spring.context.annotation.discovery.EnableNacosDiscovery;
@ -26,6 +27,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import static com.alibaba.nacos.spring.util.NacosBeanUtils.DISCOVERY_GLOBAL_NACOS_PROPERTIES_BEAN_NAME;
@ -39,6 +41,7 @@ import static com.alibaba.nacos.spring.util.NacosBeanUtils.DISCOVERY_GLOBAL_NACO
@EnableNacosDiscovery
@EnableConfigurationProperties(value = NacosDiscoveryProperties.class)
@ConditionalOnClass(name = "org.springframework.boot.context.properties.bind.Binder")
@Import(EnableNacosDiscoveryAotProcessor.class)
public class NacosDiscoveryAutoConfiguration {
@Bean

View File

@ -21,7 +21,7 @@ import com.alibaba.boot.nacos.discovery.properties.Register;
import com.alibaba.nacos.api.annotation.NacosInjected;
import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.api.naming.NamingService;
import com.alibaba.nacos.client.naming.utils.NetUtils;
import com.alibaba.nacos.api.utils.NetUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -49,7 +49,7 @@ public class NacosDiscoveryAutoDeregister
private final NacosDiscoveryProperties discoveryProperties;
private final WebServer webServer;
@Value("${spring.application.name:spring.application.name}")
@Value("${spring.application.name:}")
private String applicationName;
public NacosDiscoveryAutoDeregister(NacosDiscoveryProperties discoveryProperties,
@ -74,15 +74,20 @@ public class NacosDiscoveryAutoDeregister
register.setPort(webServer.getPort());
}
String serviceName = StringUtils.isEmpty(register.getServiceName())
? applicationName
: register.getServiceName();
String serviceName = register.getServiceName();
if (StringUtils.isEmpty(serviceName)){
if (StringUtils.isEmpty(applicationName)){
throw new AutoDeregisterException("serviceName notNull");
}
serviceName = applicationName;
}
try {
namingService.deregisterInstance(serviceName, register.getGroupName(),
register);
logger.info("Finished auto deregister service : {}, ip : {}, port : {}",
register.getServiceName(), register.getIp(), register.getPort());
serviceName, register.getIp(), register.getPort());
}
catch (NacosException e) {
throw new AutoDeregisterException(e);

View File

@ -21,7 +21,7 @@ import com.alibaba.boot.nacos.discovery.properties.Register;
import com.alibaba.nacos.api.annotation.NacosInjected;
import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.api.naming.NamingService;
import com.alibaba.nacos.client.naming.utils.NetUtils;
import com.alibaba.nacos.api.utils.NetUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -32,59 +32,65 @@ import org.springframework.boot.web.context.WebServerInitializedEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;
/**
* @author <a href="mailto:liaochunyhm@live.com">liaochuntao</a>
* @since 0.2.3
*/
@Component
public class NacosDiscoveryAutoRegister
implements ApplicationListener<WebServerInitializedEvent> {
implements ApplicationListener<WebServerInitializedEvent> {
private static final Logger logger = LoggerFactory
.getLogger(NacosDiscoveryAutoRegister.class);
private static final Logger logger = LoggerFactory
.getLogger(NacosDiscoveryAutoRegister.class);
@NacosInjected
private NamingService namingService;
@NacosInjected
private NamingService namingService;
@Autowired
private NacosDiscoveryProperties discoveryProperties;
@Autowired
private NacosDiscoveryProperties discoveryProperties;
@Value("${spring.application.name:spring.application.name}")
@Value("${spring.application.name:}")
private String applicationName;
@Override
public void onApplicationEvent(WebServerInitializedEvent event) {
@Override
public void onApplicationEvent(WebServerInitializedEvent event) {
if (!discoveryProperties.isAutoRegister()) {
return;
}
if (!discoveryProperties.isAutoRegister()) {
return;
}
Register register = discoveryProperties.getRegister();
Register register = discoveryProperties.getRegister();
if (StringUtils.isEmpty(register.getIp())) {
register.setIp(NetUtils.localIP());
}
if (StringUtils.isEmpty(register.getIp())) {
register.setIp(NetUtils.localIP());
}
if (register.getPort() == 0) {
register.setPort(event.getWebServer().getPort());
}
if (register.getPort() == 0) {
register.setPort(event.getWebServer().getPort());
}
register.getMetadata().put("preserved.register.source", "SPRING_BOOT");
register.getMetadata().put("preserved.register.source", "SPRING_BOOT");
register.setInstanceId("");
String serviceName = StringUtils.isEmpty(register.getServiceName())
? applicationName
: register.getServiceName();
register.setInstanceId("");
try {
namingService.registerInstance(serviceName, register.getGroupName(),
register);
logger.info("Finished auto register service : {}, ip : {}, port : {}",
register.getServiceName(), register.getIp(), register.getPort());
}
catch (NacosException e) {
throw new AutoRegisterException(e);
}
}
String serviceName = register.getServiceName();
if (StringUtils.isEmpty(serviceName)){
if (StringUtils.isEmpty(applicationName)){
throw new AutoRegisterException("serviceName notNull");
}
serviceName = applicationName;
}
try {
namingService.registerInstance(serviceName, register.getGroupName(),
register);
logger.info("Finished auto register service : {}, ip : {}, port : {}",
serviceName, register.getIp(), register.getPort());
} catch (NacosException e) {
throw new AutoRegisterException(e);
}
}
}

View File

@ -49,6 +49,26 @@ public class NacosDiscoveryProperties {
@NestedConfigurationProperty
private Register register = new Register();
private String username;
private String password;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getServerAddr() {
return serverAddr;
}

View File

@ -0,0 +1 @@
com.alibaba.boot.nacos.discovery.autoconfigure.NacosDiscoveryAutoConfiguration

View File

@ -19,6 +19,7 @@ package com.alibaba.boot.nacos.autoconfigure;
import java.util.Properties;
import com.alibaba.boot.nacos.discovery.autoconfigure.NacosDiscoveryAutoConfiguration;
import com.alibaba.boot.nacos.discovery.autoconfigure.NacosDiscoveryAutoRegister;
import com.alibaba.boot.nacos.discovery.properties.NacosDiscoveryProperties;
import com.alibaba.nacos.api.PropertyKeyConst;
import com.alibaba.nacos.api.annotation.NacosInjected;
@ -64,13 +65,13 @@ public class NacosDiscoveryAutoConfigurationTest {
}
@Test(expected = NoSuchBeanDefinitionException.class)
public void testNacosConfigGlobalBean() {
public void testNacosDiscoveryGlobalBean() {
Assert.assertNull(applicationContext
.getBean(NacosBeanUtils.GLOBAL_NACOS_PROPERTIES_BEAN_NAME));
}
@Test(expected = NoSuchBeanDefinitionException.class)
public void testNacosDiscoveryGlobalBean() {
public void testNacosConfigGlobalBean() {
Assert.assertNull(applicationContext
.getBean(NacosBeanUtils.CONFIG_GLOBAL_NACOS_PROPERTIES_BEAN_NAME));
}
@ -84,4 +85,8 @@ public class NacosDiscoveryAutoConfigurationTest {
properties.getProperty(PropertyKeyConst.SERVER_ADDR));
}
@Test
public void testAddNacosDiscoveryAutoRegister() {
Assert.assertNotNull(applicationContext.getBean(NacosDiscoveryAutoRegister.class));
}
}

View File

@ -18,7 +18,7 @@
<parent>
<groupId>com.alibaba.boot</groupId>
<artifactId>nacos-spring-boot-parent</artifactId>
<version>0.2.4</version>
<version>${revision}</version>
<relativePath>../nacos-spring-boot-parent</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
@ -40,6 +40,18 @@
<dependency>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-spring-context</artifactId>
<exclusions>
<exclusion>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-client</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-client</artifactId>
<version>${nacos.version}</version>
</dependency>
<dependency>
@ -52,5 +64,10 @@
<artifactId>nacos-spring-boot-base</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.boot</groupId>
<artifactId>nacos-spring-boot-aot</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,69 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ /*
~ * 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.
~ */
-->
<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.boot</groupId>
<artifactId>nacos-spring-boot-parent</artifactId>
<version>${revision}</version>
<relativePath>../nacos-spring-boot-parent</relativePath>
</parent>
<artifactId>nacos-spring-boot-aot</artifactId>
<packaging>jar</packaging>
<name>Nacos Spring Boot Aot</name>
<description>Nacos Spring Boot Aot</description>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${spring6.framework.version}</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring6.framework.version}</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring6.framework.version}</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-spring-context</artifactId>
<version>${nacos-spring-context.version}</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-client</artifactId>
<version>${nacos.version}</version>
</dependency>
</dependencies>
</project>

View File

@ -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.boot.nacos.aot.context;
import com.alibaba.boot.nacos.aot.util.AotDetector;
import com.alibaba.nacos.spring.context.annotation.config.EnableNacosConfig;
import com.alibaba.nacos.spring.context.annotation.config.NacosConfigBeanDefinitionRegistrar;
import com.alibaba.nacos.spring.core.env.NacosPropertySourcePostProcessor;
import com.alibaba.nacos.spring.util.NacosBeanUtils;
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);
// replace NacosPropertySourcePostProcessor with NacosPropertySourcePostProcessorForAot
if (registry.containsBeanDefinition(NacosPropertySourcePostProcessor.BEAN_NAME)) {
registry.removeBeanDefinition(NacosPropertySourcePostProcessor.BEAN_NAME);
}
NacosBeanUtils.registerInfrastructureBeanIfAbsent(registry, NacosPropertySourcePostProcessorForAot.BEAN_NAME,
NacosPropertySourcePostProcessorForAot.class);
// 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;
}
}

View File

@ -0,0 +1,94 @@
/*
*
* * 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.boot.nacos.aot.context;
import com.alibaba.boot.nacos.aot.util.AotDetector;
import com.alibaba.nacos.spring.context.annotation.discovery.EnableNacosDiscovery;
import com.alibaba.nacos.spring.context.annotation.discovery.NacosDiscoveryBeanDefinitionRegistrar;
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;
}
}

View File

@ -0,0 +1,90 @@
/*
*
* * 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.boot.nacos.aot.context;
import com.alibaba.boot.nacos.aot.util.AotDetector;
import com.alibaba.nacos.spring.context.annotation.config.NacosPropertySource;
import com.alibaba.nacos.spring.core.env.AbstractNacosPropertySourceBuilder;
import com.alibaba.nacos.spring.core.env.NacosPropertySourcePostProcessor;
import com.alibaba.spring.util.BeanUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.AnnotatedGenericBeanDefinition;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import java.util.ArrayList;
import java.util.Map;
import static com.alibaba.nacos.spring.util.NacosBeanUtils.getConfigServiceBeanBuilder;
public class NacosPropertySourcePostProcessorForAot extends NacosPropertySourcePostProcessor {
@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);
if (AotDetector.useGeneratedArtifacts()) {
// the type of all BeanDefinitions is RootBeanDefinition in AOT, but what we need is AnnotatedGenericBeanDefinition.
Map<String, Object> beansWithAnnotation = beanFactory.getBeansWithAnnotation(NacosPropertySource.class);
for (Map.Entry<String, Object> entry : beansWithAnnotation.entrySet()) {
processPropertySourceForAot(entry.getKey(), entry.getValue());
}
}
String[] beanNames = beanFactory.getBeanDefinitionNames();
for (String beanName : beanNames) {
processPropertySource(beanName, beanFactory);
}
}
private void processPropertySourceForAot(String beanName, Object bean) {
if (processedBeanNames.contains(beanName)) {
return;
}
BeanDefinition beanDefinition = null;
Class<?> aClass = bean.getClass();
NacosPropertySource[] annotations = aClass.getSuperclass().getAnnotationsByType(NacosPropertySource.class);
if (annotations.length != 0) {
beanDefinition = new AnnotatedGenericBeanDefinition(aClass.getSuperclass());
}
annotations = aClass.getAnnotationsByType(NacosPropertySource.class);
if (annotations.length != 0) {
beanDefinition = new AnnotatedGenericBeanDefinition(aClass);
}
doProcessPropertySource(beanName, beanDefinition);
processedBeanNames.add(beanName);
}
}

View File

@ -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.boot.nacos.aot.hint;
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);
}
}
}
}

View File

@ -0,0 +1,45 @@
/*
*
* * 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.boot.nacos.aot.util;
import org.springframework.core.NativeDetector;
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));
}
}

View File

@ -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.boot.nacos.aot.util;
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);
/**
* Returns {@code true} if invoked in the context of image building or during image runtime, else {@code false}.
*/
public static boolean inNativeImage() {
return imageCode;
}
}

View File

@ -0,0 +1,9 @@
[
{
"name": "com.alibaba.boot.nacos.aot.context.NacosPropertySourcePostProcessorForAot",
"allDeclaredClasses": true,
"allDeclaredMethods": true,
"allDeclaredFields": true,
"allDeclaredConstructors": true
}
]

View File

@ -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"
}
]
}
}

View File

@ -0,0 +1,2 @@
org.springframework.beans.factory.aot.BeanRegistrationAotProcessor=\
com.alibaba.boot.nacos.aot.hint.NacosAnnotationBeanRegistrationAotProcessor

View File

@ -18,7 +18,7 @@
<parent>
<groupId>com.alibaba.boot</groupId>
<artifactId>nacos-spring-boot-parent</artifactId>
<version>0.2.4</version>
<version>${revision}</version>
<relativePath>../nacos-spring-boot-parent</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
@ -54,7 +54,20 @@
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-spring-context</artifactId>
<optional>true</optional>
<exclusions>
<exclusion>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-client</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-client</artifactId>
<version>${nacos.version}</version>
</dependency>
<!-- Test Dependencies -->
<dependency>

View File

@ -0,0 +1 @@
com.alibaba.boot.nacos.common.NacosFailureAnalyzer

View File

@ -18,7 +18,7 @@
<parent>
<groupId>com.alibaba.boot</groupId>
<artifactId>nacos-spring-boot-project</artifactId>
<version>0.2.4</version>
<version>${revision}</version>
<relativePath>../pom.xml</relativePath>
</parent>
@ -35,8 +35,9 @@
<java.target.version>1.8</java.target.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<spring-boot.version>2.0.3.RELEASE</spring-boot.version>
<nacos-spring-context.version>0.3.4</nacos-spring-context.version>
<spring-boot.version>2.6.3</spring-boot.version>
<spring6.framework.version>6.0.8</spring6.framework.version>
<nacos-spring-context.version>2.1.0-RC</nacos-spring-context.version>
<!-- Build args -->
<argline>-server -Xms256m -Xmx512m -XX:PermSize=64m -XX:MaxPermSize=128m -Dfile.encoding=UTF-8
-Djava.net.preferIPv4Stack=true
@ -52,6 +53,7 @@
<maven-release-plugin.version>2.5.3</maven-release-plugin.version>
<maven-surefire-plugin.version>2.19.1</maven-surefire-plugin.version>
<maven-deploy-plugin.version>2.8.2</maven-deploy-plugin.version>
<nacos.version>2.2.1</nacos.version>
</properties>
<dependencyManagement>
@ -71,6 +73,18 @@
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-spring-context</artifactId>
<version>${nacos-spring-context.version}</version>
<exclusions>
<exclusion>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-client</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-client</artifactId>
<version>${nacos.version}</version>
</dependency>
<dependency>
@ -79,6 +93,12 @@
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.alibaba.boot</groupId>
<artifactId>nacos-spring-boot-aot</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.alibaba.boot</groupId>
<artifactId>nacos-config-spring-boot-autoconfigure</artifactId>
@ -156,6 +176,16 @@
</pluginRepository>
</pluginRepositories>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.1</version>
<scope>compile</scope>
<optional>true</optional>
</dependency>
</dependencies>
<build>
<!-- Used for packaging NOTICE & LICENSE to each sub-module jar-->
<resources>
@ -419,4 +449,4 @@
</plugins>
</build>
</project>
</project>

View File

@ -0,0 +1,105 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ /*
~ * 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.
~ */
-->
<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.boot</groupId>
<artifactId>nacos-spring-boot-samples</artifactId>
<version>${revision}</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>nacos-aot-sample</artifactId>
<packaging>jar</packaging>
<name>Nacos Spring Boot Aot Sample</name>
<description>Nacos Spring Boot Aot Sample</description>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>3.0.6</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>com.alibaba.boot</groupId>
<artifactId>nacos-config-spring-boot-starter</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>com.alibaba.boot</groupId>
<artifactId>nacos-discovery-spring-boot-starter</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
<profiles>
<profile>
<id>native</id>
<build>
<plugins>
<plugin>
<groupId>org.graalvm.buildtools</groupId>
<artifactId>native-maven-plugin</artifactId>
<version>0.9.25</version>
<executions>
<execution>
<id>compile</id>
<goals>
<goal>compile</goal>
</goals>
</execution>
</executions>
<configuration>
<classesDirectory>${project.build.outputDirectory}</classesDirectory>
<mainClass>com.alibaba.boot.nacos.sample.AotApplication</mainClass>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<id>process-aot</id>
<goals>
<goal>process-aot</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>

View File

@ -0,0 +1,32 @@
/*
*
* * 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.boot.nacos.sample;
import com.alibaba.nacos.spring.context.annotation.config.NacosPropertySource;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
@NacosPropertySource(dataId = "example", autoRefreshed = true)
public class AotApplication {
public static void main(String[] args) {
SpringApplication.run(AotApplication.class, args);
}
}

View File

@ -0,0 +1,65 @@
/*
*
* * 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.boot.nacos.sample.controller;
import com.alibaba.nacos.api.annotation.NacosInjected;
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.api.naming.NamingService;
import com.alibaba.nacos.api.naming.pojo.Instance;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import java.util.List;
import static org.springframework.web.bind.annotation.RequestMethod.GET;
@Controller
public class AotController {
@NacosInjected
private ConfigService configService;
@NacosInjected
private NamingService namingService;
@NacosValue(value = "${flag:false}", autoRefreshed = true)
private boolean flag;
@ResponseBody
@RequestMapping(value = "/config/get", method = GET)
public String getConfig() throws NacosException {
return configService.getConfig("example", "DEFAULT_GROUP", 5000);
}
@ResponseBody
@RequestMapping(value = "/naming/get", method = GET)
public List<Instance> getNaming(@RequestParam("serviceName") String serviceName) throws NacosException {
return namingService.getAllInstances(serviceName);
}
@ResponseBody
@RequestMapping(value = "/flag/get", method = GET)
public boolean getFlag() {
return flag;
}
}

View File

@ -0,0 +1,36 @@
[
{
"name":"[Lcom.sun.management.internal.DiagnosticCommandArgumentInfo;"
},
{
"name":"[Lcom.sun.management.internal.DiagnosticCommandInfo;"
},
{
"name":"com.sun.management.internal.DiagnosticCommandArgumentInfo",
"methods":[{"name":"<init>","parameterTypes":["java.lang.String","java.lang.String","java.lang.String","java.lang.String","boolean","boolean","boolean","int"] }]
},
{
"name":"com.sun.management.internal.DiagnosticCommandInfo",
"methods":[{"name":"<init>","parameterTypes":["java.lang.String","java.lang.String","java.lang.String","java.lang.String","java.lang.String","java.lang.String","boolean","java.util.List"] }]
},
{
"name":"java.lang.Boolean",
"methods":[{"name":"getBoolean","parameterTypes":["java.lang.String"] }]
},
{
"name":"java.lang.InternalError",
"methods":[{"name":"<init>","parameterTypes":["java.lang.String"] }]
},
{
"name":"java.util.Arrays",
"methods":[{"name":"asList","parameterTypes":["java.lang.Object[]"] }]
},
{
"name":"sun.instrument.InstrumentationImpl",
"methods":[{"name":"<init>","parameterTypes":["long","boolean","boolean"] }, {"name":"loadClassAndCallAgentmain","parameterTypes":["java.lang.String","java.lang.String"] }, {"name":"loadClassAndCallPremain","parameterTypes":["java.lang.String","java.lang.String"] }, {"name":"transform","parameterTypes":["java.lang.Module","java.lang.ClassLoader","java.lang.String","java.lang.Class","java.security.ProtectionDomain","byte[]","boolean"] }]
},
{
"name":"sun.management.VMManagementImpl",
"fields":[{"name":"compTimeMonitoringSupport"}, {"name":"currentThreadCpuTimeSupport"}, {"name":"objectMonitorUsageSupport"}, {"name":"otherThreadCpuTimeSupport"}, {"name":"remoteDiagnosticCommandsSupport"}, {"name":"synchronizerUsageSupport"}, {"name":"threadAllocatedMemorySupport"}, {"name":"threadContentionMonitoringSupport"}]
}
]

View File

@ -0,0 +1,8 @@
[
{
"type":"agent-extracted",
"classes":[
]
}
]

View File

@ -0,0 +1,20 @@
[
{
"interfaces":["java.lang.reflect.ParameterizedType","org.springframework.core.SerializableTypeWrapper$SerializableTypeProxy","java.io.Serializable"]
},
{
"interfaces":["java.lang.reflect.TypeVariable","org.springframework.core.SerializableTypeWrapper$SerializableTypeProxy","java.io.Serializable"]
},
{
"interfaces":["java.lang.reflect.WildcardType","org.springframework.core.SerializableTypeWrapper$SerializableTypeProxy","java.io.Serializable"]
},
{
"interfaces":["org.springframework.boot.context.properties.ConfigurationProperties"]
},
{
"interfaces":["org.springframework.web.bind.annotation.RequestMapping"]
},
{
"interfaces":["org.springframework.web.bind.annotation.RequestParam"]
}
]

View File

@ -0,0 +1,440 @@
{
"resources":{
"includes":[{
"pattern":"\\QMETA-INF/services/ch.qos.logback.classic.spi.Configurator\\E"
}, {
"pattern":"\\QMETA-INF/services/com.alibaba.nacos.api.config.filter.IConfigFilter\\E"
}, {
"pattern":"\\QMETA-INF/services/com.alibaba.nacos.api.remote.Payload\\E"
}, {
"pattern":"\\QMETA-INF/services/com.alibaba.nacos.common.log.NacosLogbackConfigurator\\E"
}, {
"pattern":"\\QMETA-INF/services/com.alibaba.nacos.plugin.auth.spi.client.AbstractClientAuthService\\E"
}, {
"pattern":"\\QMETA-INF/services/com.alibaba.nacos.shaded.io.grpc.LoadBalancerProvider\\E"
}, {
"pattern":"\\QMETA-INF/services/com.alibaba.nacos.shaded.io.grpc.ManagedChannelProvider\\E"
}, {
"pattern":"\\QMETA-INF/services/com.alibaba.nacos.shaded.io.grpc.NameResolverProvider\\E"
}, {
"pattern":"\\QMETA-INF/services/com.alibaba.nacos.spring.util.ConfigParse\\E"
}, {
"pattern":"\\QMETA-INF/services/org.slf4j.spi.SLF4JServiceProvider\\E"
}, {
"pattern":"\\QMETA-INF/spring-autoconfigure-metadata.properties\\E"
}, {
"pattern":"\\QMETA-INF/spring.factories\\E"
}, {
"pattern":"\\QMETA-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports\\E"
}, {
"pattern":"\\Qapplication.properties\\E"
}, {
"pattern":"\\Qcom/alibaba/boot/nacos/aot/context/EnableNacosConfigAotProcessor.class\\E"
}, {
"pattern":"\\Qcom/alibaba/boot/nacos/aot/context/EnableNacosDiscoveryAotProcessor.class\\E"
}, {
"pattern":"\\Qcom/alibaba/boot/nacos/common/NacosFailureAnalyzer.class\\E"
}, {
"pattern":"\\Qcom/alibaba/boot/nacos/config/autoconfigure/NacosConfigAutoConfiguration.class\\E"
}, {
"pattern":"\\Qcom/alibaba/boot/nacos/config/autoconfigure/NacosConfigBootBeanDefinitionRegistrar.class\\E"
}, {
"pattern":"\\Qcom/alibaba/boot/nacos/config/autoconfigure/NacosConfigEnvironmentProcessor.class\\E"
}, {
"pattern":"\\Qcom/alibaba/boot/nacos/config/logging/NacosLoggingListener.class\\E"
}, {
"pattern":"\\Qcom/alibaba/boot/nacos/config/support/MultiProfilesYamlConfigParseSupport.class\\E"
}, {
"pattern":"\\Qcom/alibaba/boot/nacos/discovery/autoconfigure/NacosDiscoveryAutoConfiguration.class\\E"
}, {
"pattern":"\\Qcom/alibaba/boot/nacos/sample/\\E"
}, {
"pattern":"\\Qcom/alibaba/boot/nacos/sample/controller/AotController.class\\E"
}, {
"pattern":"\\Qcom/alibaba/nacos/spring/context/annotation/config/EnableNacosConfig.class\\E"
}, {
"pattern":"\\Qcom/alibaba/nacos/spring/context/annotation/config/NacosConfigBeanDefinitionRegistrar.class\\E"
}, {
"pattern":"\\Qcom/alibaba/nacos/spring/context/annotation/discovery/EnableNacosDiscovery.class\\E"
}, {
"pattern":"\\Qcom/alibaba/nacos/spring/context/annotation/discovery/NacosDiscoveryBeanDefinitionRegistrar.class\\E"
}, {
"pattern":"\\Qcom/alibaba/nacos/spring/util/AbstractConfigParse.class\\E"
}, {
"pattern":"\\Qcom/alibaba/nacos/spring/util/ConfigParse.class\\E"
}, {
"pattern":"\\Qcom/alibaba/nacos/spring/util/parse/DefaultYamlConfigParse.class\\E"
}, {
"pattern":"\\Qnacos-version.txt\\E"
}, {
"pattern":"\\Qnacos_default_setting.properties\\E"
}, {
"pattern":"\\Qorg/apache/catalina/core/RestrictedFilters.properties\\E"
}, {
"pattern":"\\Qorg/apache/catalina/core/RestrictedListeners.properties\\E"
}, {
"pattern":"\\Qorg/apache/catalina/core/RestrictedServlets.properties\\E"
}, {
"pattern":"\\Qorg/apache/catalina/loader/JdbcLeakPrevention.class\\E"
}, {
"pattern":"\\Qorg/apache/catalina/util/CharsetMapperDefault.properties\\E"
}, {
"pattern":"\\Qorg/apache/catalina/util/ServerInfo.properties\\E"
}, {
"pattern":"\\Qorg/springframework/beans/factory/Aware.class\\E"
}, {
"pattern":"\\Qorg/springframework/beans/factory/BeanFactoryAware.class\\E"
}, {
"pattern":"\\Qorg/springframework/beans/factory/config/BeanFactoryPostProcessor.class\\E"
}, {
"pattern":"\\Qorg/springframework/beans/factory/support/BeanDefinitionRegistryPostProcessor.class\\E"
}, {
"pattern":"\\Qorg/springframework/boot/autoconfigure/AbstractDependsOnBeanFactoryPostProcessor.class\\E"
}, {
"pattern":"\\Qorg/springframework/boot/autoconfigure/AutoConfiguration.class\\E"
}, {
"pattern":"\\Qorg/springframework/boot/autoconfigure/AutoConfigureAfter.class\\E"
}, {
"pattern":"\\Qorg/springframework/boot/autoconfigure/AutoConfigureBefore.class\\E"
}, {
"pattern":"\\Qorg/springframework/boot/autoconfigure/AutoConfigureOrder.class\\E"
}, {
"pattern":"\\Qorg/springframework/boot/autoconfigure/admin/SpringApplicationAdminJmxAutoConfiguration.class\\E"
}, {
"pattern":"\\Qorg/springframework/boot/autoconfigure/aop/AopAutoConfiguration$AspectJAutoProxyingConfiguration.class\\E"
}, {
"pattern":"\\Qorg/springframework/boot/autoconfigure/aop/AopAutoConfiguration$ClassProxyingConfiguration.class\\E"
}, {
"pattern":"\\Qorg/springframework/boot/autoconfigure/aop/AopAutoConfiguration.class\\E"
}, {
"pattern":"\\Qorg/springframework/boot/autoconfigure/availability/ApplicationAvailabilityAutoConfiguration.class\\E"
}, {
"pattern":"\\Qorg/springframework/boot/autoconfigure/cache/CacheAutoConfiguration$CacheConfigurationImportSelector.class\\E"
}, {
"pattern":"\\Qorg/springframework/boot/autoconfigure/cache/CacheAutoConfiguration$CacheManagerEntityManagerFactoryDependsOnPostProcessor.class\\E"
}, {
"pattern":"\\Qorg/springframework/boot/autoconfigure/cache/CacheAutoConfiguration$CacheManagerValidator.class\\E"
}, {
"pattern":"\\Qorg/springframework/boot/autoconfigure/cache/CacheAutoConfiguration.class\\E"
}, {
"pattern":"\\Qorg/springframework/boot/autoconfigure/cache/GenericCacheConfiguration.class\\E"
}, {
"pattern":"\\Qorg/springframework/boot/autoconfigure/cache/NoOpCacheConfiguration.class\\E"
}, {
"pattern":"\\Qorg/springframework/boot/autoconfigure/cache/SimpleCacheConfiguration.class\\E"
}, {
"pattern":"\\Qorg/springframework/boot/autoconfigure/condition/ConditionalOnBean.class\\E"
}, {
"pattern":"\\Qorg/springframework/boot/autoconfigure/condition/ConditionalOnClass.class\\E"
}, {
"pattern":"\\Qorg/springframework/boot/autoconfigure/condition/ConditionalOnMissingBean.class\\E"
}, {
"pattern":"\\Qorg/springframework/boot/autoconfigure/condition/ConditionalOnMissingClass.class\\E"
}, {
"pattern":"\\Qorg/springframework/boot/autoconfigure/condition/ConditionalOnNotWarDeployment.class\\E"
}, {
"pattern":"\\Qorg/springframework/boot/autoconfigure/condition/ConditionalOnProperty.class\\E"
}, {
"pattern":"\\Qorg/springframework/boot/autoconfigure/condition/ConditionalOnWebApplication.class\\E"
}, {
"pattern":"\\Qorg/springframework/boot/autoconfigure/context/ConfigurationPropertiesAutoConfiguration.class\\E"
}, {
"pattern":"\\Qorg/springframework/boot/autoconfigure/context/LifecycleAutoConfiguration.class\\E"
}, {
"pattern":"\\Qorg/springframework/boot/autoconfigure/context/MessageSourceAutoConfiguration.class\\E"
}, {
"pattern":"\\Qorg/springframework/boot/autoconfigure/context/PropertyPlaceholderAutoConfiguration.class\\E"
}, {
"pattern":"\\Qorg/springframework/boot/autoconfigure/http/GsonHttpMessageConvertersConfiguration.class\\E"
}, {
"pattern":"\\Qorg/springframework/boot/autoconfigure/http/HttpMessageConvertersAutoConfiguration$HttpMessageConvertersAutoConfigurationRuntimeHints.class\\E"
}, {
"pattern":"\\Qorg/springframework/boot/autoconfigure/http/HttpMessageConvertersAutoConfiguration$NotReactiveWebApplicationCondition$ReactiveWebApplication.class\\E"
}, {
"pattern":"\\Qorg/springframework/boot/autoconfigure/http/HttpMessageConvertersAutoConfiguration$NotReactiveWebApplicationCondition.class\\E"
}, {
"pattern":"\\Qorg/springframework/boot/autoconfigure/http/HttpMessageConvertersAutoConfiguration$StringHttpMessageConverterConfiguration.class\\E"
}, {
"pattern":"\\Qorg/springframework/boot/autoconfigure/http/HttpMessageConvertersAutoConfiguration.class\\E"
}, {
"pattern":"\\Qorg/springframework/boot/autoconfigure/http/JacksonHttpMessageConvertersConfiguration$MappingJackson2HttpMessageConverterConfiguration.class\\E"
}, {
"pattern":"\\Qorg/springframework/boot/autoconfigure/http/JacksonHttpMessageConvertersConfiguration$MappingJackson2XmlHttpMessageConverterConfiguration.class\\E"
}, {
"pattern":"\\Qorg/springframework/boot/autoconfigure/http/JacksonHttpMessageConvertersConfiguration.class\\E"
}, {
"pattern":"\\Qorg/springframework/boot/autoconfigure/http/JsonbHttpMessageConvertersConfiguration.class\\E"
}, {
"pattern":"\\Qorg/springframework/boot/autoconfigure/info/ProjectInfoAutoConfiguration$GitResourceAvailableCondition.class\\E"
}, {
"pattern":"\\Qorg/springframework/boot/autoconfigure/info/ProjectInfoAutoConfiguration.class\\E"
}, {
"pattern":"\\Qorg/springframework/boot/autoconfigure/jackson/JacksonAutoConfiguration$Jackson2ObjectMapperBuilderCustomizerConfiguration$StandardJackson2ObjectMapperBuilderCustomizer.class\\E"
}, {
"pattern":"\\Qorg/springframework/boot/autoconfigure/jackson/JacksonAutoConfiguration$Jackson2ObjectMapperBuilderCustomizerConfiguration.class\\E"
}, {
"pattern":"\\Qorg/springframework/boot/autoconfigure/jackson/JacksonAutoConfiguration$JacksonAutoConfigurationRuntimeHints.class\\E"
}, {
"pattern":"\\Qorg/springframework/boot/autoconfigure/jackson/JacksonAutoConfiguration$JacksonMixinConfiguration.class\\E"
}, {
"pattern":"\\Qorg/springframework/boot/autoconfigure/jackson/JacksonAutoConfiguration$JacksonObjectMapperBuilderConfiguration.class\\E"
}, {
"pattern":"\\Qorg/springframework/boot/autoconfigure/jackson/JacksonAutoConfiguration$JacksonObjectMapperConfiguration.class\\E"
}, {
"pattern":"\\Qorg/springframework/boot/autoconfigure/jackson/JacksonAutoConfiguration$ParameterNamesModuleConfiguration.class\\E"
}, {
"pattern":"\\Qorg/springframework/boot/autoconfigure/jackson/JacksonAutoConfiguration.class\\E"
}, {
"pattern":"\\Qorg/springframework/boot/autoconfigure/jmx/JmxAutoConfiguration.class\\E"
}, {
"pattern":"\\Qorg/springframework/boot/autoconfigure/orm/jpa/EntityManagerFactoryDependsOnPostProcessor.class\\E"
}, {
"pattern":"\\Qorg/springframework/boot/autoconfigure/sql/init/DataSourceInitializationConfiguration.class\\E"
}, {
"pattern":"\\Qorg/springframework/boot/autoconfigure/sql/init/R2dbcInitializationConfiguration.class\\E"
}, {
"pattern":"\\Qorg/springframework/boot/autoconfigure/sql/init/SqlInitializationAutoConfiguration$SqlInitializationModeCondition$ModeIsNever.class\\E"
}, {
"pattern":"\\Qorg/springframework/boot/autoconfigure/sql/init/SqlInitializationAutoConfiguration$SqlInitializationModeCondition.class\\E"
}, {
"pattern":"\\Qorg/springframework/boot/autoconfigure/sql/init/SqlInitializationAutoConfiguration.class\\E"
}, {
"pattern":"\\Qorg/springframework/boot/autoconfigure/task/TaskExecutionAutoConfiguration.class\\E"
}, {
"pattern":"\\Qorg/springframework/boot/autoconfigure/task/TaskSchedulingAutoConfiguration.class\\E"
}, {
"pattern":"\\Qorg/springframework/boot/autoconfigure/web/client/RestTemplateAutoConfiguration$NotReactiveWebApplicationCondition$ReactiveWebApplication.class\\E"
}, {
"pattern":"\\Qorg/springframework/boot/autoconfigure/web/client/RestTemplateAutoConfiguration$NotReactiveWebApplicationCondition.class\\E"
}, {
"pattern":"\\Qorg/springframework/boot/autoconfigure/web/client/RestTemplateAutoConfiguration.class\\E"
}, {
"pattern":"\\Qorg/springframework/boot/autoconfigure/web/embedded/EmbeddedWebServerFactoryCustomizerAutoConfiguration$JettyWebServerFactoryCustomizerConfiguration.class\\E"
}, {
"pattern":"\\Qorg/springframework/boot/autoconfigure/web/embedded/EmbeddedWebServerFactoryCustomizerAutoConfiguration$NettyWebServerFactoryCustomizerConfiguration.class\\E"
}, {
"pattern":"\\Qorg/springframework/boot/autoconfigure/web/embedded/EmbeddedWebServerFactoryCustomizerAutoConfiguration$TomcatWebServerFactoryCustomizerConfiguration.class\\E"
}, {
"pattern":"\\Qorg/springframework/boot/autoconfigure/web/embedded/EmbeddedWebServerFactoryCustomizerAutoConfiguration$UndertowWebServerFactoryCustomizerConfiguration.class\\E"
}, {
"pattern":"\\Qorg/springframework/boot/autoconfigure/web/embedded/EmbeddedWebServerFactoryCustomizerAutoConfiguration.class\\E"
}, {
"pattern":"\\Qorg/springframework/boot/autoconfigure/web/servlet/DispatcherServletAutoConfiguration$DefaultDispatcherServletCondition.class\\E"
}, {
"pattern":"\\Qorg/springframework/boot/autoconfigure/web/servlet/DispatcherServletAutoConfiguration$DispatcherServletConfiguration.class\\E"
}, {
"pattern":"\\Qorg/springframework/boot/autoconfigure/web/servlet/DispatcherServletAutoConfiguration$DispatcherServletRegistrationCondition.class\\E"
}, {
"pattern":"\\Qorg/springframework/boot/autoconfigure/web/servlet/DispatcherServletAutoConfiguration$DispatcherServletRegistrationConfiguration.class\\E"
}, {
"pattern":"\\Qorg/springframework/boot/autoconfigure/web/servlet/DispatcherServletAutoConfiguration.class\\E"
}, {
"pattern":"\\Qorg/springframework/boot/autoconfigure/web/servlet/HttpEncodingAutoConfiguration$LocaleCharsetMappingsCustomizer.class\\E"
}, {
"pattern":"\\Qorg/springframework/boot/autoconfigure/web/servlet/HttpEncodingAutoConfiguration.class\\E"
}, {
"pattern":"\\Qorg/springframework/boot/autoconfigure/web/servlet/MultipartAutoConfiguration.class\\E"
}, {
"pattern":"\\Qorg/springframework/boot/autoconfigure/web/servlet/ServletWebServerFactoryAutoConfiguration$BeanPostProcessorsRegistrar.class\\E"
}, {
"pattern":"\\Qorg/springframework/boot/autoconfigure/web/servlet/ServletWebServerFactoryAutoConfiguration$ForwardedHeaderFilterConfiguration.class\\E"
}, {
"pattern":"\\Qorg/springframework/boot/autoconfigure/web/servlet/ServletWebServerFactoryAutoConfiguration$ForwardedHeaderFilterCustomizer.class\\E"
}, {
"pattern":"\\Qorg/springframework/boot/autoconfigure/web/servlet/ServletWebServerFactoryAutoConfiguration.class\\E"
}, {
"pattern":"\\Qorg/springframework/boot/autoconfigure/web/servlet/ServletWebServerFactoryConfiguration$EmbeddedJetty.class\\E"
}, {
"pattern":"\\Qorg/springframework/boot/autoconfigure/web/servlet/ServletWebServerFactoryConfiguration$EmbeddedTomcat.class\\E"
}, {
"pattern":"\\Qorg/springframework/boot/autoconfigure/web/servlet/ServletWebServerFactoryConfiguration$EmbeddedUndertow.class\\E"
}, {
"pattern":"\\Qorg/springframework/boot/autoconfigure/web/servlet/WebMvcAutoConfiguration$EnableWebMvcConfiguration.class\\E"
}, {
"pattern":"\\Qorg/springframework/boot/autoconfigure/web/servlet/WebMvcAutoConfiguration$OptionalPathExtensionContentNegotiationStrategy.class\\E"
}, {
"pattern":"\\Qorg/springframework/boot/autoconfigure/web/servlet/WebMvcAutoConfiguration$ProblemDetailsErrorHandlingConfiguration.class\\E"
}, {
"pattern":"\\Qorg/springframework/boot/autoconfigure/web/servlet/WebMvcAutoConfiguration$ResourceChainCustomizerConfiguration.class\\E"
}, {
"pattern":"\\Qorg/springframework/boot/autoconfigure/web/servlet/WebMvcAutoConfiguration$ResourceChainResourceHandlerRegistrationCustomizer.class\\E"
}, {
"pattern":"\\Qorg/springframework/boot/autoconfigure/web/servlet/WebMvcAutoConfiguration$ResourceHandlerRegistrationCustomizer.class\\E"
}, {
"pattern":"\\Qorg/springframework/boot/autoconfigure/web/servlet/WebMvcAutoConfiguration$WebMvcAutoConfigurationAdapter.class\\E"
}, {
"pattern":"\\Qorg/springframework/boot/autoconfigure/web/servlet/WebMvcAutoConfiguration.class\\E"
}, {
"pattern":"\\Qorg/springframework/boot/autoconfigure/web/servlet/error/ErrorMvcAutoConfiguration$DefaultErrorViewResolverConfiguration.class\\E"
}, {
"pattern":"\\Qorg/springframework/boot/autoconfigure/web/servlet/error/ErrorMvcAutoConfiguration$ErrorPageCustomizer.class\\E"
}, {
"pattern":"\\Qorg/springframework/boot/autoconfigure/web/servlet/error/ErrorMvcAutoConfiguration$ErrorTemplateMissingCondition.class\\E"
}, {
"pattern":"\\Qorg/springframework/boot/autoconfigure/web/servlet/error/ErrorMvcAutoConfiguration$PreserveErrorControllerTargetClassPostProcessor.class\\E"
}, {
"pattern":"\\Qorg/springframework/boot/autoconfigure/web/servlet/error/ErrorMvcAutoConfiguration$StaticView.class\\E"
}, {
"pattern":"\\Qorg/springframework/boot/autoconfigure/web/servlet/error/ErrorMvcAutoConfiguration$WhitelabelErrorViewConfiguration.class\\E"
}, {
"pattern":"\\Qorg/springframework/boot/autoconfigure/web/servlet/error/ErrorMvcAutoConfiguration.class\\E"
}, {
"pattern":"\\Qorg/springframework/boot/autoconfigure/websocket/servlet/WebSocketServletAutoConfiguration$JettyWebSocketConfiguration.class\\E"
}, {
"pattern":"\\Qorg/springframework/boot/autoconfigure/websocket/servlet/WebSocketServletAutoConfiguration$TomcatWebSocketConfiguration.class\\E"
}, {
"pattern":"\\Qorg/springframework/boot/autoconfigure/websocket/servlet/WebSocketServletAutoConfiguration$UndertowWebSocketConfiguration.class\\E"
}, {
"pattern":"\\Qorg/springframework/boot/autoconfigure/websocket/servlet/WebSocketServletAutoConfiguration.class\\E"
}, {
"pattern":"\\Qorg/springframework/boot/context/properties/EnableConfigurationProperties.class\\E"
}, {
"pattern":"\\Qorg/springframework/boot/context/properties/EnableConfigurationPropertiesRegistrar.class\\E"
}, {
"pattern":"\\Qorg/springframework/boot/diagnostics/AbstractFailureAnalyzer.class\\E"
}, {
"pattern":"\\Qorg/springframework/boot/diagnostics/FailureAnalyzer.class\\E"
}, {
"pattern":"\\Qorg/springframework/boot/env/EnvironmentPostProcessor.class\\E"
}, {
"pattern":"\\Qorg/springframework/boot/sql/init/dependency/DatabaseInitializationDependencyConfigurer.class\\E"
}, {
"pattern":"\\Qorg/springframework/context/ApplicationContextAware.class\\E"
}, {
"pattern":"\\Qorg/springframework/context/ApplicationListener.class\\E"
}, {
"pattern":"\\Qorg/springframework/context/EnvironmentAware.class\\E"
}, {
"pattern":"\\Qorg/springframework/context/ResourceLoaderAware.class\\E"
}, {
"pattern":"\\Qorg/springframework/context/annotation/Conditional.class\\E"
}, {
"pattern":"\\Qorg/springframework/context/annotation/Configuration.class\\E"
}, {
"pattern":"\\Qorg/springframework/context/annotation/Import.class\\E"
}, {
"pattern":"\\Qorg/springframework/context/annotation/ImportBeanDefinitionRegistrar.class\\E"
}, {
"pattern":"\\Qorg/springframework/context/annotation/ImportRuntimeHints.class\\E"
}, {
"pattern":"\\Qorg/springframework/context/event/GenericApplicationListener.class\\E"
}, {
"pattern":"\\Qorg/springframework/context/event/SmartApplicationListener.class\\E"
}, {
"pattern":"\\Qorg/springframework/core/Ordered.class\\E"
}, {
"pattern":"\\Qorg/springframework/core/annotation/Order.class\\E"
}, {
"pattern":"\\Qorg/springframework/web/context/ServletContextAware.class\\E"
}, {
"pattern":"\\Qorg/springframework/web/servlet/config/annotation/DelegatingWebMvcConfiguration.class\\E"
}, {
"pattern":"\\Qorg/springframework/web/servlet/config/annotation/WebMvcConfigurationSupport$NoOpValidator.class\\E"
}, {
"pattern":"\\Qorg/springframework/web/servlet/config/annotation/WebMvcConfigurationSupport.class\\E"
}, {
"pattern":"\\Qorg/springframework/web/servlet/config/annotation/WebMvcConfigurer.class\\E"
}, {
"pattern":"\\Qorg/springframework/web/util/HtmlCharacterEntityReferences.properties\\E"
}]},
"bundles":[{
"name":"jakarta.servlet.LocalStrings",
"locales":[""]
}, {
"name":"jakarta.servlet.http.LocalStrings",
"locales":[""]
}, {
"name":"org.apache.catalina.authenticator.LocalStrings",
"locales":[""]
}, {
"name":"org.apache.catalina.authenticator.jaspic.LocalStrings",
"locales":[""]
}, {
"name":"org.apache.catalina.connector.LocalStrings",
"locales":[""]
}, {
"name":"org.apache.catalina.core.LocalStrings",
"locales":[""]
}, {
"name":"org.apache.catalina.deploy.LocalStrings",
"locales":[""]
}, {
"name":"org.apache.catalina.loader.LocalStrings",
"locales":[""]
}, {
"name":"org.apache.catalina.mapper.LocalStrings",
"locales":[""]
}, {
"name":"org.apache.catalina.mbeans.LocalStrings",
"locales":[""]
}, {
"name":"org.apache.catalina.realm.LocalStrings",
"locales":[""]
}, {
"name":"org.apache.catalina.security.LocalStrings",
"locales":[""]
}, {
"name":"org.apache.catalina.session.LocalStrings",
"locales":[""]
}, {
"name":"org.apache.catalina.startup.LocalStrings",
"locales":[""]
}, {
"name":"org.apache.catalina.util.LocalStrings",
"locales":[""]
}, {
"name":"org.apache.catalina.valves.LocalStrings",
"locales":[""]
}, {
"name":"org.apache.catalina.webresources.LocalStrings",
"locales":[""]
}, {
"name":"org.apache.coyote.LocalStrings",
"locales":[""]
}, {
"name":"org.apache.coyote.http11.LocalStrings",
"locales":[""]
}, {
"name":"org.apache.coyote.http11.filters.LocalStrings",
"locales":[""]
}, {
"name":"org.apache.naming.LocalStrings",
"locales":[""]
}, {
"name":"org.apache.tomcat.util.LocalStrings",
"locales":[""]
}, {
"name":"org.apache.tomcat.util.buf.LocalStrings",
"locales":[""]
}, {
"name":"org.apache.tomcat.util.compat.LocalStrings",
"locales":[""]
}, {
"name":"org.apache.tomcat.util.descriptor.web.LocalStrings",
"locales":[""]
}, {
"name":"org.apache.tomcat.util.http.LocalStrings",
"locales":[""]
}, {
"name":"org.apache.tomcat.util.http.parser.LocalStrings",
"locales":[""]
}, {
"name":"org.apache.tomcat.util.modeler.LocalStrings",
"locales":[""]
}, {
"name":"org.apache.tomcat.util.net.LocalStrings",
"locales":[""]
}, {
"name":"org.apache.tomcat.util.scan.LocalStrings",
"locales":[""]
}, {
"name":"org.apache.tomcat.util.threads.LocalStrings",
"locales":[""]
}, {
"name":"org.apache.tomcat.websocket.LocalStrings",
"locales":[""]
}, {
"name":"org.apache.tomcat.websocket.server.LocalStrings",
"locales":[""]
}]
}

View File

@ -0,0 +1,17 @@
{
"types":[
{
"name":"java.rmi.server.RemoteObject"
},
{
"name":"java.rmi.server.RemoteStub"
},
{
"name":"javax.management.remote.rmi.RMIServerImpl_Stub"
}
],
"lambdaCapturingTypes":[
],
"proxies":[
]
}

View File

@ -0,0 +1,2 @@
nacos.config.server-addr=localhost:8848
nacos.discovery.server-addr=localhost:8848

View File

@ -20,13 +20,13 @@
<parent>
<groupId>com.alibaba.boot</groupId>
<artifactId>nacos-spring-boot-samples</artifactId>
<version>0.2.4</version>
<version>${revision}</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>nacos-config-sample</artifactId>
<packaging>pom</packaging>
<packaging>jar</packaging>
<name>Nacos Spring Boot Config Sample</name>
<description>Nacos Spring Boot Config Sample</description>
<modules>
@ -38,7 +38,7 @@
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.1.6.RELEASE</version>
<version>2.5.12</version>
</dependency>
<dependency>
@ -62,11 +62,10 @@
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j</artifactId>
<version>2.11.2</version>
<version>2.13.2</version>
<type>pom</type>
</dependency>
</dependencies>
<build>

View File

@ -20,6 +20,7 @@ import com.alibaba.nacos.api.annotation.NacosInjected;
import com.alibaba.nacos.api.common.Constants;
import com.alibaba.nacos.api.config.ConfigService;
import com.alibaba.nacos.api.config.annotation.NacosValue;
import com.alibaba.nacos.spring.context.annotation.config.EnableNacosConfig;
import com.alibaba.nacos.spring.context.annotation.config.NacosPropertySource;
import org.springframework.beans.factory.annotation.Autowired;
@ -42,9 +43,10 @@ import static org.springframework.core.env.StandardEnvironment.SYSTEM_PROPERTIES
@SpringBootApplication
@NacosPropertySource(name = "custom", dataId = ConfigApplication.DATA_ID, first = true, before = SYSTEM_PROPERTIES_PROPERTY_SOURCE_NAME, after = SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME)
@EnableScheduling
@EnableNacosConfig
public class ConfigApplication {
public static final String content = "dept: Aliware\ngroup: Alibaba";
public static final String content = "dept=Aliware\ngroup=Alibaba";
public static final String DATA_ID = "test";

View File

@ -16,7 +16,7 @@
*/
package com.alibaba.boot.nacos.sample;
import java.util.Properties;
import java.util.Map;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
@ -33,6 +33,7 @@ import org.springframework.boot.logging.LoggingSystem;
import org.springframework.stereotype.Service;
/**
* print logger
* @author <a href="mailto:liaochunyhm@live.com">liaochuntao</a>
* @since
*/
@ -45,13 +46,13 @@ public class PrintLogger {
@Autowired
private LoggingSystem loggingSystem;
@NacosConfigListener(dataId = "nacos.log", timeout = 5000)
@NacosConfigListener(dataId = "${nacos.example.listener.data-id}", timeout = 5000)
public void onChange(String newLog) throws Exception {
Properties properties = new DefaultPropertiesConfigParse().parse(newLog);
Map<String, Object> properties = new DefaultPropertiesConfigParse().parse(newLog);
for (Object t : properties.keySet()) {
String key = String.valueOf(t);
if (key.startsWith(LOGGER_TAG)) {
String strLevel = properties.getProperty(key, "info");
String strLevel = (String) properties.getOrDefault(key, "info");
LogLevel level = LogLevel.valueOf(strLevel.toUpperCase());
loggingSystem.setLogLevel(key.replace(LOGGER_TAG, ""), level);
logger.info("{}:{}", key, strLevel);
@ -71,4 +72,4 @@ public class PrintLogger {
}
});
}
}
}

View File

@ -36,7 +36,7 @@ public class TestController {
@NacosValue(value = "${people.enable:bbbbb}", autoRefreshed = true)
private String enable;
@Value("${people.enable}")
@Value("${people.enable:}")
private String springEnable;
@Autowired

View File

@ -1,6 +1,11 @@
nacos.example.listener.data-id=nacos.log
nacos.config.bootstrap.enable=true
nacos.config.server-addr=127.0.0.1:8848
nacos.config.remote-first=true
nacos.config.data-ids=people,test
nacos.config.namespace=nacos-dev
nacos.config.group=DEVELOP
nacos.config.type=properties
nacos.config.auto-refresh=true
@ -8,6 +13,8 @@ nacos.config.max-retry=10
nacos.config.config-retry-time=2333
nacos.config.config-long-poll-timeout=46000
nacos.config.enable-remote-sync-config=true
nacos.config.username=nacos
nacos.config.password=nacos
nacos.config.ext-config[0].data-id=nacos.log.test
nacos.config.ext-config[0].group=LOG_DEVELOP

View File

@ -20,13 +20,13 @@
<parent>
<groupId>com.alibaba.boot</groupId>
<artifactId>nacos-spring-boot-samples</artifactId>
<version>0.2.4</version>
<version>${revision}</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>nacos-discovery-sample</artifactId>
<packaging>pom</packaging>
<packaging>jar</packaging>
<name>Nacos Spring Boot Discovery Sample</name>
<description>Nacos Spring Boot Discovery Sample</description>
<modules>

View File

@ -2,6 +2,7 @@ nacos.discovery.server-addr=127.0.0.1:8848
server.port=10012
spring.application.name=SPRING_BOOT_SERVICE
nacos.discovery.auto-register=true
nacos.discovery.register.ip=1.1.1.1
nacos.discovery.register.port=1
@ -11,7 +12,7 @@ nacos.discovery.register.enabled=true
nacos.discovery.register.ephemeral=true
nacos.discovery.register.clusterName=SPRINGBOOT
nacos.discovery.register.groupName=BOOT
nacos.discovery.register.serviceName=SPRING_BOOT_SERVICE
#nacos.discovery.register.serviceName=SPRING_BOOT_SERVICE
nacos.discovery.register.metadata.username=test
management.endpoints.web.exposure.include=*

View File

@ -20,7 +20,7 @@
<parent>
<groupId>com.alibaba.boot</groupId>
<artifactId>nacos-spring-boot-parent</artifactId>
<version>0.2.4</version>
<version>${revision}</version>
<relativePath>../nacos-spring-boot-parent/pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
@ -33,6 +33,7 @@
<modules>
<module>nacos-config-sample</module>
<module>nacos-discovery-sample</module>
<module>nacos-aot-sample</module>
</modules>
<build>

38
pom.xml
View File

@ -8,14 +8,16 @@
<version>7</version>
</parent>
<properties>
<revision>0.3.0-RC</revision>
<maven_javadoc_version>3.0.1</maven_javadoc_version>
<maven_surefire_version>2.19.1</maven_surefire_version>
<maven-source-plugin.version>3.1.0</maven-source-plugin.version>
<maven-flatten-version>1.1.0</maven-flatten-version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<groupId>com.alibaba.boot</groupId>
<artifactId>nacos-spring-boot-project</artifactId>
<version>0.2.4</version>
<version>${revision}</version>
<packaging>pom</packaging>
@ -33,6 +35,7 @@
<module>nacos-discovery-spring-boot-starter</module>
<module>nacos-discovery-spring-boot-actuator</module>
<module>nacos-spring-boot-samples</module>
<module>nacos-spring-boot-aot</module>
</modules>
<organization>
@ -74,6 +77,9 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<configuration>
<doclint>none</doclint>
</configuration>
<executions>
<execution>
<phase>package</phase>
@ -115,6 +121,34 @@
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>flatten-maven-plugin</artifactId>
<version>${maven-flatten-version}</version>
<configuration>
<updatePomFile>true</updatePomFile>
<flattenMode>resolveCiFriendliesOnly</flattenMode>
<pomElements>
<dependencies>expand</dependencies>
</pomElements>
</configuration>
<executions>
<execution>
<id>flatten</id>
<phase>process-resources</phase>
<goals>
<goal>flatten</goal>
</goals>
</execution>
<execution>
<id>flatten.clean</id>
<phase>clean</phase>
<goals>
<goal>clean</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
@ -130,4 +164,4 @@
</repository>
</distributionManagement>
</project>
</project>