1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.springframework.context.annotation;
18
19 import java.util.ArrayList;
20 import java.util.Collections;
21 import java.util.List;
22
23 import org.springframework.beans.BeanUtils;
24 import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
25 import org.springframework.beans.factory.support.BeanDefinitionRegistry;
26 import org.springframework.context.ConfigurableApplicationContext;
27 import org.springframework.context.annotation.ConfigurationCondition.ConfigurationPhase;
28 import org.springframework.core.annotation.AnnotationAwareOrderComparator;
29 import org.springframework.core.env.Environment;
30 import org.springframework.core.env.EnvironmentCapable;
31 import org.springframework.core.io.ResourceLoader;
32 import org.springframework.core.type.AnnotatedTypeMetadata;
33 import org.springframework.core.type.AnnotationMetadata;
34 import org.springframework.util.ClassUtils;
35 import org.springframework.util.MultiValueMap;
36
37
38
39
40
41
42
43 class ConditionEvaluator {
44
45 private final ConditionContextImpl context;
46
47
48
49
50
51 public ConditionEvaluator(BeanDefinitionRegistry registry, Environment environment, ResourceLoader resourceLoader) {
52 this.context = new ConditionContextImpl(registry, environment, resourceLoader);
53 }
54
55
56
57
58
59
60
61
62
63 public boolean shouldSkip(AnnotatedTypeMetadata metadata) {
64 return shouldSkip(metadata, null);
65 }
66
67
68
69
70
71
72
73 public boolean shouldSkip(AnnotatedTypeMetadata metadata, ConfigurationPhase phase) {
74 if (metadata == null || !metadata.isAnnotated(Conditional.class.getName())) {
75 return false;
76 }
77
78 if (phase == null) {
79 if (metadata instanceof AnnotationMetadata &&
80 ConfigurationClassUtils.isConfigurationCandidate((AnnotationMetadata) metadata)) {
81 return shouldSkip(metadata, ConfigurationPhase.PARSE_CONFIGURATION);
82 }
83 return shouldSkip(metadata, ConfigurationPhase.REGISTER_BEAN);
84 }
85
86 List<Condition> conditions = new ArrayList<Condition>();
87 for (String[] conditionClasses : getConditionClasses(metadata)) {
88 for (String conditionClass : conditionClasses) {
89 Condition condition = getCondition(conditionClass, this.context.getClassLoader());
90 conditions.add(condition);
91 }
92 }
93
94 AnnotationAwareOrderComparator.sort(conditions);
95
96 for (Condition condition : conditions) {
97 ConfigurationPhase requiredPhase = null;
98 if (condition instanceof ConfigurationCondition) {
99 requiredPhase = ((ConfigurationCondition) condition).getConfigurationPhase();
100 }
101 if (requiredPhase == null || requiredPhase == phase) {
102 if (!condition.matches(this.context, metadata)) {
103 return true;
104 }
105 }
106 }
107
108 return false;
109 }
110
111 @SuppressWarnings("unchecked")
112 private List<String[]> getConditionClasses(AnnotatedTypeMetadata metadata) {
113 MultiValueMap<String, Object> attributes = metadata.getAllAnnotationAttributes(Conditional.class.getName(), true);
114 Object values = (attributes != null ? attributes.get("value") : null);
115 return (List<String[]>) (values != null ? values : Collections.emptyList());
116 }
117
118 private Condition getCondition(String conditionClassName, ClassLoader classloader) {
119 Class<?> conditionClass = ClassUtils.resolveClassName(conditionClassName, classloader);
120 return (Condition) BeanUtils.instantiateClass(conditionClass);
121 }
122
123
124
125
126
127 private static class ConditionContextImpl implements ConditionContext {
128
129 private final BeanDefinitionRegistry registry;
130
131 private final ConfigurableListableBeanFactory beanFactory;
132
133 private final Environment environment;
134
135 private final ResourceLoader resourceLoader;
136
137 public ConditionContextImpl(BeanDefinitionRegistry registry, Environment environment, ResourceLoader resourceLoader) {
138 this.registry = registry;
139 this.beanFactory = deduceBeanFactory(registry);
140 this.environment = (environment != null ? environment : deduceEnvironment(registry));
141 this.resourceLoader = (resourceLoader != null ? resourceLoader : deduceResourceLoader(registry));
142 }
143
144 private ConfigurableListableBeanFactory deduceBeanFactory(BeanDefinitionRegistry source) {
145 if (source instanceof ConfigurableListableBeanFactory) {
146 return (ConfigurableListableBeanFactory) source;
147 }
148 if (source instanceof ConfigurableApplicationContext) {
149 return (((ConfigurableApplicationContext) source).getBeanFactory());
150 }
151 return null;
152 }
153
154 private Environment deduceEnvironment(BeanDefinitionRegistry source) {
155 if (source instanceof EnvironmentCapable) {
156 return ((EnvironmentCapable) source).getEnvironment();
157 }
158 return null;
159 }
160
161 private ResourceLoader deduceResourceLoader(BeanDefinitionRegistry source) {
162 if (source instanceof ResourceLoader) {
163 return (ResourceLoader) source;
164 }
165 return null;
166 }
167
168 @Override
169 public BeanDefinitionRegistry getRegistry() {
170 return this.registry;
171 }
172
173 @Override
174 public ConfigurableListableBeanFactory getBeanFactory() {
175 return this.beanFactory;
176 }
177
178 @Override
179 public Environment getEnvironment() {
180 return this.environment;
181 }
182
183 @Override
184 public ResourceLoader getResourceLoader() {
185 return this.resourceLoader;
186 }
187
188 @Override
189 public ClassLoader getClassLoader() {
190 if (this.resourceLoader != null) {
191 return this.resourceLoader.getClassLoader();
192 }
193 if (this.beanFactory != null) {
194 return this.beanFactory.getBeanClassLoader();
195 }
196 return null;
197 }
198 }
199
200 }