根据一些任意的系统状态,有条件地启用或禁用一个完整的 @Configuration 类,甚至是个别的 @Bean 方法,往往是很有用的。一个常见的例子是使用 @Profile 注解来激活 Bean,只有在 Spring 环境中启用了特定的配置文件时(详见 Bean 定义配置文件)。
@Profile 注解实际上是通过使用一个更灵活的注解 @Conditional 来实现的。@Conditional 注解指出了特定的 org.springframework.context.annotation.Condition
实现,在注册一个 @Bean 之前应该参考这些实现。
Condition 接口的实现提供了一个 matches(...)
方法,它返回 true 或 false。例如,下面的列表显示了用于 @Profile 的实际 Condition 实现。
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
// 读取 @Profile 注解属性
MultiValueMap<String, Object> attrs = metadata.getAllAnnotationAttributes(Profile.class.getName());
if (attrs != null) {
for (Object value : attrs.get("value")) {
if (context.getEnvironment().acceptsProfiles(((String[]) value))) {
return true;
}
}
return false;
}
return true;
}
简单说:你的开发环境是 dev, 在配置文件中 application.properties 标识如下
spring.profiles.active=dev
但是你想要一个配置类只能在 prod 中才能生效,只需要这样做
package cn.mrcode.study.springdocsread.web;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.context.annotation.Scope;
/**
* @author mrcode
*/
@Configuration
@Profile("prod") // 这里指定生效的环境
public class AppConfig {
@Bean
@Scope("prototype")
public Command asyncCommand() {
Command command = new Command();
// 根据需要在这里注入依赖性
return command;
}
@Bean
public CommandManager commandManager() {
System.out.println("xcc");
// 用 createCommand() 返回 CommandManager 的新匿名实现。
// 重载以返回一个新的 多例的 Command 对象
return new CommandManager() {
protected Command createCommand() {
return asyncCommand();
}
};
}
}
有关更多细节,请参见 @Conditional javadoc。