Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
A
apollo
Project
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
openSource
apollo
Commits
21a8d3ba
Commit
21a8d3ba
authored
Feb 19, 2018
by
xiaohuo
Committed by
nobodyiam
Feb 20, 2018
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Update field or method which has @Value annotation automatically
parent
7edfb1aa
Show whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
480 additions
and
4 deletions
+480
-4
ApolloConfigRegistrar.java
...ework/apollo/spring/annotation/ApolloConfigRegistrar.java
+2
-0
SpringValueProcessor.java
...mework/apollo/spring/annotation/SpringValueProcessor.java
+163
-0
SpringFieldValue.java
.../ctrip/framework/apollo/spring/auto/SpringFieldValue.java
+39
-0
SpringMethodValue.java
...ctrip/framework/apollo/spring/auto/SpringMethodValue.java
+45
-0
SpringValue.java
...a/com/ctrip/framework/apollo/spring/auto/SpringValue.java
+57
-0
ConfigPropertySourcesProcessor.java
.../apollo/spring/config/ConfigPropertySourcesProcessor.java
+2
-0
PropertySourcesProcessor.java
...mework/apollo/spring/config/PropertySourcesProcessor.java
+12
-1
JavaConfigAnnotationTest.java
...rip/framework/apollo/spring/JavaConfigAnnotationTest.java
+2
-1
XMLConfigAnnotationTest.java
...trip/framework/apollo/spring/XMLConfigAnnotationTest.java
+2
-1
SpringValueTest.java
...m/ctrip/framework/apollo/spring/auto/SpringValueTest.java
+83
-0
DefaultApplicationProvider.java
...dation/internals/provider/DefaultApplicationProvider.java
+32
-1
NullProvider.java
...framework/foundation/internals/provider/NullProvider.java
+5
-0
ApplicationProvider.java
...ramework/foundation/spi/provider/ApplicationProvider.java
+4
-0
DefaultApplicationProviderTest.java
...on/internals/provider/DefaultApplicationProviderTest.java
+30
-0
app.properties
apollo-core/src/test/resources/META-INF/app.properties
+0
-0
some-invalid-app.properties
...e/src/test/resources/META-INF/some-invalid-app.properties
+2
-0
No files found.
apollo-client/src/main/java/com/ctrip/framework/apollo/spring/annotation/ApolloConfigRegistrar.java
View file @
21a8d3ba
...
...
@@ -30,5 +30,7 @@ public class ApolloConfigRegistrar implements ImportBeanDefinitionRegistrar {
BeanRegistrationUtil
.
registerBeanDefinitionIfNotExists
(
registry
,
ApolloAnnotationProcessor
.
class
.
getName
(),
ApolloAnnotationProcessor
.
class
);
BeanRegistrationUtil
.
registerBeanDefinitionIfNotExists
(
registry
,
SpringValueProcessor
.
class
.
getName
(),
SpringValueProcessor
.
class
);
}
}
apollo-client/src/main/java/com/ctrip/framework/apollo/spring/annotation/SpringValueProcessor.java
0 → 100644
View file @
21a8d3ba
package
com
.
ctrip
.
framework
.
apollo
.
spring
.
annotation
;
import
com.ctrip.framework.apollo.ConfigChangeListener
;
import
com.ctrip.framework.apollo.model.ConfigChange
;
import
com.ctrip.framework.apollo.model.ConfigChangeEvent
;
import
com.ctrip.framework.apollo.spring.auto.SpringFieldValue
;
import
com.ctrip.framework.apollo.spring.auto.SpringMethodValue
;
import
com.ctrip.framework.apollo.spring.auto.SpringValue
;
import
com.ctrip.framework.apollo.spring.config.PropertySourcesProcessor
;
import
com.ctrip.framework.foundation.Foundation
;
import
com.ctrip.framework.foundation.spi.provider.ApplicationProvider
;
import
com.google.common.collect.LinkedListMultimap
;
import
com.google.common.collect.Multimap
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
org.springframework.beans.BeansException
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.beans.factory.config.BeanPostProcessor
;
import
org.springframework.context.EnvironmentAware
;
import
org.springframework.core.Ordered
;
import
org.springframework.core.PriorityOrdered
;
import
org.springframework.core.env.Environment
;
import
org.springframework.util.CollectionUtils
;
import
org.springframework.util.ReflectionUtils
;
import
java.lang.reflect.Field
;
import
java.lang.reflect.Method
;
import
java.util.Collection
;
import
java.util.LinkedList
;
import
java.util.List
;
import
java.util.Objects
;
import
java.util.Set
;
import
java.util.regex.Matcher
;
import
java.util.regex.Pattern
;
/**
* Spring value processor of field or method which has @Value.
*
* @author github.com/zhegexiaohuozi seimimaster@gmail.com
* @since 2017/12/20.
*/
public
class
SpringValueProcessor
implements
BeanPostProcessor
,
PriorityOrdered
,
EnvironmentAware
{
private
Pattern
pattern
=
Pattern
.
compile
(
"\\$\\{([^:]*)\\}:?(.*)"
);
private
static
Multimap
<
String
,
SpringValue
>
monitor
=
LinkedListMultimap
.
create
();
private
static
ApplicationProvider
applicationProvider
=
Foundation
.
app
();
private
Environment
environment
;
private
Logger
logger
=
LoggerFactory
.
getLogger
(
SpringValueProcessor
.
class
);
public
static
Multimap
<
String
,
SpringValue
>
monitor
()
{
return
monitor
;
}
public
static
boolean
enable
(){
return
applicationProvider
.
isAutoUpdateEnable
();
}
@Override
public
Object
postProcessBeforeInitialization
(
Object
bean
,
String
beanName
)
throws
BeansException
{
boolean
enabled
=
enable
();
if
(
enabled
){
Class
clazz
=
bean
.
getClass
();
processFields
(
bean
,
findAllField
(
clazz
));
processMethods
(
bean
,
findAllMethod
(
clazz
));
}
return
bean
;
}
@Override
public
Object
postProcessAfterInitialization
(
Object
bean
,
String
beanName
)
throws
BeansException
{
return
bean
;
}
private
void
processFields
(
Object
bean
,
List
<
Field
>
declaredFields
)
{
for
(
Field
field
:
declaredFields
)
{
// regist @Value on field
Value
value
=
field
.
getAnnotation
(
Value
.
class
);
if
(
value
==
null
)
{
continue
;
}
Matcher
matcher
=
pattern
.
matcher
(
value
.
value
());
if
(
matcher
.
matches
())
{
String
key
=
matcher
.
group
(
1
);
monitor
.
put
(
key
,
SpringFieldValue
.
create
(
key
,
bean
,
field
));
logger
.
info
(
"Listening apollo key = {}"
,
key
);
}
}
}
private
void
processMethods
(
final
Object
bean
,
List
<
Method
>
declaredMethods
)
{
for
(
final
Method
method
:
declaredMethods
)
{
//regist @Value on method
Value
value
=
method
.
getAnnotation
(
Value
.
class
);
if
(
value
==
null
)
{
continue
;
}
Matcher
matcher
=
pattern
.
matcher
(
value
.
value
());
if
(
matcher
.
matches
())
{
String
key
=
matcher
.
group
(
1
);
monitor
.
put
(
key
,
SpringMethodValue
.
create
(
key
,
bean
,
method
));
logger
.
info
(
"Listening apollo key = {}"
,
key
);
}
}
}
@Override
public
int
getOrder
()
{
//make it as late as possible
return
Ordered
.
LOWEST_PRECEDENCE
;
}
private
List
<
Field
>
findAllField
(
Class
clazz
)
{
final
List
<
Field
>
res
=
new
LinkedList
<>();
ReflectionUtils
.
doWithFields
(
clazz
,
new
ReflectionUtils
.
FieldCallback
()
{
@Override
public
void
doWith
(
Field
field
)
throws
IllegalArgumentException
,
IllegalAccessException
{
res
.
add
(
field
);
}
});
return
res
;
}
private
List
<
Method
>
findAllMethod
(
Class
clazz
)
{
final
List
<
Method
>
res
=
new
LinkedList
<>();
ReflectionUtils
.
doWithMethods
(
clazz
,
new
ReflectionUtils
.
MethodCallback
()
{
@Override
public
void
doWith
(
Method
method
)
throws
IllegalArgumentException
,
IllegalAccessException
{
res
.
add
(
method
);
}
});
return
res
;
}
@Override
public
void
setEnvironment
(
Environment
env
)
{
this
.
environment
=
env
;
PropertySourcesProcessor
.
registerListener
(
new
ConfigChangeListener
()
{
@Override
public
void
onChange
(
ConfigChangeEvent
changeEvent
)
{
Set
<
String
>
keys
=
changeEvent
.
changedKeys
();
if
(
CollectionUtils
.
isEmpty
(
keys
))
{
return
;
}
if
(!
SpringValueProcessor
.
enable
())
{
return
;
}
for
(
String
k
:
keys
)
{
ConfigChange
configChange
=
changeEvent
.
getChange
(
k
);
if
(!
Objects
.
equals
(
environment
.
getProperty
(
k
),
configChange
.
getNewValue
()))
{
continue
;
}
Collection
<
SpringValue
>
targetValues
=
SpringValueProcessor
.
monitor
().
get
(
k
);
if
(
targetValues
==
null
||
targetValues
.
isEmpty
())
{
continue
;
}
for
(
SpringValue
val
:
targetValues
)
{
val
.
updateVal
(
environment
.
getProperty
(
k
));
}
}
}
});
}
}
apollo-client/src/main/java/com/ctrip/framework/apollo/spring/auto/SpringFieldValue.java
0 → 100644
View file @
21a8d3ba
package
com
.
ctrip
.
framework
.
apollo
.
spring
.
auto
;
import
java.lang.reflect.Field
;
/**
* Spring @Value field info
* @author github.com/zhegexiaohuozi seimimaster@gmail.com
* @since 2018/2/6.
*/
public
class
SpringFieldValue
extends
SpringValue
{
private
Field
field
;
private
SpringFieldValue
(
String
key
,
Object
ins
,
Field
field
)
{
super
();
this
.
bean
=
ins
;
this
.
className
=
ins
.
getClass
().
getName
();
this
.
fieldName
=
field
.
getName
();
this
.
field
=
field
;
this
.
parser
=
findParser
(
field
.
getType
());
this
.
valKey
=
key
;
}
public
static
SpringFieldValue
create
(
String
key
,
Object
ins
,
Field
field
)
{
return
new
SpringFieldValue
(
key
,
ins
,
field
);
}
@Override
public
void
updateVal
(
String
newVal
)
{
try
{
boolean
accessible
=
field
.
isAccessible
();
field
.
setAccessible
(
true
);
field
.
set
(
bean
,
parseVal
(
newVal
));
field
.
setAccessible
(
accessible
);
logger
.
info
(
"auto update apollo changed value, key={}, newVal={} in {}.{}"
,
valKey
,
newVal
,
className
,
fieldName
);
}
catch
(
Exception
e
)
{
logger
.
error
(
"update field {}.{} fail with new val={},key = {}, msg = {}"
,
className
,
fieldName
,
newVal
,
valKey
,
e
.
getMessage
());
}
}
}
apollo-client/src/main/java/com/ctrip/framework/apollo/spring/auto/SpringMethodValue.java
0 → 100644
View file @
21a8d3ba
package
com
.
ctrip
.
framework
.
apollo
.
spring
.
auto
;
import
java.lang.reflect.Method
;
/**
* Spring @Value method info
* @author github.com/zhegexiaohuozi seimimaster@gmail.com
* @since 2018/2/6.
*/
public
class
SpringMethodValue
extends
SpringValue
{
private
Method
method
;
private
SpringMethodValue
(
String
key
,
Object
ins
,
Method
method
)
{
this
.
bean
=
ins
;
this
.
method
=
method
;
this
.
className
=
ins
.
getClass
().
getName
();
this
.
fieldName
=
method
.
getName
()
+
"(*)"
;
Class
<?>[]
paramTps
=
method
.
getParameterTypes
();
if
(
paramTps
.
length
!=
1
)
{
logger
.
error
(
"invalid setter,can not update in {}.{}"
,
className
,
fieldName
);
return
;
}
this
.
parser
=
findParser
(
paramTps
[
0
]);
this
.
valKey
=
key
;
}
public
static
SpringMethodValue
create
(
String
key
,
Object
ins
,
Method
method
)
{
return
new
SpringMethodValue
(
key
,
ins
,
method
);
}
@Override
public
void
updateVal
(
String
newVal
)
{
try
{
Class
<?>[]
paramTps
=
method
.
getParameterTypes
();
if
(
paramTps
.
length
!=
1
)
{
logger
.
error
(
"invalid setter ,can not update key={} val={} in {}.{}"
,
valKey
,
newVal
,
className
,
fieldName
);
return
;
}
method
.
invoke
(
bean
,
parseVal
(
newVal
));
logger
.
info
(
"auto update apollo changed value, key={}, newVal={} in {}.{}"
,
valKey
,
newVal
,
className
,
fieldName
);
}
catch
(
Exception
e
)
{
logger
.
error
(
"update field {}.{} fail with new val={},key = {}, msg = {}"
,
className
,
fieldName
,
newVal
,
valKey
,
e
.
getMessage
());
}
}
}
apollo-client/src/main/java/com/ctrip/framework/apollo/spring/auto/SpringValue.java
0 → 100644
View file @
21a8d3ba
package
com
.
ctrip
.
framework
.
apollo
.
spring
.
auto
;
import
com.ctrip.framework.apollo.util.function.Functions
;
import
com.google.common.base.Function
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
java.util.Date
;
/**
* Spring @Value field and method common info
*
* @author github.com/zhegexiaohuozi seimimaster@gmail.com
* @since 2017/12/20.
*/
public
abstract
class
SpringValue
{
protected
Object
bean
;
String
className
;
String
fieldName
;
String
valKey
;
protected
Function
<
String
,
?>
parser
;
protected
Logger
logger
=
LoggerFactory
.
getLogger
(
getClass
());
public
abstract
void
updateVal
(
String
newVal
);
Object
parseVal
(
String
newVal
)
{
if
(
parser
==
null
)
{
return
newVal
;
}
return
parser
.
apply
(
newVal
);
}
Function
<
String
,
?>
findParser
(
Class
<?>
targetType
)
{
Function
<
String
,
?>
res
=
null
;
if
(
targetType
.
equals
(
String
.
class
))
{
return
null
;
}
else
if
(
targetType
.
equals
(
int
.
class
)
||
targetType
.
equals
(
Integer
.
class
))
{
res
=
Functions
.
TO_INT_FUNCTION
;
}
else
if
(
targetType
.
equals
(
long
.
class
)
||
targetType
.
equals
(
Long
.
class
))
{
res
=
Functions
.
TO_LONG_FUNCTION
;
}
else
if
(
targetType
.
equals
(
boolean
.
class
)
||
targetType
.
equals
(
Boolean
.
class
))
{
res
=
Functions
.
TO_BOOLEAN_FUNCTION
;
}
else
if
(
targetType
.
equals
(
Date
.
class
))
{
res
=
Functions
.
TO_DATE_FUNCTION
;
}
else
if
(
targetType
.
equals
(
short
.
class
)
||
targetType
.
equals
(
Short
.
class
))
{
res
=
Functions
.
TO_SHORT_FUNCTION
;
}
else
if
(
targetType
.
equals
(
double
.
class
)
||
targetType
.
equals
(
Double
.
class
))
{
res
=
Functions
.
TO_DOUBLE_FUNCTION
;
}
else
if
(
targetType
.
equals
(
float
.
class
)
||
targetType
.
equals
(
Float
.
class
))
{
res
=
Functions
.
TO_FLOAT_FUNCTION
;
}
else
if
(
targetType
.
equals
(
byte
.
class
)
||
targetType
.
equals
(
Byte
.
class
))
{
res
=
Functions
.
TO_BYTE_FUNCTION
;
}
return
res
;
}
}
apollo-client/src/main/java/com/ctrip/framework/apollo/spring/config/ConfigPropertySourcesProcessor.java
View file @
21a8d3ba
package
com
.
ctrip
.
framework
.
apollo
.
spring
.
config
;
import
com.ctrip.framework.apollo.spring.annotation.SpringValueProcessor
;
import
org.springframework.beans.BeansException
;
import
org.springframework.beans.factory.support.BeanDefinitionRegistry
;
import
org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor
;
...
...
@@ -22,5 +23,6 @@ public class ConfigPropertySourcesProcessor extends PropertySourcesProcessor
PropertySourcesPlaceholderConfigurer
.
class
);
BeanRegistrationUtil
.
registerBeanDefinitionIfNotExists
(
registry
,
ApolloAnnotationProcessor
.
class
.
getName
(),
ApolloAnnotationProcessor
.
class
);
BeanRegistrationUtil
.
registerBeanDefinitionIfNotExists
(
registry
,
SpringValueProcessor
.
class
.
getName
(),
SpringValueProcessor
.
class
);
}
}
apollo-client/src/main/java/com/ctrip/framework/apollo/spring/config/PropertySourcesProcessor.java
View file @
21a8d3ba
package
com
.
ctrip
.
framework
.
apollo
.
spring
.
config
;
import
com.google.common.collect.HashMultimap
;
import
com.ctrip.framework.apollo.ConfigChangeListener
;
import
com.google.common.collect.ImmutableSortedSet
;
import
com.google.common.collect.Lists
;
import
com.google.common.collect.LinkedHashMultimap
;
import
com.google.common.collect.Multimap
;
...
...
@@ -19,6 +22,7 @@ import org.springframework.core.env.Environment;
import
java.util.Collection
;
import
java.util.Iterator
;
import
java.util.List
;
/**
* Apollo Property Sources processor for Spring Annotation Based Application. <br /> <br />
...
...
@@ -31,6 +35,7 @@ import java.util.Iterator;
* @author Jason Song(song_s@ctrip.com)
*/
public
class
PropertySourcesProcessor
implements
BeanFactoryPostProcessor
,
EnvironmentAware
,
PriorityOrdered
{
private
static
final
List
<
Config
>
ALL_CONFIG
=
Lists
.
newLinkedList
();
private
static
final
Multimap
<
Integer
,
String
>
NAMESPACE_NAMES
=
LinkedHashMultimap
.
create
();
private
ConfigurableEnvironment
environment
;
...
...
@@ -39,6 +44,12 @@ public class PropertySourcesProcessor implements BeanFactoryPostProcessor, Envir
return
NAMESPACE_NAMES
.
putAll
(
order
,
namespaces
);
}
public
static
void
registerListener
(
ConfigChangeListener
configChangeListener
){
for
(
Config
config:
ALL_CONFIG
){
config
.
addChangeListener
(
configChangeListener
);
}
}
@Override
public
void
postProcessBeanFactory
(
ConfigurableListableBeanFactory
beanFactory
)
throws
BeansException
{
initializePropertySources
();
...
...
@@ -59,7 +70,7 @@ public class PropertySourcesProcessor implements BeanFactoryPostProcessor, Envir
int
order
=
iterator
.
next
();
for
(
String
namespace
:
NAMESPACE_NAMES
.
get
(
order
))
{
Config
config
=
ConfigService
.
getConfig
(
namespace
);
ALL_CONFIG
.
add
(
config
);
composite
.
addPropertySource
(
new
ConfigPropertySource
(
namespace
,
config
));
}
}
...
...
apollo-client/src/test/java/com/ctrip/framework/apollo/spring/JavaConfigAnnotationTest.java
View file @
21a8d3ba
...
...
@@ -88,7 +88,8 @@ public class JavaConfigAnnotationTest extends AbstractSpringIntegrationTest {
TestApolloConfigChangeListenerBean1
bean
=
getBean
(
TestApolloConfigChangeListenerBean1
.
class
,
AppConfig3
.
class
);
assertEquals
(
3
,
applicationListeners
.
size
());
//PropertySourcesProcessor add listeners to listen config changed of all namespace
assertEquals
(
4
,
applicationListeners
.
size
());
assertEquals
(
1
,
fxApolloListeners
.
size
());
for
(
ConfigChangeListener
listener
:
applicationListeners
)
{
...
...
apollo-client/src/test/java/com/ctrip/framework/apollo/spring/XMLConfigAnnotationTest.java
View file @
21a8d3ba
...
...
@@ -86,7 +86,8 @@ public class XMLConfigAnnotationTest extends AbstractSpringIntegrationTest {
TestApolloConfigChangeListenerBean1
bean
=
getBean
(
"spring/XmlConfigAnnotationTest3.xml"
,
TestApolloConfigChangeListenerBean1
.
class
);
assertEquals
(
3
,
applicationListeners
.
size
());
//PropertySourcesProcessor add listeners to listen config changed of all namespace
assertEquals
(
4
,
applicationListeners
.
size
());
assertEquals
(
1
,
fxApolloListeners
.
size
());
for
(
ConfigChangeListener
listener
:
applicationListeners
)
{
...
...
apollo-client/src/test/java/com/ctrip/framework/apollo/spring/auto/SpringValueTest.java
0 → 100644
View file @
21a8d3ba
package
com
.
ctrip
.
framework
.
apollo
.
spring
.
auto
;
import
com.ctrip.framework.apollo.enums.PropertyChangeType
;
import
com.ctrip.framework.apollo.model.ConfigChange
;
import
com.ctrip.framework.apollo.util.function.Functions
;
import
org.junit.Assert
;
import
org.junit.Before
;
import
org.junit.Test
;
import
java.lang.reflect.Field
;
import
java.lang.reflect.Method
;
import
java.util.Date
;
import
java.util.regex.Matcher
;
import
java.util.regex.Pattern
;
/**
* SpringValue Tester.
*
* @author github.com/zhegexiaohuozi seimimaster@gmail.com
* @version 1.0
*/
public
class
SpringValueTest
{
private
SpringValue
defaultVal
;
private
ConfigChange
testTarget
;
//SpringValueProcessor.pattern
private
Pattern
pattern
=
Pattern
.
compile
(
"\\$\\{([^:]*)\\}:?(.*)"
);
@Before
public
void
before
()
throws
Exception
{
Field
field
=
ConfigChange
.
class
.
getDeclaredField
(
"newValue"
);
field
.
setAccessible
(
true
);
testTarget
=
new
ConfigChange
(
"test"
,
"test"
,
"testO"
,
"testN"
,
PropertyChangeType
.
MODIFIED
);
defaultVal
=
SpringFieldValue
.
create
(
"test"
,
testTarget
,
field
);
}
/**
* Method: updateVal(String newVal)
*/
@Test
public
void
testUpdateVal
()
throws
Exception
{
defaultVal
.
updateVal
(
"testUp"
);
Assert
.
assertEquals
(
"testUp"
,
testTarget
.
getNewValue
());
}
/**
* Method: findParser(Class<?> targetType)
*/
@Test
public
void
testFindParser
()
throws
Exception
{
Method
findParser
=
SpringValue
.
class
.
getDeclaredMethod
(
"findParser"
,
Class
.
class
);
findParser
.
setAccessible
(
true
);
Assert
.
assertNull
(
findParser
.
invoke
(
defaultVal
,
String
.
class
));
Assert
.
assertEquals
(
Functions
.
TO_INT_FUNCTION
,
findParser
.
invoke
(
defaultVal
,
int
.
class
));
Assert
.
assertEquals
(
Functions
.
TO_INT_FUNCTION
,
findParser
.
invoke
(
defaultVal
,
Integer
.
class
));
Assert
.
assertEquals
(
Functions
.
TO_LONG_FUNCTION
,
findParser
.
invoke
(
defaultVal
,
long
.
class
));
Assert
.
assertEquals
(
Functions
.
TO_LONG_FUNCTION
,
findParser
.
invoke
(
defaultVal
,
Long
.
class
));
Assert
.
assertEquals
(
Functions
.
TO_DOUBLE_FUNCTION
,
findParser
.
invoke
(
defaultVal
,
double
.
class
));
Assert
.
assertEquals
(
Functions
.
TO_DOUBLE_FUNCTION
,
findParser
.
invoke
(
defaultVal
,
Double
.
class
));
Assert
.
assertEquals
(
Functions
.
TO_FLOAT_FUNCTION
,
findParser
.
invoke
(
defaultVal
,
float
.
class
));
Assert
.
assertEquals
(
Functions
.
TO_FLOAT_FUNCTION
,
findParser
.
invoke
(
defaultVal
,
Float
.
class
));
Assert
.
assertEquals
(
Functions
.
TO_BYTE_FUNCTION
,
findParser
.
invoke
(
defaultVal
,
byte
.
class
));
Assert
.
assertEquals
(
Functions
.
TO_BYTE_FUNCTION
,
findParser
.
invoke
(
defaultVal
,
Byte
.
class
));
Assert
.
assertEquals
(
Functions
.
TO_BOOLEAN_FUNCTION
,
findParser
.
invoke
(
defaultVal
,
boolean
.
class
));
Assert
.
assertEquals
(
Functions
.
TO_BOOLEAN_FUNCTION
,
findParser
.
invoke
(
defaultVal
,
Boolean
.
class
));
Assert
.
assertEquals
(
Functions
.
TO_SHORT_FUNCTION
,
findParser
.
invoke
(
defaultVal
,
short
.
class
));
Assert
.
assertEquals
(
Functions
.
TO_SHORT_FUNCTION
,
findParser
.
invoke
(
defaultVal
,
Short
.
class
));
Assert
.
assertEquals
(
Functions
.
TO_DATE_FUNCTION
,
findParser
.
invoke
(
defaultVal
,
Date
.
class
));
}
@Test
public
void
testPattern
(){
String
valP
=
"${some.timeout:5000}"
;
Matcher
matcher
=
pattern
.
matcher
(
valP
);
if
(
matcher
.
matches
())
{
String
key
=
matcher
.
group
(
1
);
Assert
.
assertEquals
(
"some.timeout"
,
key
);
}
}
}
apollo-core/src/main/java/com/ctrip/framework/foundation/internals/provider/DefaultApplicationProvider.java
View file @
21a8d3ba
...
...
@@ -19,6 +19,7 @@ public class DefaultApplicationProvider implements ApplicationProvider {
private
Properties
m_appProperties
=
new
Properties
();
private
String
m_appId
;
private
boolean
m_enableAutoUpdate
;
@Override
public
void
initialize
()
{
...
...
@@ -49,11 +50,20 @@ public class DefaultApplicationProvider implements ApplicationProvider {
}
initAppId
();
initEnableAutoUpdate
();
}
catch
(
Throwable
ex
)
{
logger
.
error
(
"Initialize DefaultApplicationProvider failed."
,
ex
);
}
}
/**
* @return whether update the field or method which has '@Value' automatically
*/
@Override
public
boolean
isAutoUpdateEnable
()
{
return
m_enableAutoUpdate
;
}
@Override
public
String
getAppId
()
{
return
m_appId
;
...
...
@@ -101,8 +111,29 @@ public class DefaultApplicationProvider implements ApplicationProvider {
logger
.
warn
(
"app.id is not available from System Property and {}. It is set to null"
,
APP_PROPERTIES_CLASSPATH
);
}
private
void
initEnableAutoUpdate
(){
// 1. Get app.autoupdate.enabled from System Property
String
enabeAutoUpdate
=
System
.
getProperty
(
"app.autoupdate.enabled"
);
if
(!
Utils
.
isBlank
(
enabeAutoUpdate
))
{
m_enableAutoUpdate
=
Boolean
.
parseBoolean
(
enabeAutoUpdate
.
trim
());
logger
.
info
(
"App update value automatically is {} by app.autoupdate property from System Property"
,
m_enableAutoUpdate
);
return
;
}
// 2. Try to get app.autoupdate.enabled from app.properties.
enabeAutoUpdate
=
m_appProperties
.
getProperty
(
"app.autoupdate.enabled"
);
if
(!
Utils
.
isBlank
(
enabeAutoUpdate
))
{
m_enableAutoUpdate
=
Boolean
.
parseBoolean
(
enabeAutoUpdate
.
trim
());
logger
.
info
(
"App update value automatically is {} by app.autoupdate property from {}"
,
m_enableAutoUpdate
,
APP_PROPERTIES_CLASSPATH
);
return
;
}
// default true, update field automatically
m_enableAutoUpdate
=
true
;
}
@Override
public
String
toString
()
{
return
"appId ["
+
getAppId
()
+
"] properties: "
+
m_appProperties
+
" (DefaultApplicationProvider)"
;
return
"appId ["
+
getAppId
()
+
"]
,enableAutoUpdate["
+
isAutoUpdateEnable
()+
"]
properties: "
+
m_appProperties
+
" (DefaultApplicationProvider)"
;
}
}
apollo-core/src/main/java/com/ctrip/framework/foundation/internals/provider/NullProvider.java
View file @
21a8d3ba
...
...
@@ -59,6 +59,11 @@ public class NullProvider implements ApplicationProvider, NetworkProvider, Serve
}
@Override
public
boolean
isAutoUpdateEnable
()
{
return
false
;
}
@Override
public
String
getHostAddress
()
{
return
null
;
}
...
...
apollo-core/src/main/java/com/ctrip/framework/foundation/spi/provider/ApplicationProvider.java
View file @
21a8d3ba
...
...
@@ -20,4 +20,8 @@ public interface ApplicationProvider extends Provider {
* Initialize the application provider with the specified input stream
*/
public
void
initialize
(
InputStream
in
);
/**
* @return whether update the field or method which has '@Value' automatically
*/
public
boolean
isAutoUpdateEnable
();
}
apollo-core/src/test/java/com/ctrip/framework/apollo/foundation/internals/provider/DefaultApplicationProviderTest.java
View file @
21a8d3ba
...
...
@@ -61,4 +61,34 @@ public class DefaultApplicationProviderTest {
assertEquals
(
null
,
defaultApplicationProvider
.
getAppId
());
assertFalse
(
defaultApplicationProvider
.
isAppIdSet
());
}
@Test
public
void
testLoadAutoUpdateSwitchFromSystemProperty
(){
String
notEnable
=
"false"
;
System
.
setProperty
(
"app.autoupdate.enabled"
,
notEnable
);
defaultApplicationProvider
.
initialize
();
System
.
clearProperty
(
"app.autoupdate.enabled"
);
assertFalse
(
defaultApplicationProvider
.
isAutoUpdateEnable
());
}
@Test
public
void
testLoadAutoUpdateSwitchFormConfigFile
()
throws
Exception
{
File
baseDir
=
new
File
(
"src/test/resources/META-INF"
);
File
appProperties
=
new
File
(
baseDir
,
"some-invalid-app.properties"
);
defaultApplicationProvider
.
initialize
(
new
FileInputStream
(
appProperties
));
assertFalse
(
defaultApplicationProvider
.
isAutoUpdateEnable
());
}
@Test
public
void
testLoadAutoUpdateSwitchByDefault
()
throws
Exception
{
File
baseDir
=
new
File
(
"src/test/resources/META-INF"
);
File
appProperties
=
new
File
(
baseDir
,
"app.properties"
);
defaultApplicationProvider
.
initialize
(
new
FileInputStream
(
appProperties
));
assertTrue
(
defaultApplicationProvider
.
isAutoUpdateEnable
());
}
}
apollo-core/src/test/resources/META-INF/app.properties
View file @
21a8d3ba
apollo-core/src/test/resources/META-INF/some-invalid-app.properties
View file @
21a8d3ba
appid
=
110402
app.autoupdate.enabled
=
false
\ No newline at end of file
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment