{"id":13694650,"url":"https://github.com/nacos-group/nacos-spring-project","last_synced_at":"2025-05-15T04:08:02.250Z","repository":{"id":33032326,"uuid":"142377858","full_name":"nacos-group/nacos-spring-project","owner":"nacos-group","description":"Nacos ECO Project for Spring Framework","archived":false,"fork":false,"pushed_at":"2024-08-02T01:57:37.000Z","size":1358,"stargazers_count":762,"open_issues_count":62,"forks_count":309,"subscribers_count":62,"default_branch":"develop","last_synced_at":"2025-04-11T15:57:01.550Z","etag":null,"topics":["distributed-configuration","java","nacos","spring","springframework"],"latest_commit_sha":null,"homepage":"https://nacos.io/","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/nacos-group.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-07-26T02:30:01.000Z","updated_at":"2025-03-21T17:50:38.000Z","dependencies_parsed_at":"2022-08-07T19:30:28.137Z","dependency_job_id":"5e7d84cd-0106-4bac-9fac-51f84a4244ef","html_url":"https://github.com/nacos-group/nacos-spring-project","commit_stats":{"total_commits":239,"total_committers":35,"mean_commits":6.828571428571428,"dds":0.6276150627615062,"last_synced_commit":"bede11a7e2e189d49cd50b05e1be731e2d043f50"},"previous_names":[],"tags_count":14,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nacos-group%2Fnacos-spring-project","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nacos-group%2Fnacos-spring-project/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nacos-group%2Fnacos-spring-project/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nacos-group%2Fnacos-spring-project/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nacos-group","download_url":"https://codeload.github.com/nacos-group/nacos-spring-project/tar.gz/refs/heads/develop","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254270656,"owners_count":22042860,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["distributed-configuration","java","nacos","spring","springframework"],"created_at":"2024-08-02T17:01:36.475Z","updated_at":"2025-05-15T04:07:57.237Z","avatar_url":"https://github.com/nacos-group.png","language":"Java","funding_links":[],"categories":["Java"],"sub_categories":[],"readme":"Nacos Spring Project\n=================================\n\n[![Build Status](https://travis-ci.org/nacos-group/nacos-spring-project.svg?branch=master)](https://travis-ci.org/nacos-group/nacos-spring-project)\n\n[Nacos](https://github.com/alibaba/nacos) is an open source project for discovering, configuring and managing cloud-native applications. Key features of Nacos include:\n\n- Service Discovery and Service Health Check\n- Dynamic Configuration Management\n- Dynamic DNS Service\n- Service and Metadata Management\n\n[Nacos Spring Project](https://github.com/nacos-group/nacos-spring-project), which is based on [Nacos](https://github.com/alibaba/nacos), fully embraces the Spring ecosystem and is designed to help you build Spring applications rapidly. \n\nThe project contains a core module named [`nacos-spring-context`](nacos-spring-context). It enables you to expand modern Java programming models in the following ways:\n\n- [Annotation-Driven](#41-annotation-driven)\n- [Dependency Injection](#42-dependency-injection)\n- [Externalized Configuration](#43-externalized-configuration)\n- [Event-Driven](#44-eventlistener-driven)\n\nThese features strongly depend on Spring Framework 3.2+ API, and can be seamlessly integrated with any Spring Stack, such as Spring Boot and Spring Cloud.\n\n**Note:** We recommend that you use annotation-driven programming, even though XML-based features also work.\n\nContent\n===============================\n\u003c!-- TOC --\u003e\n\n- [1. Samples](#1-samples)\n    - [1.1. Samples](#11-samples)\n    - [1.2. How To Run the Samples](#12-how-to-run-the-samples)\n- [2. Dependencies \u0026 Compatibility](#2-dependencies--compatibility)\n- [3. Quickstart](#3-quickstart)\n    - [3.1. Prerequisite](#31-prerequisite)\n    - [3.2. Enable Nacos](#32-enable-nacos)\n    - [3.3. Enable configuration service](#33-enable-configuration-service)\n    - [3.4. Enable Service Discovery](#34-enable-service-discovery)\n- [4. Core Features](#4-core-features)\n    - [4.1. Annotation-Driven](#41-annotation-driven)\n        - [4.1.1. Enable Nacos](#411-enable-nacos)\n        - [4.1.2. Configure Change Listener method](#412-configure-change-listener-method)\n            - [4.1.2.1. Type Conversion](#4121-type-conversion)\n              - [4.1.2.1.1. Type Conversion during YAML Parsing](#41211-Type Conversion during YAML Parsing)\n            - [4.1.2.2. Timeout of Execution](#4122-timeout-of-execution)\n        - [4.1.3. Global and Special Nacos Properties](#413-global-and-special-nacos-properties)\n        - [4.1.4. `@NacosProperties`](#414-nacosproperties)\n    - [4.2. Dependency Injection](#42-dependency-injection)\n    - [4.3. Externalized Configuration](#43-externalized-configuration)\n    - [4.4. Event/Listener Driven](#44-eventlistener-driven)\n- [5. Modules](#5-modules)\n- [6. Relative Projects](#6-relative-projects)\n\n\u003c!-- /TOC --\u003e\n\n\n# 1. Samples\n\nIncluded in this section are some samples for you to get a quick start with Nacos Spring.\n\n## 1.1. Samples\n\n- [Dependency Injection Sample of `@NacosInjected`](https://github.com/nacos-group/nacos-spring-project/blob/master/nacos-spring-samples/nacos-spring-webmvc-sample/src/main/java/com/alibaba/nacos/samples/spring/NacosConfiguration.java)\n\n- [Simple Sample of `@NacosConfigListener`](https://github.com/nacos-group/nacos-spring-project/blob/master/nacos-spring-samples/nacos-spring-webmvc-sample/src/main/java/com/alibaba/nacos/samples/spring/listener/SimpleNacosConfigListener.java)\n\n- [Type Conversion Sample of `@NacosConfigListener`](https://github.com/nacos-group/nacos-spring-project/blob/master/nacos-spring-samples/nacos-spring-webmvc-sample/src/main/java/com/alibaba/nacos/samples/spring/listener/PojoNacosConfigListener.java)\n\n- [Timeout Sample of `@NacosConfigListener`](https://github.com/nacos-group/nacos-spring-project/blob/master/nacos-spring-samples/nacos-spring-webmvc-sample/src/main/java/com/alibaba/nacos/samples/spring/listener/TimeoutNacosConfigListener.java)\n\n- [Sample of `@NacosConfigurationProperties`/`@NacosProperty`/`@NacosIgnore`](https://github.com/nacos-group/nacos-spring-project/blob/master/nacos-spring-samples/nacos-spring-webmvc-sample/src/main/java/com/alibaba/nacos/samples/spring/properties/NacosConfigurationPropertiesConfiguration.java)\n\n- [Sample of `@NacosPropertySources`/`@NacosPropertySource`](https://github.com/nacos-group/nacos-spring-project/blob/master/nacos-spring-samples/nacos-spring-webmvc-sample/src/main/java/com/alibaba/nacos/samples/spring/env/NacosPropertySourceConfiguration.java)\n\n- [Event/Listener Sample](https://github.com/nacos-group/nacos-spring-project/blob/master/nacos-spring-samples/nacos-spring-webmvc-sample/src/main/java/com/alibaba/nacos/samples/spring/event/NacosEventListenerConfiguration.java)\n\n## 1.2. How To Run the Samples\n\nTake the Spring Web MVC project for example:\n\n1. Check out the source code of `nacos-spring-project` :\n   \n\t` $ git clone git@github.com:nacos-group/nacos-spring-project.git`\n\n2. Build your source code with Maven:\n    \n\t`$ mvn clean package`\n    \n3. Run Spring Web MVC Samples:\n\n      `$ java -jar target/nacos-spring-webmvc-sample.war`\n\n# 2. Dependencies \u0026 Compatibility\n\nThe following table shows the dependencies and compatabilities of Nacos Spring Project.\n\n| Dependencies   | Compatibility |\n| -------------- | ------------- |\n| Java           | 1.8+         |\n| Spring Context | 3.2+         |\n| [Alibaba Spring Context Support](https://github.com/alibaba/spring-context-support) | 1.0.1+ |\n| [Alibaba Nacos](https://github.com/alibaba/nacos) | 1.1.1+ |\n\n\n\n\n# 3. Quickstart\n\nThis quickstart shows you how to enable Nacos and its service discovery and configuration management features in your Spring project.\n\n## 3.1. Prerequisite\n\nBefore you configure your Spring project to use Nacos, you need to start a Nacos server in the backend. Refer to [Nacos Quick Start](https://nacos.io/en-us/docs/quick-start.html) for instructions on how to start a Nacos server.\n\n## 3.2. Enable Nacos\nComplete the following steps to enable Nacos for your Spring project.\n\n1. Add [`nacos-spring-context`](nacos-spring-context) in your Spring application's dependencies:\n\n\t```xml\n\t    \u003cdependencies\u003e\n\t        ...\n\t        \n\t        \u003cdependency\u003e\n\t            \u003cgroupId\u003ecom.alibaba.nacos\u003c/groupId\u003e\n\t            \u003cartifactId\u003enacos-spring-context\u003c/artifactId\u003e\n\t            \u003cversion\u003e1.1.0\u003c/version\u003e\n\t        \u003c/dependency\u003e\n\t        \n\t        ...\n\t    \u003c/dependencies\u003e\n\t```\n\n**Note:** Support Spring 5 from version 0.2.3-RC1, support Spring 6 from version 2.1.0.\n\n2. Add the `@EnableNacos` annotation in the `@Configuration` class of Spring and specify \"\\${host}:${port}\" of your Nacos server in the `serverAddr` attribute:\n\n\t```java\n\t@Configuration\n\t@EnableNacos(\n\t        globalProperties =\n\t        @NacosProperties(serverAddr = \"${nacos.server-addr:localhost:12345}\")\n\t)\n\tpublic class NacosConfiguration {\n\t    ...\n\t}\n\t```\n\n\n## 3.3. Enable configuration service\nNow you would like to use the confguration service of Nacos. Simply use **Dependency Injection** to inject `ConfigService` instance in your Spring Beans when `@EnableNacos` is annotated, as shown below: \n\n```java\n@Service\npublic class ConfigServiceDemo {\n\n    @NacosInjected\n    private ConfigService configService;\n    \n    public void demoGetConfig() {\n        try {\n            String dataId = \"{dataId}\";\n            String group = \"{group}\";\n            String content = configService.getConfig(dataId, groupId, 5000);\n        \tSystem.out.println(content);\n        } catch (NacosException e) {\n            e.printStackTrace();\n        }\n    }\n    ...\n}\n```\n\n`ConfigService` is the key interface of Nacos which helps you to get or publish configurations.\n\nThe following code achieves the same effect: \n\n```java\ntry {\n    // Initialize the configuration service, and the console automatically obtains the following parameters through the sample code.\n\tString serverAddr = \"{serverAddr}\";\n\tString dataId = \"{dataId}\";\n\tString group = \"{group}\";\n\tProperties properties = new Properties();\n\tproperties.put(\"serverAddr\", serverAddr);\n\tConfigService configService = NacosFactory.createConfigService(properties);\n    // Actively get the configuration.\n\tString content = configService.getConfig(dataId, group, 5000);\n\tSystem.out.println(content);\n} catch (NacosException e) {\n    // TODO Auto-generated catch block\n    e.printStackTrace();\n}\n```\n## 3.4. Enable Service Discovery\nIf you would also like to use the service discovery feature of Nacos, you can inject a `NamingService` instance for service discovery:\n\n```java\n    @NacosInjected\n    private NamingService namingService;\n```\n\nFor details about the usages of `ConfigService` and `NamingService`, please refer to [Nacos SDK](https://nacos.io/en-us/docs/sdk.html).\n\n\n\n# 4. Core Features\n\nThis section provides a detailed description of the key features of [`nacos-spring-context`](nacos-spring-context):\n\n- [Annotation-Driven](#annotation-driven)\n- [Dependency Injection](#dependency-injection)\n- [Externalized Configuration](#externalized-configuration)\n- [Event-Driven](#eventlistener-driven)\n\n\n\n## 4.1. Annotation-Driven\n\n### 4.1.1. Enable Nacos\n\n`@EnableNacos` is a modular-driven annotation that enables all features of Nacos Spring, including **Service Discovery** and **Distributed Configuration**. It equals to  `@EnableNacosDiscovery` and \n`@EnableNacosConfig`, which can be configured separately and used in different scenarios.\n\n### 4.1.2. Configure Change Listener method\n\nSuppose there was a config in Nacos Server whose `dataId` is \"testDataId\" and `groupId` is default group(\"DEFAULT_GROUP\"). Now you would like to change its content by using the `ConfigService#publishConfig` method:\n\n```java\n    @NacosInjected\n    private ConfigService configService;\n\n    @Test\n    public void testPublishConfig() throws NacosException {\n        configService.publishConfig(DATA_ID, DEFAULT_GROUP, \"9527\");\n    }\n```\n\nThen you would like to add a listener, which will be listening for the config changes. You can do this by adding a config change listener method into your Spring Beans:\n\n```java\n    @NacosConfigListener(dataId = DATA_ID)\n    public void onMessage(String config) {\n        assertEquals(\"mercyblitz\", config); // asserts true\n    }\n```\n\nThe code below has the same effect:\n\n```java\n\tconfigService.addListener(DATA_ID, DEFAULT_GROUP, new AbstractListener() {\n        @Override\n        public void receiveConfigInfo(String config) {\n            assertEquals(\"9527\", config); // asserts true\n        }\n    });\n```\n\n**Note:** `@NacosConfigListener` supports richer type conversions.\n\n- See [Simple Sample of `@NacosConfigListener`](https://github.com/nacos-group/nacos-spring-project/blob/master/nacos-spring-samples/nacos-spring-webmvc-sample/src/main/java/com/alibaba/nacos/samples/spring/listener/SimpleNacosConfigListener.java)\n\n\n\n\n#### 4.1.2.1. Type Conversion\n\nThe type conversion of `@NacosConfigListener` includes both build-in and customized implementations. By default, build-in type conversion is based on Spring `DefaultFormattingConversionService`, which means it covers most of the general cases as well as the rich features of the higher Spring framework. \n\nFor example, the content \"9527\" in the preceding example can also be listened by a method with integer or the `Integer` argument:\n\n```java\n    @NacosConfigListener(dataId = DATA_ID)\n    public void onInteger(Integer value) {\n        assertEquals(Integer.valueOf(9527), value); // asserts true\n    }\n\n    @NacosConfigListener(dataId = DATA_ID)\n    public void onInt(int value) {\n        assertEquals(9527, value); // asserts true\n    }\n```\n\nOf course, [`nacos-spring-context`](nacos-spring-context) provides elastic extension for developers. If you define a named `nacosConfigConversionService` Spring Bean whose type is `ConversionService` , the `DefaultFormattingConversionService` will be ignored. In addition, you can customize the implementation of  the `NacosConfigConverter` interface to specify a listener method for type conversion:\n\n```java\npublic class UserNacosConfigConverter implements NacosConfigConverter\u003cUser\u003e {\n\n    @Override\n    public boolean canConvert(Class\u003cUser\u003e targetType) {\n        return true;\n    }\n\n    @Override\n    public User convert(String source) {\n        return JSON.parseObject(source, User.class);\n    }\n}\n```\n\nThe `UserNacosConfigConverter` class binds the `@NacosConfigListener.converter()` attribute:\n\n```java\n\t@NacosInjected\n    private ConfigService configService;\n\n\t@Test\n    public void testPublishUser() throws NacosException {\n        configService.publishConfig(\"user\", DEFAULT_GROUP, \"{\\\"id\\\":1,\\\"name\\\":\\\"mercyblitz\\\"}\");\n    }\n\n    @NacosConfigListener(dataId = \"user\", converter = UserNacosConfigConverter.class)\n    public void onUser(User user) {\n        assertEquals(Long.valueOf(1L), user.getId()); \n        assertEquals(\"mercyblitz\", user.getName());\n    }\n```\n\n##### 4.1.2.1.1. Type Conversion during YAML Parsing\n\nBy default, starting from version 1.1.2, this library uses `SafeConstructor` for type conversion during YAML parsing. This is done to ensure that potentially unsafe code is not executed during the parsing process. `SafeConstructor` provides a secure construction logic for mapping YAML structures to Java objects.\n\n**System Property Toggle**\n\nTo maintain compatibility with versions prior to 1.1.2, we have introduced a system property toggle named `yamlAllowComplexObject`. Prior to version 1.1.2, the library defaulted to using `Constructor`, another constructor in the SnakeYAML library that supports more complex object mapping. Starting from version 1.1.2, the default is switched to `SafeConstructor`.\n\n**Potential Risks**\n\nIt's important to note that enabling `Constructor` introduces some potential risks, particularly the risk of Remote Code Execution (`RCE`). This is because `Constructor` allows more flexible object construction, but it also increases the risk of handling malicious YAML input.\n\n**Recommendations**\n\n- We recommend using the `NacosConfigConverter` for custom conversions.\n\n**If You Must Use `Constructor`**\n\n- Ensure that the source of the YAML data is secure.\n\n**How to Disable `SafeConstructor`**\n\nYou can set the toggle by adding a JVM system property when starting your application. For example, in the command line:\n\n```bash\njava -DyamlAllowComplexObject=true -jar your-application.jar\n```\n\n- See [Type Conversion Sample of `@NacosConfigListener`](https://github.com/nacos-group/nacos-spring-project/blob/master/nacos-spring-samples/nacos-spring-webmvc-sample/src/main/java/com/alibaba/nacos/samples/spring/listener/PojoNacosConfigListener.java)\n\n\n\n\n#### 4.1.2.2. Timeout of Execution\n\nAs it might cost some time to run customized `NacosConfigConverter`, you can set  max execution time in the `@NacosConfigListener.timeout()` attribute to prevent it from blocking other listeners:\n\n```java\n@Configuration\npublic class Listeners {\n\n    private Integer integerValue;\n\n    private Double doubleValue;\n\n    @NacosConfigListener(dataId = DATA_ID, timeout = 50)\n    public void onInteger(Integer value) throws Exception {\n        Thread.sleep(100); // timeout of execution\n        this.integerValue = value;\n    }\n\n    @NacosConfigListener(dataId = DATA_ID, timeout = 200)\n    public void onDouble(Double value) throws Exception {\n        Thread.sleep(100); // normal execution\n        this.doubleValue = value;\n    }\n\n    public Integer getIntegerValue() {\n        return integerValue;\n    }\n\n    public Double getDoubleValue() {\n        return doubleValue;\n    }\n}\n```\n\nThe `integerValue` of `Listeners` Bean is always `null` and will not be changed. Therefore, those asserts will be `true`:\n\n```java\n    @Autowired\n    private Listeners listeners;\n\n    @Test\n    public void testPublishConfig() throws NacosException {\n        configService.publishConfig(DATA_ID, DEFAULT_GROUP, \"9527\");\n        assertNull(listeners.getIntegerValue()); // asserts true\n        assertEquals(Double.valueOf(9527), listeners.getDoubleValue());   // asserts true\n    }\n```\n\n\n\n\n- See [Timeout Sample of `@NacosConfigListener`](https://github.com/nacos-group/nacos-spring-project/blob/master/nacos-spring-samples/nacos-spring-webmvc-sample/src/main/java/com/alibaba/nacos/samples/spring/listener/TimeoutNacosConfigListener.java)\n\n### 4.1.3. Global and Special Nacos Properties\n\nThe `globalProperties` is a required attribute in any `@EnableNacos`, `@EnableNacosDiscovery` or `@EnableNacosConfig`, and its type is `@NacosProperties`. `globalProperties` initializes \"**Global Nacos Properties**\" that will be used by other annotations \nand components, e,g `@NacosInjected`. In other words, **Global Nacos Properties**\" defines the global and default properties. It is set with the lowest priority and can be overridden if needed. The precedence of overiding rules is shown in the following table:\n\n| Precedence Order | Nacos Annotation                                             | Required |\n| ---------------- | ------------------------------------------------------------ | -------- |\n| 1                | `*.properties()`                                             | N        |\n| 2                | `@EnableNacosConfig.globalProperties()` or `@EnableNacosDiscovery.globalProperties()` | Y        |\n| 3                | `@EnableNacos.globalProperties()`                            | Y        |\n\n\n`*.properties()` defines special Nacos properties which come from one of the following:  \n\n- `@NacosInjected.properties()` \n- `@NacosConfigListener.properties()`\n- `@NacosPropertySource.properties()` \n- `@NacosConfigurationProperties.properties()`\n\nSpecial Nacos properties are also configured by `@NacosProperties`. However, they are optional and are used to override Global Nacos Properties in special scenarios. If not defined, the Nacos Properties will \ntry to retrieve properities from `@EnableNacosConfig.globalProperties()` or `@EnableNacosDiscovery.globalProperties()`, or \n`@EnableNacos.globalProperties()`.\n\n\n\n### 4.1.4. `Nacos Properties`\n\n`@NacosProperties` is a uniform annotation for global and special Nacos properties. It serves as a mediator between Java `Properties` and `NacosFactory` class.   `NacosFactory` is responsible for creating `ConfigService` or `NamingService` instances. \n\nThe attributes of `@NacosProperties` completely support placeholders whose source is all kinds of `PropertySource` in Spring `Environment` abstraction, typically Java System `Properties` and OS environment variables. The prefix of all placeholders are `nacos.`.  The mapping between the attributes of `@NacosProperties` and Nacos properties are shown below: \n\n| Attribute       | Property       | Placeholder              | Description | Required  |\n| --------------- | -------------- | ------------------------ | ----------- | --------- |\n| `endpoint()`    | `endpoint`     | `${nacos.endpoint:}`     |             |     N     |\n| `namespace()`   | `namespace`    | `${nacos.namespace:}`    |             |     N     |\n| `accessKey()`   | `access-key`   | `${nacos.access-key:}`   |             |     N     |\n| `secretKey()`   | `secret-key`   | `${nacos.secret-key:}`   |             |     N     |\n| `serverAddr()`  | `server-addr`  | `${nacos.server-addr:}`  |             |     Y     |\n| `contextPath()` | `context-path` | `${nacos.context-path:}` |             |     N     |\n| `clusterName()` | `cluster-name` | `${nacos.cluster-name:}` |             |     N     |\n| `encode()`      | `encode`       | `${nacos.encode:UTF-8}`  |             |     N     |\n\n\nNote that there are some differences in the placeholders of `globalProperties()` between `@EnableNacosDiscovery` and `@EnableNacosConfig`:\n\n\n| Attribute       | `@EnableNacosDiscovery`'s Placeholder                     |`@EnableNacosConfig`'s Placeholder  |\n| --------------- | -------------------------------------------------------- | -------------------------------------------------    |\n| `endpoint()`    | `${nacos.discovery.endpoint:${nacos.endpoint:}}`         |`${nacos.config.endpoint:${nacos.endpoint:}}`         |\n| `namespace()`   | `${nacos.discovery.namespace:${nacos.namespace:}}`       |`${nacos.config.namespace:${nacos.namespace:}}`       |\n| `accessKey()`   | `${nacos.discovery.access-key:${nacos.access-key:}}`     |`${nacos.config.access-key:${nacos.access-key:}}`     |\n| `secretKey()`   | `${nacos.discovery.secret-key:${nacos.secret-key:}}`     |`${nacos.config.secret-key:${nacos.secret-key:}}`     |\n| `serverAddr()`  | `${nacos.discovery.server-addr:${nacos.server-addr:}}`   | `${nacos.config.server-addr:${nacos.server-addr:}}`   |\n| `contextPath()` | `${nacos.discovery.context-path:${nacos.context-path:}}` | `${nacos.config.context-path:${nacos.context-path:}}` |\n| `clusterName()` | `${nacos.discovery.cluster-name:${nacos.cluster-name:}}` |`${nacos.config.cluster-name:${nacos.cluster-name:}}` |\n| `encode()`      | `${nacos.discovery.encode:${nacos.encode:UTF-8}}`        |`${nacos.config.encode:${nacos.encode:UTF-8}}`        |\n\n\n\nThese placeholders of `@EnableNacosDiscovery` and `@EnableNacosConfig` are designed to isolate different Nacos servers, and are unnecessary in most scenarios.  By default, general placeholders will be reused.\n\n\n\n\n## 4.2. Dependency Injection\n\n`@NacosInjected` is a core annotation which is used to inject `ConfigService` or `NamingService` instance in your Spring Beans and make these instances **cacheable**. This means the instances will be the same if their `@NacosProperties` are equal, regargless of whether the properties come from global or special Nacos properties:\n\n```java\n    @NacosInjected\n    private ConfigService configService;\n\n    @NacosInjected(properties = @NacosProperties(encode = \"UTF-8\"))\n    private ConfigService configService2;\n\n    @NacosInjected(properties = @NacosProperties(encode = \"GBK\"))\n    private ConfigService configService3;\n\n    @NacosInjected\n    private NamingService namingService;\n\n    @NacosInjected(properties = @NacosProperties(encode = \"UTF-8\"))\n    private NamingService namingService2;\n\n    @NacosInjected(properties = @NacosProperties(encode = \"GBK\"))\n    private NamingService namingService3;\n\n    @Test\n    public void testInjection() {\n\n        Assert.assertEquals(configService, configService2);\n        Assert.assertNotEquals(configService2, configService3);\n\n        Assert.assertEquals(namingService, namingService2);\n        Assert.assertNotEquals(namingService2, namingService3);\n    }\n```\n\nThe property `configService` uses `@EnableNacos#globalProperties()` or `@EnableNacosConfig#globalProperties()`, and because the default value of the `encode` attribute is “UTF-8”, therefore the `configService` instance and the `configService2` instance which is annotated by `@NacosProperties(encode = \"UTF-8\")` are the same. The same is true for `namingService` and `namingService2`.\n\nMore importantly, unlike the `ConfigService` instances created by the `NacosFactory.createConfigService()` method, the `ConfigService` instances created by the `@NacosInjected` annotation support Nacos Spring events. For instance, there will be an `NacosConfigPublishedEvent`  after an enhanced `ConfigService` invokes the `publishConfig()` method. Refer to the [Event/Listener Driven](#eventlistener-driven) section for more details.\n\n\n\n\n- See [Dependency Injection Sample](https://github.com/nacos-group/nacos-spring-project/blob/master/nacos-spring-samples/nacos-spring-webmvc-sample/src/main/java/com/alibaba/nacos/samples/spring/NacosConfiguration.java)\n\n\n\n\n## 4.3. Externalized Configuration\n\nExternalized configuration is a concept introduced by Spring Boot, which allows applications to receive external property sources to control runtime behavior. Nacos Server runs an isolation process outside the application to maintain the application configurations. [`nacos-spring-context`](nacos-spring-context) provides properties features including object binding, dynamic configuration(auto-refreshed) and so on, and dependence on Spring Boot or Spring Cloud framework is required.\n\nHere is a simple comparison between  [`nacos-spring-context`](nacos-spring-context) and Spring stack:\n\n| Spring Stack               | Nacos Spring                    | Highlight                                      |\n| -------------------------- | ------------------------------- | ---------------------------------------------- |\n| `@Value`                   | `@NacosValue`                   | auto-refreshed                                 |\n| `@ConfigurationProperties` | `@NacosConfigurationProperties` | auto-refreshed,`@NacosProperty`,`@NacosIgnore` |\n| `@PropertySource`          | `@NacosPropertySource`          | auto-refreshed, precedence order control       |\n| `@PropertySources`         | `@NacosPropertySources`         |                                                |\n\n\n\n\n- See [Auto-Refreshed Sample of `@NacosConfigurationProperties`](https://github.com/nacos-group/nacos-spring-project/blob/master/nacos-spring-samples/nacos-spring-webmvc-sample/src/main/java/com/alibaba/nacos/samples/spring/properties/NacosConfigurationPropertiesConfiguration.java)\n\n\n\n- See [Sample of `@NacosPropertySources` and `@NacosPropertySource`](https://github.com/nacos-group/nacos-spring-project/blob/master/nacos-spring-samples/nacos-spring-webmvc-sample/src/main/java/com/alibaba/nacos/samples/spring/env/NacosPropertySourceConfiguration.java)\n\n\n\n## 4.4. Event/Listener Driven\n\nNacos Event/Listener Driven is based on the standard Spring Event/Listener mechanism. The `ApplicationEvent` of Spring is an abstract super class for all Nacos Spring events:\n\n| Nacos Spring Event                           | Trigger                                                      |\n| -------------------------------------------- | ------------------------------------------------------------ |\n| `NacosConfigPublishedEvent`                  | After `ConfigService.publishConfig()`                        |\n| `NacosConfigReceivedEvent`                   | After`Listener.receiveConfigInfo()`                          |\n| `NacosConfigRemovedEvent`                    | After `configService.removeConfig()`                         |\n| `NacosConfigTimeoutEvent`                    | `ConfigService.getConfig()` on timeout                       |\n| `NacosConfigListenerRegisteredEvent`         | After `ConfigService.addListner()` or `ConfigService.removeListener()` |\n| `NacosConfigurationPropertiesBeanBoundEvent` | After `@NacosConfigurationProperties` binding                |\n| `NacosConfigMetadataEvent`                   | After Nacos Config operations                                |\n\n- See [Event/Listener Sample](https://github.com/nacos-group/nacos-spring-project/blob/master/nacos-spring-samples/nacos-spring-webmvc-sample/src/main/java/com/alibaba/nacos/samples/spring/event/NacosEventListenerConfiguration.java)\n\n\n\n\n\n\n\n# 5. Modules\n\n- [`nacos-spring-context`](nacos-spring-context)\n  \n- [`nacos-spring-samples`](nacos-spring-samples)\n\n\n\n# 6. Relative Projects\n\n- [Alibaba Nacos](https://github.com/alibaba/nacos)\n- [Alibaba Spring Context Support](https://github.com/alibaba/spring-context-support)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnacos-group%2Fnacos-spring-project","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnacos-group%2Fnacos-spring-project","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnacos-group%2Fnacos-spring-project/lists"}