官方文档
ConfigurationCondition
ConfigurationCondition.ConfigurationPhase
源码解析
package org.springframework.context.annotation;
/**
* 与@Configuration一起使用时提供更精细控制的条件,允许某些Condition在匹配时根据配置阶段进行调整
*/
public interface ConfigurationCondition extends Condition {
/**
* 返回判断Condition的ConfigurationCondition.ConfigurationPhase(配置阶段)
*/
ConfigurationPhase getConfigurationPhase();
/**
* 可以判断Condition的不同配置阶段
*/
enum ConfigurationPhase {
/**
* @Configuration注解的类解析的阶段判断Condition
* 如果Condition不匹配,则@Configuration注解的类不会加载
*/
PARSE_CONFIGURATION,
/**
* @Configuration注解的类实例化为bean的阶段判断Condition
* 无论Condition是否匹配,@Configuration注解的类都会加载,且类加载先于Condition判断
*/
REGISTER_BEAN
}
}
代码测试
IService.java
public interface IService {
String hello();
}
HelloService.java
@Service
@Conditional(HelloCondition.class)
public class HelloService implements IService {
@Override
public String hello() {
return "hello";
}
}
application.properties
com.example.demo.a=true
HelloController.java
@RestController("/")
public class HelloController {
@Autowired(required = false)
private IService service;
@GetMapping("hello")
public String hello() {
try {
// 查看内存中已加载的类
Field f=ClassLoader.class.getDeclaredField("classes");
f.setAccessible(true);
Vector classes=(Vector)f.get(ClassLoader.getSystemClassLoader());
System.out.println(check(classes));
} catch (Exception e){
e.printStackTrace();
}
return "hello";
}
private String check(Vector classes) {
for (Object ss : classes) {
if (((Class) ss).getName().equals("com.example.demo.service.impl.HelloService")) {
return "已加载com.example.demo.service.impl.HelloService";
}
}
return "未加载com.example.demo.service.impl.HelloService";
}
}
HelloCondition.java
public class HelloCondition extends AnyNestedCondition {
public HelloCondition() {
super(ConfigurationPhase.PARSE_CONFIGURATION);
}
@ConditionalOnProperty(value = "com.example.demo.a", havingValue = "false")
static class demoA {
}
}
当com.example.demo.a匹配true时,此时Condition匹配,HelloService将会实例化
当ConfigurationPhase设置为PARSE_CONFIGURATION时,测试结果为:
已加载com.example.demo.service.impl.HelloService
当ConfigurationPhase设置为REGISTER_BEAN时,测试结果为:
已加载com.example.demo.service.impl.HelloService
当com.example.demo.a匹配false时,此时Condition不匹配,HelloService不会实例化
当ConfigurationPhase设置为PARSE_CONFIGURATION时,测试结果为:
未加载com.example.demo.service.impl.HelloService
当ConfigurationPhase设置为REGISTER_BEAN时,测试结果为:
已加载com.example.demo.service.impl.HelloService
综上所述,只有Condition不匹配,且Condition判断的阶段,即ConfigurationPhase设置为PARSE_CONFIGURATION时,@Configuration(例子是@Service,相同效果)注解的类将不会加载到内存中。