Skip to content
This repository was archived by the owner on Feb 18, 2024. It is now read-only.

Commit 5798e36

Browse files
committed
add base init
1 parent a7d5a4e commit 5798e36

File tree

2 files changed

+226
-0
lines changed

2 files changed

+226
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,216 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
package com.ctrip.framework.apollo.spring.boot;
18+
19+
import com.ctrip.framework.apollo.Config;
20+
import com.ctrip.framework.apollo.ConfigService;
21+
import com.ctrip.framework.apollo.core.ConfigConsts;
22+
import com.ctrip.framework.apollo.spring.config.ConfigPropertySourceFactory;
23+
import com.ctrip.framework.apollo.spring.config.PropertySourcesConstants;
24+
import com.ctrip.framework.apollo.spring.util.SpringInjector;
25+
import com.ctrip.framework.apollo.util.factory.PropertiesFactory;
26+
import com.google.common.base.Splitter;
27+
import com.google.common.base.Strings;
28+
import org.slf4j.Logger;
29+
import org.slf4j.LoggerFactory;
30+
import org.springframework.boot.SpringApplication;
31+
import org.springframework.boot.env.EnvironmentPostProcessor;
32+
import org.springframework.context.ApplicationContextInitializer;
33+
import org.springframework.context.ConfigurableApplicationContext;
34+
import org.springframework.core.Ordered;
35+
import org.springframework.core.env.CompositePropertySource;
36+
import org.springframework.core.env.ConfigurableEnvironment;
37+
38+
import java.util.List;
39+
40+
/**
41+
* Initialize apollo system properties and inject the Apollo config in Spring Boot bootstrap phase
42+
*
43+
* <p>Configuration example:</p>
44+
* <pre class="code">
45+
* # set app.id
46+
* app.id = 100004458
47+
* # enable apollo bootstrap config and inject 'application' namespace in bootstrap phase
48+
* apollo.bootstrap.enabled = true
49+
* </pre>
50+
*
51+
* or
52+
*
53+
* <pre class="code">
54+
* # set app.id
55+
* app.id = 100004458
56+
* # enable apollo bootstrap config
57+
* apollo.bootstrap.enabled = true
58+
* # will inject 'application' and 'FX.apollo' namespaces in bootstrap phase
59+
* apollo.bootstrap.namespaces = application,FX.apollo
60+
* </pre>
61+
*
62+
*
63+
* If you want to load Apollo configurations even before Logging System Initialization Phase,
64+
* add
65+
* <pre class="code">
66+
* # set apollo.bootstrap.eagerLoad.enabled
67+
* apollo.bootstrap.eagerLoad.enabled = true
68+
* </pre>
69+
*
70+
* This would be very helpful when your logging configurations is set by Apollo.
71+
*
72+
* for example, you have defined logback-spring.xml in your project, and you want to inject some attributes into logback-spring.xml.
73+
*
74+
*/
75+
public class ApolloApplicationContextInitializer
76+
implements
77+
ApplicationContextInitializer<ConfigurableApplicationContext>,
78+
EnvironmentPostProcessor, Ordered {
79+
public static final int DEFAULT_ORDER = 0;
80+
81+
private static final Logger logger = LoggerFactory
82+
.getLogger(ApolloApplicationContextInitializer.class);
83+
private static final Splitter NAMESPACE_SPLITTER = Splitter.on(",")
84+
.omitEmptyStrings()
85+
.trimResults();
86+
private static final String[] APOLLO_SYSTEM_PROPERTIES = { "app.id",
87+
ConfigConsts.APOLLO_CLUSTER_KEY, "apollo.cacheDir", "apollo.accesskey.secret",
88+
ConfigConsts.APOLLO_META_KEY, PropertiesFactory.APOLLO_PROPERTY_ORDER_ENABLE };
89+
90+
private final ConfigPropertySourceFactory configPropertySourceFactory = SpringInjector
91+
.getInstance(ConfigPropertySourceFactory.class);
92+
93+
private int order = DEFAULT_ORDER;
94+
95+
@Override
96+
public void initialize(ConfigurableApplicationContext context) {
97+
ConfigurableEnvironment environment = context.getEnvironment();
98+
99+
if (!environment.getProperty(PropertySourcesConstants.APOLLO_BOOTSTRAP_ENABLED,
100+
Boolean.class, false)) {
101+
logger.debug(
102+
"Apollo bootstrap config is not enabled for context {}, see property: ${{}}",
103+
context, PropertySourcesConstants.APOLLO_BOOTSTRAP_ENABLED);
104+
return;
105+
}
106+
logger.debug("Apollo bootstrap config is enabled for context {}", context);
107+
108+
initialize(environment);
109+
}
110+
111+
/**
112+
* Initialize Apollo Configurations Just after environment is ready.
113+
*
114+
* @param environment
115+
*/
116+
protected void initialize(ConfigurableEnvironment environment) {
117+
118+
if (environment.getPropertySources().contains(
119+
PropertySourcesConstants.APOLLO_BOOTSTRAP_PROPERTY_SOURCE_NAME)) {
120+
//already initialized
121+
return;
122+
}
123+
124+
String namespaces = environment.getProperty(
125+
PropertySourcesConstants.APOLLO_BOOTSTRAP_NAMESPACES,
126+
ConfigConsts.NAMESPACE_APPLICATION);
127+
logger.debug("Apollo bootstrap namespaces: {}", namespaces);
128+
List<String> namespaceList = NAMESPACE_SPLITTER.splitToList(namespaces);
129+
130+
CompositePropertySource composite = new CompositePropertySource(
131+
PropertySourcesConstants.APOLLO_BOOTSTRAP_PROPERTY_SOURCE_NAME);
132+
for (String namespace : namespaceList) {
133+
Config config = ConfigService.getConfig(namespace);
134+
135+
composite.addPropertySource(configPropertySourceFactory.getConfigPropertySource(
136+
namespace, config));
137+
}
138+
139+
environment.getPropertySources().addFirst(composite);
140+
}
141+
142+
/**
143+
* To fill system properties from environment config
144+
*/
145+
void initializeSystemProperty(ConfigurableEnvironment environment) {
146+
for (String propertyName : APOLLO_SYSTEM_PROPERTIES) {
147+
fillSystemPropertyFromEnvironment(environment, propertyName);
148+
}
149+
}
150+
151+
private void fillSystemPropertyFromEnvironment(ConfigurableEnvironment environment,
152+
String propertyName) {
153+
if (System.getProperty(propertyName) != null) {
154+
return;
155+
}
156+
157+
String propertyValue = environment.getProperty(propertyName);
158+
159+
if (Strings.isNullOrEmpty(propertyValue)) {
160+
return;
161+
}
162+
163+
System.setProperty(propertyName, propertyValue);
164+
}
165+
166+
/**
167+
*
168+
* In order to load Apollo configurations as early as even before Spring loading logging system phase,
169+
* this EnvironmentPostProcessor can be called Just After ConfigFileApplicationListener has succeeded.
170+
*
171+
* <br />
172+
* The processing sequence would be like this: <br />
173+
* Load Bootstrap properties and application properties -----> load Apollo configuration properties ----> Initialize Logging systems
174+
*
175+
* @param configurableEnvironment
176+
* @param springApplication
177+
*/
178+
@Override
179+
public void postProcessEnvironment(ConfigurableEnvironment configurableEnvironment,
180+
SpringApplication springApplication) {
181+
182+
// should always initialize system properties like app.id in the first place
183+
// initializeSystemProperty(configurableEnvironment);
184+
185+
Boolean eagerLoadEnabled = configurableEnvironment.getProperty(
186+
PropertySourcesConstants.APOLLO_BOOTSTRAP_EAGER_LOAD_ENABLED, Boolean.class, false);
187+
188+
//EnvironmentPostProcessor should not be triggered if you don't want Apollo Loading before Logging System Initialization
189+
if (!eagerLoadEnabled) {
190+
return;
191+
}
192+
193+
Boolean bootstrapEnabled = configurableEnvironment.getProperty(
194+
PropertySourcesConstants.APOLLO_BOOTSTRAP_ENABLED, Boolean.class, false);
195+
196+
if (bootstrapEnabled) {
197+
initialize(configurableEnvironment);
198+
}
199+
200+
}
201+
202+
/**
203+
* @since 1.3.0
204+
*/
205+
@Override
206+
public int getOrder() {
207+
return order;
208+
}
209+
210+
/**
211+
* @since 1.3.0
212+
*/
213+
public void setOrder(int order) {
214+
this.order = order;
215+
}
216+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
app.id=SampleApp
2+
apollo.bootstrap.enabled=true
3+
apollo.bootstrap.eagerLoad.enabled=true
4+
apollo.bootstrap.namespaces=application
5+
apollo.autoUpdateInjectedSpringProperties=true
6+
7+
# ?? ???? docker ?? bridge ?????? Eureka ?????? apollo ?????
8+
# ????????????????????????? meta ????????????????
9+
# ?????? System.setProperty("apollo.configService", "http://localhost:8080")????????????
10+
apollo.meta=http://localhost:8080

0 commit comments

Comments
 (0)