根据一些任意的系统状态,有条件地启用或禁用一个完整的 @Configuration 类,甚至是个别的 @Bean 方法,往往是很有用的。一个常见的例子是使用 @Profile 注解来激活 Bean,只有在 Spring 环境中启用了特定的配置文件时(详见 Bean 定义配置文件)。
@Profile 注解实际上是通过使用一个更灵活的注解 @Conditional 来实现的。@Conditional 注解指出了特定的 org.springframework.context.annotation.Condition实现,在注册一个 @Bean 之前应该参考这些实现。
Condition 接口的实现提供了一个 matches(...) 方法,它返回 true 或 false。例如,下面的列表显示了用于 @Profile 的实际 Condition 实现。
@Overridepublic 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;}@Beanpublic CommandManager commandManager() {System.out.println("xcc");// 用 createCommand() 返回 CommandManager 的新匿名实现。// 重载以返回一个新的 多例的 Command 对象return new CommandManager() {protected Command createCommand() {return asyncCommand();}};}}
有关更多细节,请参见 @Conditional javadoc。
