Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
wrr-cat
apollo
提交
ee51eff4
apollo
项目概览
wrr-cat
/
apollo
与 Fork 源项目一致
从无法访问的项目Fork
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
apollo
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
提交
ee51eff4
编写于
2月 15, 2017
作者:
J
Jason Song
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Apollo client integration with Spring
上级
87129adc
变更
45
隐藏空白更改
内联
并排
Showing
45 changed file
with
1869 addition
and
8 deletion
+1869
-8
apollo-client/pom.xml
apollo-client/pom.xml
+6
-0
apollo-client/src/main/java/com/ctrip/framework/apollo/spring/annotation/ApolloAnnotationProcessor.java
...k/apollo/spring/annotation/ApolloAnnotationProcessor.java
+83
-0
apollo-client/src/main/java/com/ctrip/framework/apollo/spring/annotation/ApolloConfig.java
...trip/framework/apollo/spring/annotation/ApolloConfig.java
+31
-0
apollo-client/src/main/java/com/ctrip/framework/apollo/spring/annotation/ApolloConfigChangeListener.java
.../apollo/spring/annotation/ApolloConfigChangeListener.java
+33
-0
apollo-client/src/main/java/com/ctrip/framework/apollo/spring/annotation/ApolloConfigRegistrar.java
...ework/apollo/spring/annotation/ApolloConfigRegistrar.java
+35
-0
apollo-client/src/main/java/com/ctrip/framework/apollo/spring/annotation/EnableApolloConfig.java
...ramework/apollo/spring/annotation/EnableApolloConfig.java
+44
-0
apollo-client/src/main/java/com/ctrip/framework/apollo/spring/config/ConfigPropertySource.java
.../framework/apollo/spring/config/ConfigPropertySource.java
+21
-0
apollo-client/src/main/java/com/ctrip/framework/apollo/spring/config/ConfigPropertySourcesProcessor.java
.../apollo/spring/config/ConfigPropertySourcesProcessor.java
+26
-0
apollo-client/src/main/java/com/ctrip/framework/apollo/spring/config/NamespaceHandler.java
...trip/framework/apollo/spring/config/NamespaceHandler.java
+58
-0
apollo-client/src/main/java/com/ctrip/framework/apollo/spring/config/PropertySourcesProcessor.java
...mework/apollo/spring/config/PropertySourcesProcessor.java
+77
-0
apollo-client/src/main/java/com/ctrip/framework/apollo/spring/package-info.java
.../java/com/ctrip/framework/apollo/spring/package-info.java
+19
-0
apollo-client/src/main/java/com/ctrip/framework/apollo/spring/util/BeanRegistrationUtil.java
...ip/framework/apollo/spring/util/BeanRegistrationUtil.java
+33
-0
apollo-client/src/main/resources/META-INF/apollo-1.0.0.xsd
apollo-client/src/main/resources/META-INF/apollo-1.0.0.xsd
+41
-0
apollo-client/src/main/resources/META-INF/spring.handlers
apollo-client/src/main/resources/META-INF/spring.handlers
+1
-0
apollo-client/src/main/resources/META-INF/spring.schemas
apollo-client/src/main/resources/META-INF/spring.schemas
+2
-0
apollo-client/src/test/java/com/ctrip/framework/apollo/AllTests.java
...nt/src/test/java/com/ctrip/framework/apollo/AllTests.java
+8
-3
apollo-client/src/test/java/com/ctrip/framework/apollo/internals/DefaultConfigManagerTest.java
.../framework/apollo/internals/DefaultConfigManagerTest.java
+2
-2
apollo-client/src/test/java/com/ctrip/framework/apollo/internals/RemoteConfigLongPollServiceTest.java
...ork/apollo/internals/RemoteConfigLongPollServiceTest.java
+1
-1
apollo-client/src/test/java/com/ctrip/framework/apollo/spring/AbstractSpringIntegrationTest.java
...ramework/apollo/spring/AbstractSpringIntegrationTest.java
+76
-0
apollo-client/src/test/java/com/ctrip/framework/apollo/spring/JavaConfigAnnotationTest.java
...rip/framework/apollo/spring/JavaConfigAnnotationTest.java
+254
-0
apollo-client/src/test/java/com/ctrip/framework/apollo/spring/JavaConfigPlaceholderTest.java
...ip/framework/apollo/spring/JavaConfigPlaceholderTest.java
+231
-0
apollo-client/src/test/java/com/ctrip/framework/apollo/spring/XMLConfigAnnotationTest.java
...trip/framework/apollo/spring/XMLConfigAnnotationTest.java
+207
-0
apollo-client/src/test/java/com/ctrip/framework/apollo/spring/XmlConfigPlaceholderTest.java
...rip/framework/apollo/spring/XmlConfigPlaceholderTest.java
+147
-0
apollo-client/src/test/resources/spring/XmlConfigAnnotationTest1.xml
...nt/src/test/resources/spring/XmlConfigAnnotationTest1.xml
+10
-0
apollo-client/src/test/resources/spring/XmlConfigAnnotationTest2.xml
...nt/src/test/resources/spring/XmlConfigAnnotationTest2.xml
+10
-0
apollo-client/src/test/resources/spring/XmlConfigAnnotationTest3.xml
...nt/src/test/resources/spring/XmlConfigAnnotationTest3.xml
+10
-0
apollo-client/src/test/resources/spring/XmlConfigAnnotationTest4.xml
...nt/src/test/resources/spring/XmlConfigAnnotationTest4.xml
+10
-0
apollo-client/src/test/resources/spring/XmlConfigAnnotationTest5.xml
...nt/src/test/resources/spring/XmlConfigAnnotationTest5.xml
+10
-0
apollo-client/src/test/resources/spring/XmlConfigPlaceholderTest1.xml
...t/src/test/resources/spring/XmlConfigPlaceholderTest1.xml
+13
-0
apollo-client/src/test/resources/spring/XmlConfigPlaceholderTest2.xml
...t/src/test/resources/spring/XmlConfigPlaceholderTest2.xml
+13
-0
apollo-client/src/test/resources/spring/XmlConfigPlaceholderTest3.xml
...t/src/test/resources/spring/XmlConfigPlaceholderTest3.xml
+13
-0
apollo-client/src/test/resources/spring/XmlConfigPlaceholderTest4.xml
...t/src/test/resources/spring/XmlConfigPlaceholderTest4.xml
+14
-0
apollo-client/src/test/resources/spring/XmlConfigPlaceholderTest5.xml
...t/src/test/resources/spring/XmlConfigPlaceholderTest5.xml
+13
-0
apollo-demo/pom.xml
apollo-demo/pom.xml
+57
-2
apollo-demo/src/main/java/com/ctrip/framework/apollo/demo/api/ApolloConfigDemo.java
...com/ctrip/framework/apollo/demo/api/ApolloConfigDemo.java
+2
-0
apollo-demo/src/main/java/com/ctrip/framework/apollo/demo/api/SimpleApolloConfigDemo.java
...rip/framework/apollo/demo/api/SimpleApolloConfigDemo.java
+2
-0
apollo-demo/src/main/java/com/ctrip/framework/apollo/demo/spring/AnnotationApplication.java
...p/framework/apollo/demo/spring/AnnotationApplication.java
+23
-0
apollo-demo/src/main/java/com/ctrip/framework/apollo/demo/spring/XmlApplication.java
...om/ctrip/framework/apollo/demo/spring/XmlApplication.java
+24
-0
apollo-demo/src/main/java/com/ctrip/framework/apollo/demo/spring/bean/AnnotatedBean.java
...trip/framework/apollo/demo/spring/bean/AnnotatedBean.java
+67
-0
apollo-demo/src/main/java/com/ctrip/framework/apollo/demo/spring/bean/NormalBean.java
...m/ctrip/framework/apollo/demo/spring/bean/NormalBean.java
+28
-0
apollo-demo/src/main/java/com/ctrip/framework/apollo/demo/spring/bean/XmlBean.java
.../com/ctrip/framework/apollo/demo/spring/bean/XmlBean.java
+62
-0
apollo-demo/src/main/java/com/ctrip/framework/apollo/demo/spring/config/AnotherAppConfig.java
...framework/apollo/demo/spring/config/AnotherAppConfig.java
+13
-0
apollo-demo/src/main/java/com/ctrip/framework/apollo/demo/spring/config/AppConfig.java
.../ctrip/framework/apollo/demo/spring/config/AppConfig.java
+22
-0
apollo-demo/src/main/resources/log4j2.xml
apollo-demo/src/main/resources/log4j2.xml
+3
-0
apollo-demo/src/main/resources/spring.xml
apollo-demo/src/main/resources/spring.xml
+14
-0
未找到文件。
apollo-client/pom.xml
浏览文件 @
ee51eff4
...
...
@@ -32,6 +32,12 @@
<groupId>
org.slf4j
</groupId>
<artifactId>
slf4j-api
</artifactId>
</dependency>
<!-- optional spring dependency -->
<dependency>
<groupId>
org.springframework
</groupId>
<artifactId>
spring-context
</artifactId>
<optional>
true
</optional>
</dependency>
<!-- test -->
<dependency>
<groupId>
org.eclipse.jetty
</groupId>
...
...
apollo-client/src/main/java/com/ctrip/framework/apollo/spring/annotation/ApolloAnnotationProcessor.java
0 → 100644
浏览文件 @
ee51eff4
package
com.ctrip.framework.apollo.spring.annotation
;
import
com.google.common.base.Preconditions
;
import
com.ctrip.framework.apollo.Config
;
import
com.ctrip.framework.apollo.ConfigChangeListener
;
import
com.ctrip.framework.apollo.ConfigService
;
import
com.ctrip.framework.apollo.model.ConfigChangeEvent
;
import
org.springframework.beans.BeansException
;
import
org.springframework.beans.factory.config.BeanPostProcessor
;
import
org.springframework.core.annotation.AnnotationUtils
;
import
org.springframework.util.ReflectionUtils
;
import
java.lang.reflect.Field
;
import
java.lang.reflect.Method
;
/**
* Apollo Annotation Processor for Spring Application
*
* @author Jason Song(song_s@ctrip.com)
*/
public
class
ApolloAnnotationProcessor
implements
BeanPostProcessor
{
@Override
public
Object
postProcessBeforeInitialization
(
Object
bean
,
String
beanName
)
throws
BeansException
{
Class
clazz
=
bean
.
getClass
();
processFields
(
bean
,
clazz
.
getDeclaredFields
());
processMethods
(
bean
,
clazz
.
getDeclaredMethods
());
return
bean
;
}
@Override
public
Object
postProcessAfterInitialization
(
Object
bean
,
String
beanName
)
throws
BeansException
{
return
bean
;
}
private
void
processFields
(
Object
bean
,
Field
[]
declaredFields
)
{
for
(
Field
field
:
declaredFields
)
{
ApolloConfig
annotation
=
AnnotationUtils
.
getAnnotation
(
field
,
ApolloConfig
.
class
);
if
(
annotation
==
null
)
{
continue
;
}
Preconditions
.
checkArgument
(
Config
.
class
.
isAssignableFrom
(
field
.
getType
()),
"Invalid type: %s for field: %s, should be Config"
,
field
.
getType
(),
field
);
String
namespace
=
annotation
.
value
();
Config
config
=
ConfigService
.
getConfig
(
namespace
);
ReflectionUtils
.
makeAccessible
(
field
);
ReflectionUtils
.
setField
(
field
,
bean
,
config
);
}
}
private
void
processMethods
(
final
Object
bean
,
Method
[]
declaredMethods
)
{
for
(
final
Method
method
:
declaredMethods
)
{
ApolloConfigChangeListener
annotation
=
AnnotationUtils
.
findAnnotation
(
method
,
ApolloConfigChangeListener
.
class
);
if
(
annotation
==
null
)
{
continue
;
}
Class
<?>[]
parameterTypes
=
method
.
getParameterTypes
();
Preconditions
.
checkArgument
(
parameterTypes
.
length
==
1
,
"Invalid number of parameters: %s for method: %s, should be 1"
,
parameterTypes
.
length
,
method
);
Preconditions
.
checkArgument
(
ConfigChangeEvent
.
class
.
isAssignableFrom
(
parameterTypes
[
0
]),
"Invalid parameter type: %s for method: %s, should be ConfigChangeEvent"
,
parameterTypes
[
0
],
method
);
ReflectionUtils
.
makeAccessible
(
method
);
String
[]
namespaces
=
annotation
.
value
();
for
(
String
namespace
:
namespaces
)
{
Config
config
=
ConfigService
.
getConfig
(
namespace
);
config
.
addChangeListener
(
new
ConfigChangeListener
()
{
@Override
public
void
onChange
(
ConfigChangeEvent
changeEvent
)
{
ReflectionUtils
.
invokeMethod
(
method
,
bean
,
changeEvent
);
}
});
}
}
}
}
apollo-client/src/main/java/com/ctrip/framework/apollo/spring/annotation/ApolloConfig.java
0 → 100644
浏览文件 @
ee51eff4
package
com.ctrip.framework.apollo.spring.annotation
;
import
com.ctrip.framework.apollo.core.ConfigConsts
;
import
java.lang.annotation.Documented
;
import
java.lang.annotation.ElementType
;
import
java.lang.annotation.Retention
;
import
java.lang.annotation.RetentionPolicy
;
import
java.lang.annotation.Target
;
/**
* Use this annotation to inject Apollo Config Instance.
*
* <p>Usage example:</p>
* <pre class="code">
* //Inject the config for "someNamespace"
* @ApolloConfig("someNamespace")
* private Config config;
* </pre>
*
* @author Jason Song(song_s@ctrip.com)
*/
@Retention
(
RetentionPolicy
.
RUNTIME
)
@Target
(
ElementType
.
FIELD
)
@Documented
public
@interface
ApolloConfig
{
/**
* Apollo namespace for the config, if not specified then default to application
*/
String
value
()
default
ConfigConsts
.
NAMESPACE_APPLICATION
;
}
apollo-client/src/main/java/com/ctrip/framework/apollo/spring/annotation/ApolloConfigChangeListener.java
0 → 100644
浏览文件 @
ee51eff4
package
com.ctrip.framework.apollo.spring.annotation
;
import
com.ctrip.framework.apollo.core.ConfigConsts
;
import
java.lang.annotation.Documented
;
import
java.lang.annotation.ElementType
;
import
java.lang.annotation.Retention
;
import
java.lang.annotation.RetentionPolicy
;
import
java.lang.annotation.Target
;
/**
* Use this annotation to register Apollo ConfigChangeListener.
*
* <p>Usage example:</p>
* <pre class="code">
* //Listener on namespaces of "someNamespace" and "anotherNamespace"
* @ApolloConfigChangeListener({"someNamespace","anotherNamespace"})
* private void onChange(ConfigChangeEvent changeEvent) {
* //handle change event
* }
* </pre>
*
* @author Jason Song(song_s@ctrip.com)
*/
@Retention
(
RetentionPolicy
.
RUNTIME
)
@Target
(
ElementType
.
METHOD
)
@Documented
public
@interface
ApolloConfigChangeListener
{
/**
* Apollo namespace for the config, if not specified then default to application
*/
String
[]
value
()
default
{
ConfigConsts
.
NAMESPACE_APPLICATION
};
}
apollo-client/src/main/java/com/ctrip/framework/apollo/spring/annotation/ApolloConfigRegistrar.java
0 → 100644
浏览文件 @
ee51eff4
package
com.ctrip.framework.apollo.spring.annotation
;
import
com.google.common.collect.Lists
;
import
com.ctrip.framework.apollo.spring.config.PropertySourcesProcessor
;
import
com.ctrip.framework.apollo.spring.util.BeanRegistrationUtil
;
import
org.springframework.beans.factory.support.BeanDefinitionRegistry
;
import
org.springframework.context.annotation.ImportBeanDefinitionRegistrar
;
import
org.springframework.context.support.PropertySourcesPlaceholderConfigurer
;
import
org.springframework.core.annotation.AnnotationAttributes
;
import
org.springframework.core.type.AnnotationMetadata
;
/**
* @author Jason Song(song_s@ctrip.com)
*/
public
class
ApolloConfigRegistrar
implements
ImportBeanDefinitionRegistrar
{
@Override
public
void
registerBeanDefinitions
(
AnnotationMetadata
importingClassMetadata
,
BeanDefinitionRegistry
registry
)
{
AnnotationAttributes
attributes
=
AnnotationAttributes
.
fromMap
(
importingClassMetadata
.
getAnnotationAttributes
(
EnableApolloConfig
.
class
.
getName
()));
String
[]
namespaces
=
attributes
.
getStringArray
(
"value"
);
int
order
=
attributes
.
getNumber
(
"order"
);
PropertySourcesProcessor
.
addNamespaces
(
Lists
.
newArrayList
(
namespaces
),
order
);
BeanRegistrationUtil
.
registerBeanDefinitionIfNotExists
(
registry
,
PropertySourcesPlaceholderConfigurer
.
class
.
getName
(),
PropertySourcesPlaceholderConfigurer
.
class
);
BeanRegistrationUtil
.
registerBeanDefinitionIfNotExists
(
registry
,
PropertySourcesProcessor
.
class
.
getName
(),
PropertySourcesProcessor
.
class
);
BeanRegistrationUtil
.
registerBeanDefinitionIfNotExists
(
registry
,
ApolloAnnotationProcessor
.
class
.
getName
(),
ApolloAnnotationProcessor
.
class
);
}
}
apollo-client/src/main/java/com/ctrip/framework/apollo/spring/annotation/EnableApolloConfig.java
0 → 100644
浏览文件 @
ee51eff4
package
com.ctrip.framework.apollo.spring.annotation
;
import
com.ctrip.framework.apollo.core.ConfigConsts
;
import
org.springframework.context.annotation.Import
;
import
org.springframework.core.Ordered
;
import
java.lang.annotation.Documented
;
import
java.lang.annotation.ElementType
;
import
java.lang.annotation.Retention
;
import
java.lang.annotation.RetentionPolicy
;
import
java.lang.annotation.Target
;
/**
* Use this annotation to register Apollo property sources when using Java Config.
*
* <p>Configuration example:</p>
* <pre class="code">
* @Configuration
* @EnableApolloConfig({"someNamespace","anotherNamespace"})
* public class AppConfig {
*
* }
* </pre>
*
* @author Jason Song(song_s@ctrip.com)
*/
@Retention
(
RetentionPolicy
.
RUNTIME
)
@Target
(
ElementType
.
TYPE
)
@Documented
@Import
(
ApolloConfigRegistrar
.
class
)
public
@interface
EnableApolloConfig
{
/**
* Apollo namespaces to inject configuration into Spring Property Sources.
*/
String
[]
value
()
default
{
ConfigConsts
.
NAMESPACE_APPLICATION
};
/**
* The order of the apollo config, default is {@link Ordered#LOWEST_PRECEDENCE}, which is Integer.MAX_VALUE.
* If there are properties with the same name in different apollo configs, the apollo config with smaller order wins.
* @return
*/
int
order
()
default
Ordered
.
LOWEST_PRECEDENCE
;
}
apollo-client/src/main/java/com/ctrip/framework/apollo/spring/config/ConfigPropertySource.java
0 → 100644
浏览文件 @
ee51eff4
package
com.ctrip.framework.apollo.spring.config
;
import
com.ctrip.framework.apollo.Config
;
import
org.springframework.core.env.PropertySource
;
/**
* Property source wrapper for Config
*
* @author Jason Song(song_s@ctrip.com)
*/
public
class
ConfigPropertySource
extends
PropertySource
<
Config
>
{
public
ConfigPropertySource
(
String
name
,
Config
source
)
{
super
(
name
,
source
);
}
@Override
public
Object
getProperty
(
String
name
)
{
return
this
.
source
.
getProperty
(
name
,
null
);
}
}
apollo-client/src/main/java/com/ctrip/framework/apollo/spring/config/ConfigPropertySourcesProcessor.java
0 → 100644
浏览文件 @
ee51eff4
package
com.ctrip.framework.apollo.spring.config
;
import
com.ctrip.framework.apollo.spring.annotation.ApolloAnnotationProcessor
;
import
com.ctrip.framework.apollo.spring.util.BeanRegistrationUtil
;
import
org.springframework.beans.BeansException
;
import
org.springframework.beans.factory.support.BeanDefinitionRegistry
;
import
org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor
;
import
org.springframework.context.support.PropertySourcesPlaceholderConfigurer
;
/**
* Apollo Property Sources processor for Spring XML Based Application
*
* @author Jason Song(song_s@ctrip.com)
*/
public
class
ConfigPropertySourcesProcessor
extends
PropertySourcesProcessor
implements
BeanDefinitionRegistryPostProcessor
{
@Override
public
void
postProcessBeanDefinitionRegistry
(
BeanDefinitionRegistry
registry
)
throws
BeansException
{
BeanRegistrationUtil
.
registerBeanDefinitionIfNotExists
(
registry
,
PropertySourcesPlaceholderConfigurer
.
class
.
getName
(),
PropertySourcesPlaceholderConfigurer
.
class
);
BeanRegistrationUtil
.
registerBeanDefinitionIfNotExists
(
registry
,
ApolloAnnotationProcessor
.
class
.
getName
(),
ApolloAnnotationProcessor
.
class
);
}
}
apollo-client/src/main/java/com/ctrip/framework/apollo/spring/config/NamespaceHandler.java
0 → 100644
浏览文件 @
ee51eff4
package
com.ctrip.framework.apollo.spring.config
;
import
com.google.common.base.Splitter
;
import
com.google.common.base.Strings
;
import
com.ctrip.framework.apollo.core.ConfigConsts
;
import
org.springframework.beans.factory.support.BeanDefinitionBuilder
;
import
org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser
;
import
org.springframework.beans.factory.xml.NamespaceHandlerSupport
;
import
org.springframework.core.Ordered
;
import
org.w3c.dom.Element
;
/**
* @author Jason Song(song_s@ctrip.com)
*/
public
class
NamespaceHandler
extends
NamespaceHandlerSupport
{
private
static
final
Splitter
NAMESPACE_SPLITTER
=
Splitter
.
on
(
","
).
omitEmptyStrings
().
trimResults
();
@Override
public
void
init
()
{
registerBeanDefinitionParser
(
"config"
,
new
BeanParser
());
}
static
class
BeanParser
extends
AbstractSingleBeanDefinitionParser
{
@Override
protected
Class
<?>
getBeanClass
(
Element
element
)
{
return
ConfigPropertySourcesProcessor
.
class
;
}
@Override
protected
boolean
shouldGenerateId
()
{
return
true
;
}
@Override
protected
void
doParse
(
Element
element
,
BeanDefinitionBuilder
builder
)
{
String
namespaces
=
element
.
getAttribute
(
"namespaces"
);
//default to application
if
(
Strings
.
isNullOrEmpty
(
namespaces
))
{
namespaces
=
ConfigConsts
.
NAMESPACE_APPLICATION
;
}
int
order
=
Ordered
.
LOWEST_PRECEDENCE
;
String
orderAttribute
=
element
.
getAttribute
(
"order"
);
if
(!
Strings
.
isNullOrEmpty
(
orderAttribute
))
{
try
{
order
=
Integer
.
parseInt
(
orderAttribute
);
}
catch
(
Throwable
ex
)
{
throw
new
IllegalArgumentException
(
String
.
format
(
"Invalid order: %s for namespaces: %s"
,
orderAttribute
,
namespaces
));
}
}
PropertySourcesProcessor
.
addNamespaces
(
NAMESPACE_SPLITTER
.
splitToList
(
namespaces
),
order
);
}
}
}
apollo-client/src/main/java/com/ctrip/framework/apollo/spring/config/PropertySourcesProcessor.java
0 → 100644
浏览文件 @
ee51eff4
package
com.ctrip.framework.apollo.spring.config
;
import
com.google.common.collect.HashMultimap
;
import
com.google.common.collect.ImmutableSortedSet
;
import
com.google.common.collect.Multimap
;
import
com.ctrip.framework.apollo.Config
;
import
com.ctrip.framework.apollo.ConfigService
;
import
org.springframework.beans.BeansException
;
import
org.springframework.beans.factory.config.BeanFactoryPostProcessor
;
import
org.springframework.beans.factory.config.ConfigurableListableBeanFactory
;
import
org.springframework.context.EnvironmentAware
;
import
org.springframework.core.env.CompositePropertySource
;
import
org.springframework.core.env.ConfigurableEnvironment
;
import
org.springframework.core.env.Environment
;
import
java.util.Collection
;
import
java.util.Iterator
;
import
java.util.concurrent.atomic.AtomicBoolean
;
/**
* Apollo Property Sources processor for Spring Annotation Based Application
*
* @author Jason Song(song_s@ctrip.com)
*/
public
class
PropertySourcesProcessor
implements
BeanFactoryPostProcessor
,
EnvironmentAware
{
private
static
final
String
APOLLO_PROPERTY_SOURCE_NAME
=
"ApolloPropertySources"
;
private
static
final
Multimap
<
Integer
,
String
>
NAMESPACE_NAMES
=
HashMultimap
.
create
();
private
static
final
AtomicBoolean
PROPERTY_SOURCES_INITIALIZED
=
new
AtomicBoolean
(
false
);
private
ConfigurableEnvironment
environment
;
public
static
boolean
addNamespaces
(
Collection
<
String
>
namespaces
,
int
order
)
{
return
NAMESPACE_NAMES
.
putAll
(
order
,
namespaces
);
}
@Override
public
void
postProcessBeanFactory
(
ConfigurableListableBeanFactory
beanFactory
)
throws
BeansException
{
if
(!
PROPERTY_SOURCES_INITIALIZED
.
compareAndSet
(
false
,
true
))
{
//already initialized
return
;
}
initializePropertySources
();
}
protected
void
initializePropertySources
()
{
CompositePropertySource
composite
=
new
CompositePropertySource
(
APOLLO_PROPERTY_SOURCE_NAME
);
//sort by order asc
ImmutableSortedSet
<
Integer
>
orders
=
ImmutableSortedSet
.
copyOf
(
NAMESPACE_NAMES
.
keySet
());
Iterator
<
Integer
>
iterator
=
orders
.
iterator
();
while
(
iterator
.
hasNext
())
{
int
order
=
iterator
.
next
();
for
(
String
namespace
:
NAMESPACE_NAMES
.
get
(
order
))
{
Config
config
=
ConfigService
.
getConfig
(
namespace
);
composite
.
addPropertySource
(
new
ConfigPropertySource
(
namespace
,
config
));
}
}
environment
.
getPropertySources
().
addFirst
(
composite
);
}
@Override
public
void
setEnvironment
(
Environment
environment
)
{
//it is safe enough to cast as all known environment is derived from ConfigurableEnvironment
this
.
environment
=
(
ConfigurableEnvironment
)
environment
;
}
//only for test
private
static
void
reset
()
{
NAMESPACE_NAMES
.
clear
();
PROPERTY_SOURCES_INITIALIZED
.
set
(
false
);
}
}
apollo-client/src/main/java/com/ctrip/framework/apollo/spring/package-info.java
0 → 100644
浏览文件 @
ee51eff4
/**
* This package contains Apollo Spring integration codes and enables the following features:<br/>
* <p>1. Support Spring XML based configuration</p>
* <ul>
* <li><apollo:config namespaces="someNamespace"/> to inject configurations from Apollo into Spring Property
* Sources so that placeholders like ${someProperty} and @Value("someProperty") are supported.</li>
* </ul>
* <p>2. Support Spring Java based configuration</p>
* <ul>
* <li>@EnableApolloConfig(namespaces={"someNamespace"}) to inject configurations from Apollo into Spring Property
* Sources so that placeholders like ${someProperty} and @Value("someProperty") are supported.</li>
* </ul>
*
* With the above configuration, annotations like @ApolloConfig("someNamespace")
* and @ApolloConfigChangeListener("someNamespace) are also supported.<br />
* <br />
* Requires Spring 3.1.1+
*/
package
com.ctrip.framework.apollo.spring
;
\ No newline at end of file
apollo-client/src/main/java/com/ctrip/framework/apollo/spring/util/BeanRegistrationUtil.java
0 → 100644
浏览文件 @
ee51eff4
package
com.ctrip.framework.apollo.spring.util
;
import
org.springframework.beans.factory.config.BeanDefinition
;
import
org.springframework.beans.factory.support.BeanDefinitionBuilder
;
import
org.springframework.beans.factory.support.BeanDefinitionRegistry
;
import
java.util.Objects
;
/**
* @author Jason Song(song_s@ctrip.com)
*/
public
class
BeanRegistrationUtil
{
public
static
boolean
registerBeanDefinitionIfNotExists
(
BeanDefinitionRegistry
registry
,
String
beanName
,
Class
<?>
beanClass
)
{
if
(
registry
.
containsBeanDefinition
(
beanName
))
{
return
false
;
}
String
[]
candidates
=
registry
.
getBeanDefinitionNames
();
for
(
String
candidate
:
candidates
)
{
BeanDefinition
beanDefinition
=
registry
.
getBeanDefinition
(
candidate
);
if
(
Objects
.
equals
(
beanDefinition
.
getBeanClassName
(),
beanClass
.
getName
()))
{
return
false
;
}
}
BeanDefinition
annotationProcessor
=
BeanDefinitionBuilder
.
genericBeanDefinition
(
beanClass
).
getBeanDefinition
();
registry
.
registerBeanDefinition
(
beanName
,
annotationProcessor
);
return
true
;
}
}
apollo-client/src/main/resources/META-INF/apollo-1.0.0.xsd
0 → 100644
浏览文件 @
ee51eff4
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<xsd:schema
xmlns=
"http://www.ctrip.com/schema/apollo"
xmlns:xsd=
"http://www.w3.org/2001/XMLSchema"
targetNamespace=
"http://www.ctrip.com/schema/apollo"
elementFormDefault=
"qualified"
attributeFormDefault=
"unqualified"
>
<xsd:annotation>
<xsd:documentation>
<![CDATA[ Namespace support for Ctrip Apollo Configuration Center. ]]>
</xsd:documentation>
</xsd:annotation>
<xsd:element
name=
"config"
>
<xsd:annotation>
<xsd:documentation>
<![CDATA[ Apollo configuration section to integrate with Spring.]]>
</xsd:documentation>
</xsd:annotation>
<xsd:complexType>
<xsd:attribute
name=
"namespaces"
type=
"xsd:string"
use=
"optional"
>
<xsd:annotation>
<xsd:documentation>
<![CDATA[
The comma-separated list of namespace names to integrate with Spring property sources.
If not specified, then default to application namespace.
]]>
</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute
name=
"order"
type=
"xsd:int"
use=
"optional"
>
<xsd:annotation>
<xsd:documentation>
<![CDATA[
The order of the config, default to Ordered.LOWEST_PRECEDENCE, which is Integer.MAX_VALUE.
If there are properties with the same name in different apollo configs, the config with smaller order wins.
]]>
</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:complexType>
</xsd:element>
</xsd:schema>
\ No newline at end of file
apollo-client/src/main/resources/META-INF/spring.handlers
0 → 100644
浏览文件 @
ee51eff4
http\://www.ctrip.com/schema/apollo=com.ctrip.framework.apollo.spring.config.NamespaceHandler
\ No newline at end of file
apollo-client/src/main/resources/META-INF/spring.schemas
0 → 100644
浏览文件 @
ee51eff4
http\://www.ctrip.com/schema/apollo-1.0.0.xsd=/META-INF/apollo-1.0.0.xsd
http\://www.ctrip.com/schema/apollo.xsd=/META-INF/apollo-1.0.0.xsd
apollo-client/src/test/java/com/ctrip/framework/apollo/AllTests.java
浏览文件 @
ee51eff4
...
...
@@ -14,6 +14,10 @@ import com.ctrip.framework.apollo.internals.XmlConfigFileTest;
import
com.ctrip.framework.apollo.spi.DefaultConfigFactoryManagerTest
;
import
com.ctrip.framework.apollo.spi.DefaultConfigFactoryTest
;
import
com.ctrip.framework.apollo.spi.DefaultConfigRegistryTest
;
import
com.ctrip.framework.apollo.spring.JavaConfigAnnotationTest
;
import
com.ctrip.framework.apollo.spring.JavaConfigPlaceholderTest
;
import
com.ctrip.framework.apollo.spring.XMLConfigAnnotationTest
;
import
com.ctrip.framework.apollo.spring.XmlConfigPlaceholderTest
;
import
com.ctrip.framework.apollo.util.ExceptionUtilTest
;
import
com.ctrip.framework.apollo.util.parser.DateParserTest
;
import
com.ctrip.framework.apollo.util.parser.DurationParserTest
;
...
...
@@ -27,9 +31,10 @@ import org.junit.runners.Suite.SuiteClasses;
ConfigServiceTest
.
class
,
DefaultConfigRegistryTest
.
class
,
DefaultConfigFactoryManagerTest
.
class
,
DefaultConfigManagerTest
.
class
,
DefaultConfigTest
.
class
,
LocalFileConfigRepositoryTest
.
class
,
RemoteConfigRepositoryTest
.
class
,
SimpleConfigTest
.
class
,
DefaultConfigFactoryTest
.
class
,
ConfigIntegrationTest
.
class
,
ExceptionUtilTest
.
class
,
XmlConfigFileTest
.
class
,
PropertiesConfigFileTest
.
class
,
RemoteConfigLongPollServiceTest
.
class
,
DateParserTest
.
class
,
DurationParserTest
.
class
,
JsonConfigFileTest
.
class
ConfigIntegrationTest
.
class
,
ExceptionUtilTest
.
class
,
XmlConfigFileTest
.
class
,
PropertiesConfigFileTest
.
class
,
RemoteConfigLongPollServiceTest
.
class
,
DateParserTest
.
class
,
DurationParserTest
.
class
,
JsonConfigFileTest
.
class
,
XmlConfigPlaceholderTest
.
class
,
JavaConfigPlaceholderTest
.
class
,
XMLConfigAnnotationTest
.
class
,
JavaConfigAnnotationTest
.
class
})
public
class
AllTests
{
...
...
apollo-client/src/test/java/com/ctrip/framework/apollo/internals/DefaultConfigManagerTest.java
浏览文件 @
ee51eff4
...
...
@@ -28,7 +28,7 @@ public class DefaultConfigManagerTest extends ComponentTestCase {
public
void
setUp
()
throws
Exception
{
super
.
tearDown
();
//clear the container
super
.
setUp
();
defineComponent
(
ConfigFactoryManager
.
class
,
MockConfigManager
.
class
);
defineComponent
(
ConfigFactoryManager
.
class
,
MockConfig
Factory
Manager
.
class
);
defaultConfigManager
=
(
DefaultConfigManager
)
lookup
(
ConfigManager
.
class
);
someConfigContent
=
"someContent"
;
}
...
...
@@ -84,7 +84,7 @@ public class DefaultConfigManagerTest extends ComponentTestCase {
}
public
static
class
MockConfigManager
implements
ConfigFactoryManager
{
public
static
class
MockConfig
Factory
Manager
implements
ConfigFactoryManager
{
@Override
public
ConfigFactory
getFactory
(
String
namespace
)
{
...
...
apollo-client/src/test/java/com/ctrip/framework/apollo/internals/RemoteConfigLongPollServiceTest.java
浏览文件 @
ee51eff4
...
...
@@ -225,7 +225,7 @@ public class RemoteConfigLongPollServiceTest extends ComponentTestCase {
remoteConfigLongPollService
.
submit
(
anotherNamespace
,
anotherRepository
);
submitAnotherNamespaceFinish
.
set
(
true
);
onAnotherRepositoryNotified
.
get
(
500
,
TimeUnit
.
MILLISECONDS
);
onAnotherRepositoryNotified
.
get
(
500
0
,
TimeUnit
.
MILLISECONDS
);
remoteConfigLongPollService
.
stopLongPollingRefresh
();
...
...
apollo-client/src/test/java/com/ctrip/framework/apollo/spring/AbstractSpringIntegrationTest.java
0 → 100644
浏览文件 @
ee51eff4
package
com.ctrip.framework.apollo.spring
;
import
com.google.common.collect.Maps
;
import
com.ctrip.framework.apollo.Config
;
import
com.ctrip.framework.apollo.ConfigFile
;
import
com.ctrip.framework.apollo.ConfigService
;
import
com.ctrip.framework.apollo.core.enums.ConfigFileFormat
;
import
com.ctrip.framework.apollo.internals.ConfigManager
;
import
com.ctrip.framework.apollo.spring.config.PropertySourcesProcessor
;
import
org.codehaus.plexus.PlexusContainer
;
import
org.junit.After
;
import
org.junit.Before
;
import
org.springframework.util.ReflectionUtils
;
import
org.unidal.lookup.ComponentTestCase
;
import
java.lang.reflect.Method
;
import
java.util.Map
;
/**
* @author Jason Song(song_s@ctrip.com)
*/
public
abstract
class
AbstractSpringIntegrationTest
extends
ComponentTestCase
{
private
static
final
Map
<
String
,
Config
>
CONFIG_REGISTRY
=
Maps
.
newHashMap
();
private
static
Method
PROPERTY_SOURCES_PROCESSOR_CLEAR
;
private
static
Method
CONFIG_SERVICE_SET_CONTAINER
;
static
{
try
{
PROPERTY_SOURCES_PROCESSOR_CLEAR
=
PropertySourcesProcessor
.
class
.
getDeclaredMethod
(
"reset"
);
ReflectionUtils
.
makeAccessible
(
PROPERTY_SOURCES_PROCESSOR_CLEAR
);
CONFIG_SERVICE_SET_CONTAINER
=
ConfigService
.
class
.
getDeclaredMethod
(
"setContainer"
,
PlexusContainer
.
class
);
ReflectionUtils
.
makeAccessible
(
CONFIG_SERVICE_SET_CONTAINER
);
}
catch
(
NoSuchMethodException
e
)
{
e
.
printStackTrace
();
}
}
@Override
@Before
public
void
setUp
()
throws
Exception
{
super
.
tearDown
();
//clear the container
super
.
setUp
();
//as PropertySourcesProcessor has some static states, so we must manually clear its state
ReflectionUtils
.
invokeMethod
(
PROPERTY_SOURCES_PROCESSOR_CLEAR
,
null
);
//as ConfigService is singleton, so we must manually clear its container
ReflectionUtils
.
invokeMethod
(
CONFIG_SERVICE_SET_CONTAINER
,
null
,
getContainer
());
defineComponent
(
ConfigManager
.
class
,
MockConfigManager
.
class
);
}
@Override
@After
public
void
tearDown
()
throws
Exception
{
super
.
tearDown
();
CONFIG_REGISTRY
.
clear
();
}
protected
void
mockConfig
(
String
namespace
,
Config
config
)
{
CONFIG_REGISTRY
.
put
(
namespace
,
config
);
}
public
static
class
MockConfigManager
implements
ConfigManager
{
@Override
public
Config
getConfig
(
String
namespace
)
{
return
CONFIG_REGISTRY
.
get
(
namespace
);
}
@Override
public
ConfigFile
getConfigFile
(
String
namespace
,
ConfigFileFormat
configFileFormat
)
{
return
null
;
}
}
}
apollo-client/src/test/java/com/ctrip/framework/apollo/spring/JavaConfigAnnotationTest.java
0 → 100644
浏览文件 @
ee51eff4
package
com.ctrip.framework.apollo.spring
;
import
com.google.common.collect.Lists
;
import
com.ctrip.framework.apollo.Config
;
import
com.ctrip.framework.apollo.ConfigChangeListener
;
import
com.ctrip.framework.apollo.core.ConfigConsts
;
import
com.ctrip.framework.apollo.model.ConfigChangeEvent
;
import
com.ctrip.framework.apollo.spring.annotation.ApolloConfig
;
import
com.ctrip.framework.apollo.spring.annotation.ApolloConfigChangeListener
;
import
com.ctrip.framework.apollo.spring.annotation.EnableApolloConfig
;
import
org.junit.Test
;
import
org.mockito.invocation.InvocationOnMock
;
import
org.mockito.stubbing.Answer
;
import
org.springframework.beans.factory.BeanCreationException
;
import
org.springframework.context.annotation.AnnotationConfigApplicationContext
;
import
org.springframework.context.annotation.Bean
;
import
org.springframework.context.annotation.Configuration
;
import
java.util.List
;
import
static
org
.
junit
.
Assert
.
assertEquals
;
import
static
org
.
mockito
.
Matchers
.
any
;
import
static
org
.
mockito
.
Mockito
.
doAnswer
;
import
static
org
.
mockito
.
Mockito
.
mock
;
/**
* @author Jason Song(song_s@ctrip.com)
*/
public
class
JavaConfigAnnotationTest
extends
AbstractSpringIntegrationTest
{
private
static
final
String
FX_APOLLO_NAMESPACE
=
"FX.apollo"
;
@Test
public
void
testApolloConfig
()
throws
Exception
{
Config
applicationConfig
=
mock
(
Config
.
class
);
Config
fxApolloConfig
=
mock
(
Config
.
class
);
mockConfig
(
ConfigConsts
.
NAMESPACE_APPLICATION
,
applicationConfig
);
mockConfig
(
FX_APOLLO_NAMESPACE
,
fxApolloConfig
);
TestApolloConfigBean1
bean
=
getBean
(
TestApolloConfigBean1
.
class
,
AppConfig1
.
class
);
assertEquals
(
applicationConfig
,
bean
.
getConfig
());
assertEquals
(
applicationConfig
,
bean
.
getAnotherConfig
());
assertEquals
(
fxApolloConfig
,
bean
.
getYetAnotherConfig
());
}
@Test
(
expected
=
BeanCreationException
.
class
)
public
void
testApolloConfigWithWrongFieldType
()
throws
Exception
{
Config
applicationConfig
=
mock
(
Config
.
class
);
mockConfig
(
ConfigConsts
.
NAMESPACE_APPLICATION
,
applicationConfig
);
getBean
(
TestApolloConfigBean2
.
class
,
AppConfig2
.
class
);
}
@Test
public
void
testApolloConfigChangeListener
()
throws
Exception
{
Config
applicationConfig
=
mock
(
Config
.
class
);
Config
fxApolloConfig
=
mock
(
Config
.
class
);
mockConfig
(
ConfigConsts
.
NAMESPACE_APPLICATION
,
applicationConfig
);
mockConfig
(
FX_APOLLO_NAMESPACE
,
fxApolloConfig
);
final
List
<
ConfigChangeListener
>
applicationListeners
=
Lists
.
newArrayList
();
final
List
<
ConfigChangeListener
>
fxApolloListeners
=
Lists
.
newArrayList
();
doAnswer
(
new
Answer
()
{
@Override
public
Object
answer
(
InvocationOnMock
invocation
)
throws
Throwable
{
applicationListeners
.
add
(
invocation
.
getArgumentAt
(
0
,
ConfigChangeListener
.
class
));
return
Void
.
class
;
}
}).
when
(
applicationConfig
).
addChangeListener
(
any
(
ConfigChangeListener
.
class
));
doAnswer
(
new
Answer
()
{
@Override
public
Object
answer
(
InvocationOnMock
invocation
)
throws
Throwable
{
fxApolloListeners
.
add
(
invocation
.
getArgumentAt
(
0
,
ConfigChangeListener
.
class
));
return
Void
.
class
;
}
}).
when
(
fxApolloConfig
).
addChangeListener
(
any
(
ConfigChangeListener
.
class
));
ConfigChangeEvent
someEvent
=
mock
(
ConfigChangeEvent
.
class
);
ConfigChangeEvent
anotherEvent
=
mock
(
ConfigChangeEvent
.
class
);
TestApolloConfigChangeListenerBean1
bean
=
getBean
(
TestApolloConfigChangeListenerBean1
.
class
,
AppConfig3
.
class
);
assertEquals
(
3
,
applicationListeners
.
size
());
assertEquals
(
1
,
fxApolloListeners
.
size
());
for
(
ConfigChangeListener
listener
:
applicationListeners
)
{
listener
.
onChange
(
someEvent
);
}
assertEquals
(
someEvent
,
bean
.
getChangeEvent1
());
assertEquals
(
someEvent
,
bean
.
getChangeEvent2
());
assertEquals
(
someEvent
,
bean
.
getChangeEvent3
());
for
(
ConfigChangeListener
listener
:
fxApolloListeners
)
{
listener
.
onChange
(
anotherEvent
);
}
assertEquals
(
someEvent
,
bean
.
getChangeEvent1
());
assertEquals
(
someEvent
,
bean
.
getChangeEvent2
());
assertEquals
(
anotherEvent
,
bean
.
getChangeEvent3
());
}
@Test
(
expected
=
BeanCreationException
.
class
)
public
void
testApolloConfigChangeListenerWithWrongParamType
()
throws
Exception
{
Config
applicationConfig
=
mock
(
Config
.
class
);
mockConfig
(
ConfigConsts
.
NAMESPACE_APPLICATION
,
applicationConfig
);
getBean
(
TestApolloConfigChangeListenerBean2
.
class
,
AppConfig4
.
class
);
}
@Test
(
expected
=
BeanCreationException
.
class
)
public
void
testApolloConfigChangeListenerWithWrongParamCount
()
throws
Exception
{
Config
applicationConfig
=
mock
(
Config
.
class
);
mockConfig
(
ConfigConsts
.
NAMESPACE_APPLICATION
,
applicationConfig
);
getBean
(
TestApolloConfigChangeListenerBean3
.
class
,
AppConfig5
.
class
);
}
private
<
T
>
T
getBean
(
Class
<
T
>
beanClass
,
Class
<?>...
annotatedClasses
)
{
AnnotationConfigApplicationContext
context
=
new
AnnotationConfigApplicationContext
(
annotatedClasses
);
return
context
.
getBean
(
beanClass
);
}
@Configuration
@EnableApolloConfig
static
class
AppConfig1
{
@Bean
public
TestApolloConfigBean1
bean
()
{
return
new
TestApolloConfigBean1
();
}
}
@Configuration
@EnableApolloConfig
static
class
AppConfig2
{
@Bean
public
TestApolloConfigBean2
bean
()
{
return
new
TestApolloConfigBean2
();
}
}
@Configuration
@EnableApolloConfig
static
class
AppConfig3
{
@Bean
public
TestApolloConfigChangeListenerBean1
bean
()
{
return
new
TestApolloConfigChangeListenerBean1
();
}
}
@Configuration
@EnableApolloConfig
static
class
AppConfig4
{
@Bean
public
TestApolloConfigChangeListenerBean2
bean
()
{
return
new
TestApolloConfigChangeListenerBean2
();
}
}
@Configuration
@EnableApolloConfig
static
class
AppConfig5
{
@Bean
public
TestApolloConfigChangeListenerBean3
bean
()
{
return
new
TestApolloConfigChangeListenerBean3
();
}
}
static
class
TestApolloConfigBean1
{
@ApolloConfig
private
Config
config
;
@ApolloConfig
(
ConfigConsts
.
NAMESPACE_APPLICATION
)
private
Config
anotherConfig
;
@ApolloConfig
(
FX_APOLLO_NAMESPACE
)
private
Config
yetAnotherConfig
;
public
Config
getConfig
()
{
return
config
;
}
public
Config
getAnotherConfig
()
{
return
anotherConfig
;
}
public
Config
getYetAnotherConfig
()
{
return
yetAnotherConfig
;
}
}
public
static
class
TestApolloConfigBean2
{
@ApolloConfig
private
String
config
;
}
static
class
TestApolloConfigChangeListenerBean1
{
private
ConfigChangeEvent
changeEvent1
;
private
ConfigChangeEvent
changeEvent2
;
private
ConfigChangeEvent
changeEvent3
;
@ApolloConfigChangeListener
private
void
onChange1
(
ConfigChangeEvent
changeEvent
)
{
this
.
changeEvent1
=
changeEvent
;
}
@ApolloConfigChangeListener
(
ConfigConsts
.
NAMESPACE_APPLICATION
)
private
void
onChange2
(
ConfigChangeEvent
changeEvent
)
{
this
.
changeEvent2
=
changeEvent
;
}
@ApolloConfigChangeListener
({
ConfigConsts
.
NAMESPACE_APPLICATION
,
FX_APOLLO_NAMESPACE
})
private
void
onChange3
(
ConfigChangeEvent
changeEvent
)
{
this
.
changeEvent3
=
changeEvent
;
}
public
ConfigChangeEvent
getChangeEvent1
()
{
return
changeEvent1
;
}
public
ConfigChangeEvent
getChangeEvent2
()
{
return
changeEvent2
;
}
public
ConfigChangeEvent
getChangeEvent3
()
{
return
changeEvent3
;
}
}
static
class
TestApolloConfigChangeListenerBean2
{
@ApolloConfigChangeListener
private
void
onChange
(
String
event
)
{
}
}
static
class
TestApolloConfigChangeListenerBean3
{
@ApolloConfigChangeListener
private
void
onChange
(
ConfigChangeEvent
event
,
String
someParam
)
{
}
}
}
apollo-client/src/test/java/com/ctrip/framework/apollo/spring/JavaConfigPlaceholderTest.java
0 → 100644
浏览文件 @
ee51eff4
package
com.ctrip.framework.apollo.spring
;
import
com.ctrip.framework.apollo.Config
;
import
com.ctrip.framework.apollo.core.ConfigConsts
;
import
com.ctrip.framework.apollo.spring.annotation.EnableApolloConfig
;
import
org.junit.Test
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.context.annotation.AnnotationConfigApplicationContext
;
import
org.springframework.context.annotation.Bean
;
import
org.springframework.context.annotation.Configuration
;
import
org.springframework.stereotype.Component
;
import
static
org
.
junit
.
Assert
.
assertEquals
;
import
static
org
.
mockito
.
Matchers
.
anyString
;
import
static
org
.
mockito
.
Matchers
.
eq
;
import
static
org
.
mockito
.
Mockito
.
mock
;
import
static
org
.
mockito
.
Mockito
.
when
;
/**
* @author Jason Song(song_s@ctrip.com)
*/
public
class
JavaConfigPlaceholderTest
extends
AbstractSpringIntegrationTest
{
private
static
final
String
TIMEOUT_PROPERTY
=
"timeout"
;
private
static
final
int
DEFAULT_TIMEOUT
=
100
;
private
static
final
String
BATCH_PROPERTY
=
"batch"
;
private
static
final
int
DEFAULT_BATCH
=
200
;
private
static
final
String
FX_APOLLO_NAMESPACE
=
"FX.apollo"
;
@Test
public
void
testPropertySourceWithNoNamespace
()
throws
Exception
{
int
someTimeout
=
1000
;
int
someBatch
=
2000
;
Config
config
=
mock
(
Config
.
class
);
when
(
config
.
getProperty
(
eq
(
TIMEOUT_PROPERTY
),
anyString
())).
thenReturn
(
String
.
valueOf
(
someTimeout
));
when
(
config
.
getProperty
(
eq
(
BATCH_PROPERTY
),
anyString
())).
thenReturn
(
String
.
valueOf
(
someBatch
));
mockConfig
(
ConfigConsts
.
NAMESPACE_APPLICATION
,
config
);
check
(
someTimeout
,
someBatch
,
AppConfig1
.
class
);
}
@Test
public
void
testPropertySourceWithNoConfig
()
throws
Exception
{
Config
config
=
mock
(
Config
.
class
);
mockConfig
(
ConfigConsts
.
NAMESPACE_APPLICATION
,
config
);
check
(
DEFAULT_TIMEOUT
,
DEFAULT_BATCH
,
AppConfig1
.
class
);
}
@Test
public
void
testApplicationPropertySource
()
throws
Exception
{
int
someTimeout
=
1000
;
int
someBatch
=
2000
;
Config
config
=
mock
(
Config
.
class
);
when
(
config
.
getProperty
(
eq
(
TIMEOUT_PROPERTY
),
anyString
())).
thenReturn
(
String
.
valueOf
(
someTimeout
));
when
(
config
.
getProperty
(
eq
(
BATCH_PROPERTY
),
anyString
())).
thenReturn
(
String
.
valueOf
(
someBatch
));
mockConfig
(
ConfigConsts
.
NAMESPACE_APPLICATION
,
config
);
check
(
someTimeout
,
someBatch
,
AppConfig2
.
class
);
}
@Test
public
void
testMultiplePropertySources
()
throws
Exception
{
int
someTimeout
=
1000
;
int
someBatch
=
2000
;
Config
application
=
mock
(
Config
.
class
);
when
(
application
.
getProperty
(
eq
(
TIMEOUT_PROPERTY
),
anyString
())).
thenReturn
(
String
.
valueOf
(
someTimeout
));
mockConfig
(
ConfigConsts
.
NAMESPACE_APPLICATION
,
application
);
Config
fxApollo
=
mock
(
Config
.
class
);
when
(
application
.
getProperty
(
eq
(
BATCH_PROPERTY
),
anyString
())).
thenReturn
(
String
.
valueOf
(
someBatch
));
mockConfig
(
FX_APOLLO_NAMESPACE
,
fxApollo
);
check
(
someTimeout
,
someBatch
,
AppConfig3
.
class
);
}
@Test
public
void
testMultiplePropertySourcesWithSameProperties
()
throws
Exception
{
int
someTimeout
=
1000
;
int
anotherTimeout
=
someTimeout
+
1
;
int
someBatch
=
2000
;
Config
application
=
mock
(
Config
.
class
);
when
(
application
.
getProperty
(
eq
(
TIMEOUT_PROPERTY
),
anyString
())).
thenReturn
(
String
.
valueOf
(
someTimeout
));
when
(
application
.
getProperty
(
eq
(
BATCH_PROPERTY
),
anyString
())).
thenReturn
(
String
.
valueOf
(
someBatch
));
mockConfig
(
ConfigConsts
.
NAMESPACE_APPLICATION
,
application
);
Config
fxApollo
=
mock
(
Config
.
class
);
when
(
fxApollo
.
getProperty
(
eq
(
TIMEOUT_PROPERTY
),
anyString
())).
thenReturn
(
String
.
valueOf
(
anotherTimeout
));
mockConfig
(
FX_APOLLO_NAMESPACE
,
fxApollo
);
check
(
someTimeout
,
someBatch
,
AppConfig3
.
class
);
}
@Test
public
void
testMultiplePropertySourcesWithSamePropertiesWithWeight
()
throws
Exception
{
int
someTimeout
=
1000
;
int
anotherTimeout
=
someTimeout
+
1
;
int
someBatch
=
2000
;
Config
application
=
mock
(
Config
.
class
);
when
(
application
.
getProperty
(
eq
(
TIMEOUT_PROPERTY
),
anyString
())).
thenReturn
(
String
.
valueOf
(
someTimeout
));
when
(
application
.
getProperty
(
eq
(
BATCH_PROPERTY
),
anyString
())).
thenReturn
(
String
.
valueOf
(
someBatch
));
mockConfig
(
ConfigConsts
.
NAMESPACE_APPLICATION
,
application
);
Config
fxApollo
=
mock
(
Config
.
class
);
when
(
fxApollo
.
getProperty
(
eq
(
TIMEOUT_PROPERTY
),
anyString
())).
thenReturn
(
String
.
valueOf
(
anotherTimeout
));
mockConfig
(
FX_APOLLO_NAMESPACE
,
fxApollo
);
check
(
anotherTimeout
,
someBatch
,
AppConfig2
.
class
,
AppConfig4
.
class
);
}
@Test
public
void
testApplicationPropertySourceWithValueInjectedAsParameter
()
throws
Exception
{
int
someTimeout
=
1000
;
int
someBatch
=
2000
;
Config
config
=
mock
(
Config
.
class
);
when
(
config
.
getProperty
(
eq
(
TIMEOUT_PROPERTY
),
anyString
())).
thenReturn
(
String
.
valueOf
(
someTimeout
));
when
(
config
.
getProperty
(
eq
(
BATCH_PROPERTY
),
anyString
())).
thenReturn
(
String
.
valueOf
(
someBatch
));
mockConfig
(
ConfigConsts
.
NAMESPACE_APPLICATION
,
config
);
AnnotationConfigApplicationContext
context
=
new
AnnotationConfigApplicationContext
(
AppConfig5
.
class
);
TestJavaConfigBean2
bean
=
context
.
getBean
(
TestJavaConfigBean2
.
class
);
assertEquals
(
someTimeout
,
bean
.
getTimeout
());
assertEquals
(
someBatch
,
bean
.
getBatch
());
}
private
void
check
(
int
expectedTimeout
,
int
expectedBatch
,
Class
<?>...
annotatedClasses
)
{
AnnotationConfigApplicationContext
context
=
new
AnnotationConfigApplicationContext
(
annotatedClasses
);
TestJavaConfigBean
bean
=
context
.
getBean
(
TestJavaConfigBean
.
class
);
assertEquals
(
expectedTimeout
,
bean
.
getTimeout
());
assertEquals
(
expectedBatch
,
bean
.
getBatch
());
}
@Configuration
@EnableApolloConfig
static
class
AppConfig1
{
@Bean
TestJavaConfigBean
testJavaConfigBean
()
{
return
new
TestJavaConfigBean
();
}
}
@Configuration
@EnableApolloConfig
(
"application"
)
static
class
AppConfig2
{
@Bean
TestJavaConfigBean
testJavaConfigBean
()
{
return
new
TestJavaConfigBean
();
}
}
@Configuration
@EnableApolloConfig
({
"application"
,
"FX.apollo"
})
static
class
AppConfig3
{
@Bean
TestJavaConfigBean
testJavaConfigBean
()
{
return
new
TestJavaConfigBean
();
}
}
@Configuration
@EnableApolloConfig
(
value
=
"FX.apollo"
,
order
=
10
)
static
class
AppConfig4
{
}
@Configuration
@EnableApolloConfig
static
class
AppConfig5
{
@Bean
TestJavaConfigBean2
testJavaConfigBean2
(
@Value
(
"${timeout:100}"
)
int
timeout
,
@Value
(
"${batch:200}"
)
int
batch
)
{
TestJavaConfigBean2
bean
=
new
TestJavaConfigBean2
();
bean
.
setTimeout
(
timeout
);
bean
.
setBatch
(
batch
);
return
bean
;
}
}
@Component
static
class
TestJavaConfigBean
{
@Value
(
"${timeout:100}"
)
private
int
timeout
;
private
int
batch
;
@Value
(
"${batch:200}"
)
public
void
setBatch
(
int
batch
)
{
this
.
batch
=
batch
;
}
public
int
getTimeout
()
{
return
timeout
;
}
public
int
getBatch
()
{
return
batch
;
}
}
static
class
TestJavaConfigBean2
{
private
int
timeout
;
private
int
batch
;
public
int
getTimeout
()
{
return
timeout
;
}
public
void
setTimeout
(
int
timeout
)
{
this
.
timeout
=
timeout
;
}
public
int
getBatch
()
{
return
batch
;
}
public
void
setBatch
(
int
batch
)
{
this
.
batch
=
batch
;
}
}
}
apollo-client/src/test/java/com/ctrip/framework/apollo/spring/XMLConfigAnnotationTest.java
0 → 100644
浏览文件 @
ee51eff4
package
com.ctrip.framework.apollo.spring
;
import
com.google.common.collect.Lists
;
import
com.ctrip.framework.apollo.Config
;
import
com.ctrip.framework.apollo.ConfigChangeListener
;
import
com.ctrip.framework.apollo.core.ConfigConsts
;
import
com.ctrip.framework.apollo.model.ConfigChangeEvent
;
import
com.ctrip.framework.apollo.spring.annotation.ApolloConfig
;
import
com.ctrip.framework.apollo.spring.annotation.ApolloConfigChangeListener
;
import
org.junit.Test
;
import
org.mockito.invocation.InvocationOnMock
;
import
org.mockito.stubbing.Answer
;
import
org.springframework.beans.factory.BeanCreationException
;
import
org.springframework.context.support.ClassPathXmlApplicationContext
;
import
java.util.List
;
import
static
org
.
junit
.
Assert
.
assertEquals
;
import
static
org
.
mockito
.
Matchers
.
any
;
import
static
org
.
mockito
.
Mockito
.
doAnswer
;
import
static
org
.
mockito
.
Mockito
.
mock
;
/**
* @author Jason Song(song_s@ctrip.com)
*/
public
class
XMLConfigAnnotationTest
extends
AbstractSpringIntegrationTest
{
private
static
final
String
FX_APOLLO_NAMESPACE
=
"FX.apollo"
;
@Test
public
void
testApolloConfig
()
throws
Exception
{
Config
applicationConfig
=
mock
(
Config
.
class
);
Config
fxApolloConfig
=
mock
(
Config
.
class
);
mockConfig
(
ConfigConsts
.
NAMESPACE_APPLICATION
,
applicationConfig
);
mockConfig
(
FX_APOLLO_NAMESPACE
,
fxApolloConfig
);
TestApolloConfigBean1
bean
=
getBean
(
"spring/XmlConfigAnnotationTest1.xml"
,
TestApolloConfigBean1
.
class
);
assertEquals
(
applicationConfig
,
bean
.
getConfig
());
assertEquals
(
applicationConfig
,
bean
.
getAnotherConfig
());
assertEquals
(
fxApolloConfig
,
bean
.
getYetAnotherConfig
());
}
@Test
(
expected
=
BeanCreationException
.
class
)
public
void
testApolloConfigWithWrongFieldType
()
throws
Exception
{
Config
applicationConfig
=
mock
(
Config
.
class
);
mockConfig
(
ConfigConsts
.
NAMESPACE_APPLICATION
,
applicationConfig
);
getBean
(
"spring/XmlConfigAnnotationTest2.xml"
,
TestApolloConfigBean2
.
class
);
}
@Test
public
void
testApolloConfigChangeListener
()
throws
Exception
{
Config
applicationConfig
=
mock
(
Config
.
class
);
Config
fxApolloConfig
=
mock
(
Config
.
class
);
mockConfig
(
ConfigConsts
.
NAMESPACE_APPLICATION
,
applicationConfig
);
mockConfig
(
FX_APOLLO_NAMESPACE
,
fxApolloConfig
);
final
List
<
ConfigChangeListener
>
applicationListeners
=
Lists
.
newArrayList
();
final
List
<
ConfigChangeListener
>
fxApolloListeners
=
Lists
.
newArrayList
();
doAnswer
(
new
Answer
()
{
@Override
public
Object
answer
(
InvocationOnMock
invocation
)
throws
Throwable
{
applicationListeners
.
add
(
invocation
.
getArgumentAt
(
0
,
ConfigChangeListener
.
class
));
return
Void
.
class
;
}
}).
when
(
applicationConfig
).
addChangeListener
(
any
(
ConfigChangeListener
.
class
));
doAnswer
(
new
Answer
()
{
@Override
public
Object
answer
(
InvocationOnMock
invocation
)
throws
Throwable
{
fxApolloListeners
.
add
(
invocation
.
getArgumentAt
(
0
,
ConfigChangeListener
.
class
));
return
Void
.
class
;
}
}).
when
(
fxApolloConfig
).
addChangeListener
(
any
(
ConfigChangeListener
.
class
));
ConfigChangeEvent
someEvent
=
mock
(
ConfigChangeEvent
.
class
);
ConfigChangeEvent
anotherEvent
=
mock
(
ConfigChangeEvent
.
class
);
TestApolloConfigChangeListenerBean1
bean
=
getBean
(
"spring/XmlConfigAnnotationTest3.xml"
,
TestApolloConfigChangeListenerBean1
.
class
);
assertEquals
(
3
,
applicationListeners
.
size
());
assertEquals
(
1
,
fxApolloListeners
.
size
());
for
(
ConfigChangeListener
listener
:
applicationListeners
)
{
listener
.
onChange
(
someEvent
);
}
assertEquals
(
someEvent
,
bean
.
getChangeEvent1
());
assertEquals
(
someEvent
,
bean
.
getChangeEvent2
());
assertEquals
(
someEvent
,
bean
.
getChangeEvent3
());
for
(
ConfigChangeListener
listener
:
fxApolloListeners
)
{
listener
.
onChange
(
anotherEvent
);
}
assertEquals
(
someEvent
,
bean
.
getChangeEvent1
());
assertEquals
(
someEvent
,
bean
.
getChangeEvent2
());
assertEquals
(
anotherEvent
,
bean
.
getChangeEvent3
());
}
@Test
(
expected
=
BeanCreationException
.
class
)
public
void
testApolloConfigChangeListenerWithWrongParamType
()
throws
Exception
{
Config
applicationConfig
=
mock
(
Config
.
class
);
mockConfig
(
ConfigConsts
.
NAMESPACE_APPLICATION
,
applicationConfig
);
getBean
(
"spring/XmlConfigAnnotationTest4.xml"
,
TestApolloConfigChangeListenerBean2
.
class
);
}
@Test
(
expected
=
BeanCreationException
.
class
)
public
void
testApolloConfigChangeListenerWithWrongParamCount
()
throws
Exception
{
Config
applicationConfig
=
mock
(
Config
.
class
);
mockConfig
(
ConfigConsts
.
NAMESPACE_APPLICATION
,
applicationConfig
);
getBean
(
"spring/XmlConfigAnnotationTest5.xml"
,
TestApolloConfigChangeListenerBean3
.
class
);
}
private
<
T
>
T
getBean
(
String
xmlLocation
,
Class
<
T
>
beanClass
)
{
ClassPathXmlApplicationContext
context
=
new
ClassPathXmlApplicationContext
(
xmlLocation
);
return
context
.
getBean
(
beanClass
);
}
public
static
class
TestApolloConfigBean1
{
@ApolloConfig
private
Config
config
;
@ApolloConfig
(
ConfigConsts
.
NAMESPACE_APPLICATION
)
private
Config
anotherConfig
;
@ApolloConfig
(
FX_APOLLO_NAMESPACE
)
private
Config
yetAnotherConfig
;
public
Config
getConfig
()
{
return
config
;
}
public
Config
getAnotherConfig
()
{
return
anotherConfig
;
}
public
Config
getYetAnotherConfig
()
{
return
yetAnotherConfig
;
}
}
public
static
class
TestApolloConfigBean2
{
@ApolloConfig
private
String
config
;
}
public
static
class
TestApolloConfigChangeListenerBean1
{
private
ConfigChangeEvent
changeEvent1
;
private
ConfigChangeEvent
changeEvent2
;
private
ConfigChangeEvent
changeEvent3
;
@ApolloConfigChangeListener
private
void
onChange1
(
ConfigChangeEvent
changeEvent
)
{
this
.
changeEvent1
=
changeEvent
;
}
@ApolloConfigChangeListener
(
ConfigConsts
.
NAMESPACE_APPLICATION
)
private
void
onChange2
(
ConfigChangeEvent
changeEvent
)
{
this
.
changeEvent2
=
changeEvent
;
}
@ApolloConfigChangeListener
({
ConfigConsts
.
NAMESPACE_APPLICATION
,
FX_APOLLO_NAMESPACE
})
private
void
onChange3
(
ConfigChangeEvent
changeEvent
)
{
this
.
changeEvent3
=
changeEvent
;
}
public
ConfigChangeEvent
getChangeEvent1
()
{
return
changeEvent1
;
}
public
ConfigChangeEvent
getChangeEvent2
()
{
return
changeEvent2
;
}
public
ConfigChangeEvent
getChangeEvent3
()
{
return
changeEvent3
;
}
}
public
static
class
TestApolloConfigChangeListenerBean2
{
@ApolloConfigChangeListener
private
void
onChange
(
String
event
)
{
}
}
public
static
class
TestApolloConfigChangeListenerBean3
{
@ApolloConfigChangeListener
private
void
onChange
(
ConfigChangeEvent
event
,
String
someParam
)
{
}
}
}
apollo-client/src/test/java/com/ctrip/framework/apollo/spring/XmlConfigPlaceholderTest.java
0 → 100644
浏览文件 @
ee51eff4
package
com.ctrip.framework.apollo.spring
;
import
com.ctrip.framework.apollo.Config
;
import
com.ctrip.framework.apollo.core.ConfigConsts
;
import
org.junit.Test
;
import
org.springframework.beans.factory.xml.XmlBeanDefinitionStoreException
;
import
org.springframework.context.support.ClassPathXmlApplicationContext
;
import
static
org
.
junit
.
Assert
.
assertEquals
;
import
static
org
.
mockito
.
Matchers
.
anyString
;
import
static
org
.
mockito
.
Matchers
.
eq
;
import
static
org
.
mockito
.
Mockito
.
mock
;
import
static
org
.
mockito
.
Mockito
.
when
;
/**
* @author Jason Song(song_s@ctrip.com)
*/
public
class
XmlConfigPlaceholderTest
extends
AbstractSpringIntegrationTest
{
private
static
final
String
TIMEOUT_PROPERTY
=
"timeout"
;
private
static
final
int
DEFAULT_TIMEOUT
=
100
;
private
static
final
String
BATCH_PROPERTY
=
"batch"
;
private
static
final
int
DEFAULT_BATCH
=
200
;
private
static
final
String
FX_APOLLO_NAMESPACE
=
"FX.apollo"
;
@Test
public
void
testPropertySourceWithNoNamespace
()
throws
Exception
{
int
someTimeout
=
1000
;
int
someBatch
=
2000
;
Config
config
=
mock
(
Config
.
class
);
when
(
config
.
getProperty
(
eq
(
TIMEOUT_PROPERTY
),
anyString
())).
thenReturn
(
String
.
valueOf
(
someTimeout
));
when
(
config
.
getProperty
(
eq
(
BATCH_PROPERTY
),
anyString
())).
thenReturn
(
String
.
valueOf
(
someBatch
));
mockConfig
(
ConfigConsts
.
NAMESPACE_APPLICATION
,
config
);
check
(
"spring/XmlConfigPlaceholderTest1.xml"
,
someTimeout
,
someBatch
);
}
@Test
public
void
testPropertySourceWithNoConfig
()
throws
Exception
{
Config
config
=
mock
(
Config
.
class
);
mockConfig
(
ConfigConsts
.
NAMESPACE_APPLICATION
,
config
);
check
(
"spring/XmlConfigPlaceholderTest1.xml"
,
DEFAULT_TIMEOUT
,
DEFAULT_BATCH
);
}
@Test
public
void
testApplicationPropertySource
()
throws
Exception
{
int
someTimeout
=
1000
;
int
someBatch
=
2000
;
Config
config
=
mock
(
Config
.
class
);
when
(
config
.
getProperty
(
eq
(
TIMEOUT_PROPERTY
),
anyString
())).
thenReturn
(
String
.
valueOf
(
someTimeout
));
when
(
config
.
getProperty
(
eq
(
BATCH_PROPERTY
),
anyString
())).
thenReturn
(
String
.
valueOf
(
someBatch
));
mockConfig
(
ConfigConsts
.
NAMESPACE_APPLICATION
,
config
);
check
(
"spring/XmlConfigPlaceholderTest2.xml"
,
someTimeout
,
someBatch
);
}
@Test
public
void
testMultiplePropertySources
()
throws
Exception
{
int
someTimeout
=
1000
;
int
someBatch
=
2000
;
Config
application
=
mock
(
Config
.
class
);
when
(
application
.
getProperty
(
eq
(
TIMEOUT_PROPERTY
),
anyString
())).
thenReturn
(
String
.
valueOf
(
someTimeout
));
mockConfig
(
ConfigConsts
.
NAMESPACE_APPLICATION
,
application
);
Config
fxApollo
=
mock
(
Config
.
class
);
when
(
application
.
getProperty
(
eq
(
BATCH_PROPERTY
),
anyString
())).
thenReturn
(
String
.
valueOf
(
someBatch
));
mockConfig
(
FX_APOLLO_NAMESPACE
,
fxApollo
);
check
(
"spring/XmlConfigPlaceholderTest3.xml"
,
someTimeout
,
someBatch
);
}
@Test
public
void
testMultiplePropertySourcesWithSameProperties
()
throws
Exception
{
int
someTimeout
=
1000
;
int
anotherTimeout
=
someTimeout
+
1
;
int
someBatch
=
2000
;
Config
application
=
mock
(
Config
.
class
);
when
(
application
.
getProperty
(
eq
(
TIMEOUT_PROPERTY
),
anyString
())).
thenReturn
(
String
.
valueOf
(
someTimeout
));
when
(
application
.
getProperty
(
eq
(
BATCH_PROPERTY
),
anyString
())).
thenReturn
(
String
.
valueOf
(
someBatch
));
mockConfig
(
ConfigConsts
.
NAMESPACE_APPLICATION
,
application
);
Config
fxApollo
=
mock
(
Config
.
class
);
when
(
fxApollo
.
getProperty
(
eq
(
TIMEOUT_PROPERTY
),
anyString
())).
thenReturn
(
String
.
valueOf
(
anotherTimeout
));
mockConfig
(
FX_APOLLO_NAMESPACE
,
fxApollo
);
check
(
"spring/XmlConfigPlaceholderTest3.xml"
,
someTimeout
,
someBatch
);
}
@Test
public
void
testMultiplePropertySourcesWithSamePropertiesWithWeight
()
throws
Exception
{
int
someTimeout
=
1000
;
int
anotherTimeout
=
someTimeout
+
1
;
int
someBatch
=
2000
;
Config
application
=
mock
(
Config
.
class
);
when
(
application
.
getProperty
(
eq
(
TIMEOUT_PROPERTY
),
anyString
())).
thenReturn
(
String
.
valueOf
(
someTimeout
));
when
(
application
.
getProperty
(
eq
(
BATCH_PROPERTY
),
anyString
())).
thenReturn
(
String
.
valueOf
(
someBatch
));
mockConfig
(
ConfigConsts
.
NAMESPACE_APPLICATION
,
application
);
Config
fxApollo
=
mock
(
Config
.
class
);
when
(
fxApollo
.
getProperty
(
eq
(
TIMEOUT_PROPERTY
),
anyString
())).
thenReturn
(
String
.
valueOf
(
anotherTimeout
));
mockConfig
(
FX_APOLLO_NAMESPACE
,
fxApollo
);
check
(
"spring/XmlConfigPlaceholderTest4.xml"
,
anotherTimeout
,
someBatch
);
}
@Test
(
expected
=
XmlBeanDefinitionStoreException
.
class
)
public
void
testWithInvalidWeight
()
throws
Exception
{
check
(
"spring/XmlConfigPlaceholderTest5.xml"
,
DEFAULT_TIMEOUT
,
DEFAULT_BATCH
);
}
private
void
check
(
String
xmlLocation
,
int
expectedTimeout
,
int
expectedBatch
)
{
ClassPathXmlApplicationContext
context
=
new
ClassPathXmlApplicationContext
(
xmlLocation
);
TestXmlBean
bean
=
context
.
getBean
(
TestXmlBean
.
class
);
assertEquals
(
expectedTimeout
,
bean
.
getTimeout
());
assertEquals
(
expectedBatch
,
bean
.
getBatch
());
}
public
static
class
TestXmlBean
{
private
int
timeout
;
private
int
batch
;
public
void
setTimeout
(
int
timeout
)
{
this
.
timeout
=
timeout
;
}
public
int
getTimeout
()
{
return
timeout
;
}
public
int
getBatch
()
{
return
batch
;
}
public
void
setBatch
(
int
batch
)
{
this
.
batch
=
batch
;
}
}
}
apollo-client/src/test/resources/spring/XmlConfigAnnotationTest1.xml
0 → 100644
浏览文件 @
ee51eff4
<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns=
"http://www.springframework.org/schema/beans"
xmlns:xsi=
"http://www.w3.org/2001/XMLSchema-instance"
xmlns:apollo=
"http://www.ctrip.com/schema/apollo"
xsi:schemaLocation=
"http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.ctrip.com/schema/apollo http://www.ctrip.com/schema/apollo.xsd"
>
<apollo:config/>
<bean
class=
"com.ctrip.framework.apollo.spring.XMLConfigAnnotationTest.TestApolloConfigBean1"
/>
</beans>
apollo-client/src/test/resources/spring/XmlConfigAnnotationTest2.xml
0 → 100644
浏览文件 @
ee51eff4
<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns=
"http://www.springframework.org/schema/beans"
xmlns:xsi=
"http://www.w3.org/2001/XMLSchema-instance"
xmlns:apollo=
"http://www.ctrip.com/schema/apollo"
xsi:schemaLocation=
"http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.ctrip.com/schema/apollo http://www.ctrip.com/schema/apollo.xsd"
>
<apollo:config/>
<bean
class=
"com.ctrip.framework.apollo.spring.XMLConfigAnnotationTest.TestApolloConfigBean2"
/>
</beans>
apollo-client/src/test/resources/spring/XmlConfigAnnotationTest3.xml
0 → 100644
浏览文件 @
ee51eff4
<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns=
"http://www.springframework.org/schema/beans"
xmlns:xsi=
"http://www.w3.org/2001/XMLSchema-instance"
xmlns:apollo=
"http://www.ctrip.com/schema/apollo"
xsi:schemaLocation=
"http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.ctrip.com/schema/apollo http://www.ctrip.com/schema/apollo.xsd"
>
<apollo:config/>
<bean
class=
"com.ctrip.framework.apollo.spring.XMLConfigAnnotationTest.TestApolloConfigChangeListenerBean1"
/>
</beans>
apollo-client/src/test/resources/spring/XmlConfigAnnotationTest4.xml
0 → 100644
浏览文件 @
ee51eff4
<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns=
"http://www.springframework.org/schema/beans"
xmlns:xsi=
"http://www.w3.org/2001/XMLSchema-instance"
xmlns:apollo=
"http://www.ctrip.com/schema/apollo"
xsi:schemaLocation=
"http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.ctrip.com/schema/apollo http://www.ctrip.com/schema/apollo.xsd"
>
<apollo:config/>
<bean
class=
"com.ctrip.framework.apollo.spring.XMLConfigAnnotationTest.TestApolloConfigChangeListenerBean2"
/>
</beans>
apollo-client/src/test/resources/spring/XmlConfigAnnotationTest5.xml
0 → 100644
浏览文件 @
ee51eff4
<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns=
"http://www.springframework.org/schema/beans"
xmlns:xsi=
"http://www.w3.org/2001/XMLSchema-instance"
xmlns:apollo=
"http://www.ctrip.com/schema/apollo"
xsi:schemaLocation=
"http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.ctrip.com/schema/apollo http://www.ctrip.com/schema/apollo.xsd"
>
<apollo:config/>
<bean
class=
"com.ctrip.framework.apollo.spring.XMLConfigAnnotationTest.TestApolloConfigChangeListenerBean3"
/>
</beans>
apollo-client/src/test/resources/spring/XmlConfigPlaceholderTest1.xml
0 → 100644
浏览文件 @
ee51eff4
<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns=
"http://www.springframework.org/schema/beans"
xmlns:xsi=
"http://www.w3.org/2001/XMLSchema-instance"
xmlns:apollo=
"http://www.ctrip.com/schema/apollo"
xsi:schemaLocation=
"http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.ctrip.com/schema/apollo http://www.ctrip.com/schema/apollo.xsd"
>
<apollo:config
/>
<bean
class=
"com.ctrip.framework.apollo.spring.XmlConfigPlaceholderTest.TestXmlBean"
>
<property
name=
"timeout"
value=
"${timeout:100}"
/>
<property
name=
"batch"
value=
"${batch:200}"
/>
</bean>
</beans>
apollo-client/src/test/resources/spring/XmlConfigPlaceholderTest2.xml
0 → 100644
浏览文件 @
ee51eff4
<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns=
"http://www.springframework.org/schema/beans"
xmlns:xsi=
"http://www.w3.org/2001/XMLSchema-instance"
xmlns:apollo=
"http://www.ctrip.com/schema/apollo"
xsi:schemaLocation=
"http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.ctrip.com/schema/apollo http://www.ctrip.com/schema/apollo.xsd"
>
<apollo:config
namespaces=
"application"
/>
<bean
class=
"com.ctrip.framework.apollo.spring.XmlConfigPlaceholderTest.TestXmlBean"
>
<property
name=
"timeout"
value=
"${timeout:100}"
/>
<property
name=
"batch"
value=
"${batch:200}"
/>
</bean>
</beans>
apollo-client/src/test/resources/spring/XmlConfigPlaceholderTest3.xml
0 → 100644
浏览文件 @
ee51eff4
<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns=
"http://www.springframework.org/schema/beans"
xmlns:xsi=
"http://www.w3.org/2001/XMLSchema-instance"
xmlns:apollo=
"http://www.ctrip.com/schema/apollo"
xsi:schemaLocation=
"http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.ctrip.com/schema/apollo http://www.ctrip.com/schema/apollo.xsd"
>
<apollo:config
namespaces=
"application,FX.apollo"
/>
<bean
class=
"com.ctrip.framework.apollo.spring.XmlConfigPlaceholderTest.TestXmlBean"
>
<property
name=
"timeout"
value=
"${timeout:100}"
/>
<property
name=
"batch"
value=
"${batch:200}"
/>
</bean>
</beans>
apollo-client/src/test/resources/spring/XmlConfigPlaceholderTest4.xml
0 → 100644
浏览文件 @
ee51eff4
<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns=
"http://www.springframework.org/schema/beans"
xmlns:xsi=
"http://www.w3.org/2001/XMLSchema-instance"
xmlns:apollo=
"http://www.ctrip.com/schema/apollo"
xsi:schemaLocation=
"http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.ctrip.com/schema/apollo http://www.ctrip.com/schema/apollo.xsd"
>
<apollo:config
namespaces=
"application"
/>
<apollo:config
namespaces=
"FX.apollo"
order=
"10"
/>
<bean
class=
"com.ctrip.framework.apollo.spring.XmlConfigPlaceholderTest.TestXmlBean"
>
<property
name=
"timeout"
value=
"${timeout:100}"
/>
<property
name=
"batch"
value=
"${batch:200}"
/>
</bean>
</beans>
apollo-client/src/test/resources/spring/XmlConfigPlaceholderTest5.xml
0 → 100644
浏览文件 @
ee51eff4
<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns=
"http://www.springframework.org/schema/beans"
xmlns:xsi=
"http://www.w3.org/2001/XMLSchema-instance"
xmlns:apollo=
"http://www.ctrip.com/schema/apollo"
xsi:schemaLocation=
"http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.ctrip.com/schema/apollo http://www.ctrip.com/schema/apollo.xsd"
>
<apollo:config
namespaces=
"application"
order=
"abc"
/>
<bean
class=
"com.ctrip.framework.apollo.spring.XmlConfigPlaceholderTest.TestXmlBean"
>
<property
name=
"timeout"
value=
"${timeout:100}"
/>
<property
name=
"batch"
value=
"${batch:200}"
/>
</bean>
</beans>
apollo-demo/pom.xml
浏览文件 @
ee51eff4
...
...
@@ -12,13 +12,70 @@
<packaging>
jar
</packaging>
<properties>
<github.path>
${project.artifactId}
</github.path>
<!-- apollo spring integration requires Spring 3.1.1+ -->
<spring-demo.version>
3.1.1.RELEASE
</spring-demo.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>
org.springframework
</groupId>
<artifactId>
spring-context
</artifactId>
<version>
${spring-demo.version}
</version>
</dependency>
<dependency>
<groupId>
org.springframework
</groupId>
<artifactId>
spring-aop
</artifactId>
<version>
${spring-demo.version}
</version>
</dependency>
<dependency>
<groupId>
org.springframework
</groupId>
<artifactId>
spring-beans
</artifactId>
<version>
${spring-demo.version}
</version>
</dependency>
<dependency>
<groupId>
org.springframework
</groupId>
<artifactId>
spring-core
</artifactId>
<version>
${spring-demo.version}
</version>
<exclusions>
<exclusion>
<groupId>
commons-logging
</groupId>
<artifactId>
commons-logging
</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>
org.springframework
</groupId>
<artifactId>
spring-expression
</artifactId>
<version>
${spring-demo.version}
</version>
</dependency>
<dependency>
<groupId>
org.springframework
</groupId>
<artifactId>
spring-asm
</artifactId>
<version>
${spring-demo.version}
</version>
</dependency>
<dependency>
<groupId>
cglib
</groupId>
<artifactId>
cglib
</artifactId>
<version>
2.2.2
</version>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>
com.ctrip.framework.apollo
</groupId>
<artifactId>
apollo-client
</artifactId>
<version>
${project.version}
</version>
</dependency>
<!-- for spring demo -->
<dependency>
<groupId>
org.springframework
</groupId>
<artifactId>
spring-context
</artifactId>
</dependency>
<!-- required for spring 3.1.0 -->
<dependency>
<groupId>
cglib
</groupId>
<artifactId>
cglib
</artifactId>
</dependency>
<dependency>
<groupId>
org.apache.logging.log4j
</groupId>
<artifactId>
log4j-core
</artifactId>
...
...
@@ -37,6 +94,4 @@
<artifactId>
jcl-over-slf4j
</artifactId>
</dependency>
</dependencies>
</project>
apollo-demo/src/main/java/ApolloConfigDemo.java
→
apollo-demo/src/main/java/
com/ctrip/framework/apollo/demo/api/
ApolloConfigDemo.java
浏览文件 @
ee51eff4
package
com.ctrip.framework.apollo.demo.api
;
import
com.google.common.base.Charsets
;
import
com.ctrip.framework.apollo.Config
;
...
...
apollo-demo/src/main/java/SimpleApolloConfigDemo.java
→
apollo-demo/src/main/java/
com/ctrip/framework/apollo/demo/api/
SimpleApolloConfigDemo.java
浏览文件 @
ee51eff4
package
com.ctrip.framework.apollo.demo.api
;
import
com.google.common.base.Charsets
;
import
com.ctrip.framework.apollo.Config
;
...
...
apollo-demo/src/main/java/com/ctrip/framework/apollo/demo/spring/AnnotationApplication.java
0 → 100644
浏览文件 @
ee51eff4
package
com.ctrip.framework.apollo.demo.spring
;
import
org.springframework.context.annotation.AnnotationConfigApplicationContext
;
import
java.io.IOException
;
/**
* @author Jason Song(song_s@ctrip.com)
*/
public
class
AnnotationApplication
{
public
static
void
main
(
String
[]
args
)
{
new
AnnotationConfigApplicationContext
(
AnnotationApplication
.
class
.
getPackage
().
getName
());
onKeyExit
();
}
private
static
void
onKeyExit
()
{
System
.
out
.
println
(
"Press any key to exit..."
);
try
{
System
.
in
.
read
();
}
catch
(
IOException
e
)
{
e
.
printStackTrace
();
}
}
}
apollo-demo/src/main/java/com/ctrip/framework/apollo/demo/spring/XmlApplication.java
0 → 100644
浏览文件 @
ee51eff4
package
com.ctrip.framework.apollo.demo.spring
;
import
org.springframework.context.support.ClassPathXmlApplicationContext
;
import
java.io.IOException
;
/**
* @author Jason Song(song_s@ctrip.com)
*/
public
class
XmlApplication
{
public
static
void
main
(
String
[]
args
)
{
new
ClassPathXmlApplicationContext
(
"spring.xml"
);
onKeyExit
();
}
private
static
void
onKeyExit
()
{
System
.
out
.
println
(
"Press any key to exit..."
);
try
{
System
.
in
.
read
();
}
catch
(
IOException
e
)
{
e
.
printStackTrace
();
}
}
}
apollo-demo/src/main/java/com/ctrip/framework/apollo/demo/spring/bean/AnnotatedBean.java
0 → 100644
浏览文件 @
ee51eff4
package
com.ctrip.framework.apollo.demo.spring.bean
;
import
com.ctrip.framework.apollo.Config
;
import
com.ctrip.framework.apollo.model.ConfigChange
;
import
com.ctrip.framework.apollo.model.ConfigChangeEvent
;
import
com.ctrip.framework.apollo.spring.annotation.ApolloConfig
;
import
com.ctrip.framework.apollo.spring.annotation.ApolloConfigChangeListener
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.stereotype.Component
;
import
javax.annotation.PostConstruct
;
/**
* @author Jason Song(song_s@ctrip.com)
*/
@Component
public
class
AnnotatedBean
{
private
static
final
Logger
logger
=
LoggerFactory
.
getLogger
(
AnnotatedBean
.
class
);
@Value
(
"${timeout:200}"
)
private
int
timeout
;
private
int
batch
;
@ApolloConfig
private
Config
config
;
@ApolloConfig
(
"FX.apollo"
)
private
Config
anotherConfig
;
@PostConstruct
void
initialize
()
{
logger
.
info
(
"timeout is {}"
,
timeout
);
logger
.
info
(
"batch is {}"
,
batch
);
logger
.
info
(
"Keys for config: {}"
,
config
.
getPropertyNames
());
logger
.
info
(
"Keys for anotherConfig: {}"
,
anotherConfig
.
getPropertyNames
());
}
@Value
(
"${batch:100}"
)
public
void
setBatch
(
int
batch
)
{
this
.
batch
=
batch
;
}
@ApolloConfigChangeListener
(
"application"
)
private
void
someChangeHandler
(
ConfigChangeEvent
changeEvent
)
{
logger
.
info
(
"[someChangeHandler]Changes for namespace {}"
,
changeEvent
.
getNamespace
());
for
(
String
key
:
changeEvent
.
changedKeys
())
{
ConfigChange
change
=
changeEvent
.
getChange
(
key
);
logger
.
info
(
"[someChangeHandler]Change - key: {}, oldValue: {}, newValue: {}, changeType: {}"
,
change
.
getPropertyName
(),
change
.
getOldValue
(),
change
.
getNewValue
(),
change
.
getChangeType
());
}
}
@ApolloConfigChangeListener
({
"application"
,
"FX.apollo"
})
private
void
anotherChangeHandler
(
ConfigChangeEvent
changeEvent
)
{
logger
.
info
(
"[anotherChangeHandler]Changes for namespace {}"
,
changeEvent
.
getNamespace
());
for
(
String
key
:
changeEvent
.
changedKeys
())
{
ConfigChange
change
=
changeEvent
.
getChange
(
key
);
logger
.
info
(
"[anotherChangeHandler]Change - key: {}, oldValue: {}, newValue: {}, changeType: {}"
,
change
.
getPropertyName
(),
change
.
getOldValue
(),
change
.
getNewValue
(),
change
.
getChangeType
());
}
}
}
apollo-demo/src/main/java/com/ctrip/framework/apollo/demo/spring/bean/NormalBean.java
0 → 100644
浏览文件 @
ee51eff4
package
com.ctrip.framework.apollo.demo.spring.bean
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
org.springframework.beans.factory.annotation.Value
;
import
javax.annotation.PostConstruct
;
/**
* @author Jason Song(song_s@ctrip.com)
*/
public
class
NormalBean
{
private
static
final
Logger
logger
=
LoggerFactory
.
getLogger
(
NormalBean
.
class
);
@Value
(
"${timeout:200}"
)
private
int
timeout
;
private
int
batch
;
@PostConstruct
void
initialize
()
{
logger
.
info
(
"timeout is {}"
,
timeout
);
logger
.
info
(
"batch is {}"
,
batch
);
}
public
void
setBatch
(
int
batch
)
{
this
.
batch
=
batch
;
}
}
apollo-demo/src/main/java/com/ctrip/framework/apollo/demo/spring/bean/XmlBean.java
0 → 100644
浏览文件 @
ee51eff4
package
com.ctrip.framework.apollo.demo.spring.bean
;
import
com.ctrip.framework.apollo.Config
;
import
com.ctrip.framework.apollo.model.ConfigChange
;
import
com.ctrip.framework.apollo.model.ConfigChangeEvent
;
import
com.ctrip.framework.apollo.spring.annotation.ApolloConfig
;
import
com.ctrip.framework.apollo.spring.annotation.ApolloConfigChangeListener
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
org.springframework.beans.factory.InitializingBean
;
/**
* @author Jason Song(song_s@ctrip.com)
*/
public
class
XmlBean
implements
InitializingBean
{
private
static
final
Logger
logger
=
LoggerFactory
.
getLogger
(
XmlBean
.
class
);
private
int
timeout
;
private
int
batch
;
@ApolloConfig
private
Config
config
;
@ApolloConfig
(
"FX.apollo"
)
private
Config
anotherConfig
;
public
void
setTimeout
(
int
timeout
)
{
this
.
timeout
=
timeout
;
logger
.
info
(
"Setting timeout to {}"
,
timeout
);
}
public
void
setBatch
(
int
batch
)
{
this
.
batch
=
batch
;
logger
.
info
(
"Setting batch to {}"
,
batch
);
}
@Override
public
void
afterPropertiesSet
()
throws
Exception
{
logger
.
info
(
"Keys for config: {}"
,
config
.
getPropertyNames
());
logger
.
info
(
"Keys for anotherConfig: {}"
,
anotherConfig
.
getPropertyNames
());
}
@ApolloConfigChangeListener
(
"application"
)
private
void
someChangeHandler
(
ConfigChangeEvent
changeEvent
)
{
logger
.
info
(
"[someChangeHandler]Changes for namespace {}"
,
changeEvent
.
getNamespace
());
for
(
String
key
:
changeEvent
.
changedKeys
())
{
ConfigChange
change
=
changeEvent
.
getChange
(
key
);
logger
.
info
(
"[someChangeHandler]Change - key: {}, oldValue: {}, newValue: {}, changeType: {}"
,
change
.
getPropertyName
(),
change
.
getOldValue
(),
change
.
getNewValue
(),
change
.
getChangeType
());
}
}
@ApolloConfigChangeListener
({
"application"
,
"FX.apollo"
})
private
void
anotherChangeHandler
(
ConfigChangeEvent
changeEvent
)
{
logger
.
info
(
"[anotherChangeHandler]Changes for namespace {}"
,
changeEvent
.
getNamespace
());
for
(
String
key
:
changeEvent
.
changedKeys
())
{
ConfigChange
change
=
changeEvent
.
getChange
(
key
);
logger
.
info
(
"[anotherChangeHandler]Change - key: {}, oldValue: {}, newValue: {}, changeType: {}"
,
change
.
getPropertyName
(),
change
.
getOldValue
(),
change
.
getNewValue
(),
change
.
getChangeType
());
}
}
}
apollo-demo/src/main/java/com/ctrip/framework/apollo/demo/spring/config/AnotherAppConfig.java
0 → 100644
浏览文件 @
ee51eff4
package
com.ctrip.framework.apollo.demo.spring.config
;
import
com.ctrip.framework.apollo.spring.annotation.EnableApolloConfig
;
import
org.springframework.context.annotation.Configuration
;
/**
* @author Jason Song(song_s@ctrip.com)
*/
@Configuration
@EnableApolloConfig
(
value
=
"FX.apollo"
,
order
=
11
)
public
class
AnotherAppConfig
{
}
apollo-demo/src/main/java/com/ctrip/framework/apollo/demo/spring/config/AppConfig.java
0 → 100644
浏览文件 @
ee51eff4
package
com.ctrip.framework.apollo.demo.spring.config
;
import
com.ctrip.framework.apollo.demo.spring.bean.NormalBean
;
import
com.ctrip.framework.apollo.spring.annotation.EnableApolloConfig
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.context.annotation.Bean
;
import
org.springframework.context.annotation.Configuration
;
/**
* @author Jason Song(song_s@ctrip.com)
*/
@Configuration
@EnableApolloConfig
(
value
=
"application"
,
order
=
10
)
public
class
AppConfig
{
@Bean
public
NormalBean
normalBean
(
@Value
(
"${batch:100}"
)
int
batch
)
{
NormalBean
bean
=
new
NormalBean
();
bean
.
setBatch
(
batch
);
return
bean
;
}
}
apollo-demo/src/main/resources/log4j2.xml
浏览文件 @
ee51eff4
...
...
@@ -10,6 +10,9 @@
</appenders>
<loggers>
<logger
name=
"com.ctrip.framework.apollo"
additivity=
"false"
level=
"trace"
>
<AppenderRef
ref=
"Async"
level=
"INFO"
/>
</logger>
<logger
name=
"com.ctrip.framework.apollo.demo"
additivity=
"false"
level=
"trace"
>
<AppenderRef
ref=
"Async"
level=
"DEBUG"
/>
</logger>
<root
level=
"INFO"
>
...
...
apollo-demo/src/main/resources/spring.xml
0 → 100644
浏览文件 @
ee51eff4
<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns=
"http://www.springframework.org/schema/beans"
xmlns:xsi=
"http://www.w3.org/2001/XMLSchema-instance"
xmlns:apollo=
"http://www.ctrip.com/schema/apollo"
xsi:schemaLocation=
"http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.ctrip.com/schema/apollo http://www.ctrip.com/schema/apollo.xsd"
>
<apollo:config
order=
"10"
/>
<apollo:config
namespaces=
"FX.apollo"
order=
"11"
/>
<bean
class=
"com.ctrip.framework.apollo.demo.spring.bean.XmlBean"
>
<property
name=
"timeout"
value=
"${timeout:200}"
/>
<property
name=
"batch"
value=
"${batch:100}"
/>
</bean>
</beans>
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录