通过@Conditional注解可以根据代码中设置的条件装载不同的bean,在设置条件注解之前,先要把装载的bean类去实现Condition接口,然后对该实现接口的类设置是否装载的条件。
1 配合@Bean注解
1.1 创建Bean对象
@Data
public class Person {
private String name;
private Integer age;
public Person(String name, Integer age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Person{" + "name='" + name + '\'' + ", age=" + age + '}';
}
}
1.2 实现Condition接口
这里根据系统环境来决定是否注入Bean。
public class LinuxCondition implements Condition {
@Override
public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
Environment environment = conditionContext.getEnvironment();
String property = environment.getProperty("os.name");
if (property.contains("Linux")){
return true;
}
return false;
}
}
public class WindowsCondition implements Condition {
/**
* @param conditionContext:判断条件能使用的上下文环境
* @param annotatedTypeMetadata:注解所在位置的注释信息
* */
@Override
public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
//获取ioc使用的beanFactory
ConfigurableListableBeanFactory beanFactory = conditionContext.getBeanFactory();
//获取类加载器
ClassLoader classLoader = conditionContext.getClassLoader();
//获取当前环境信息
Environment environment = conditionContext.getEnvironment();
//获取bean定义的注册类
BeanDefinitionRegistry registry = conditionContext.getRegistry();
//获得当前系统名
String property = environment.getProperty("os.name");
//包含Windows则说明是windows系统,返回true
if (property.contains("Windows")){
return true;
}
return false;
}
}
1.3 使用@Conditional注解
@Configuration
@ComponentScan("com.test")
@Scope("prototype")
public class AppConfig {
@Bean(name = "Windows")
@Conditional({WindowsCondition.class})
public Person person1(){
return new Person("Windows",62);
}
@Bean("Linux")
@Conditional({LinuxCondition.class})
public Person person2(){
return new Person("Linux",48);
}
}
这样在Linux环境中调用person2就会提示错误。
2 配合@Component实现根据yml配置,加载不同的实现
2.1 定义接口
public interface ReceiveAnnouncementService {
/**
* @description 接收信息
* @param
* @return String
*/
String receiveAnnouncement();
}
2.2 定义多个实现和对应的Condition
在每个Condition中根据yml的配置来确定是否将该实例注册到Spring容器中。
- 通过MQ方式
public class ReceiveAnnouncementByMQCondition implements Condition {
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
Environment environment = context.getEnvironment();
String property = environment.getProperty("receive-type");
return Constants.RECEIVE_TYPE_MQ.equals(property);
}
}
@Component
@Conditional({ReceiveAnnouncementByMQCondition.class})
@Slf4j
public class ReceiveAnnouncementServiceByMQImpl implements ReceiveAnnouncementService {
@Override
public String receiveAnnouncement() {
log.info("使用MQ接收消息")
return null;
}
}
- 通过MYSQL方式
public class ReceiveAnnouncementByMySQLCondition implements Condition {
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
Environment environment = context.getEnvironment();
String property = environment.getProperty("receive-type");
return Constants.RECEIVE_TYPE_MYSQL.equals(property);
}
}
@Component
@Conditional({ReceiveAnnouncementByMySQLCondition.class})
@Slf4j
public class ReceiveAnnouncementServiceByMySQLImpl implements ReceiveAnnouncementService {
@Override
public String receiveAnnouncement() {
log.info("使用MySQL接收消息")
return null;
}
}
- yml文件
receive-type: MQ
- 调用类
这里使用时,会直接根据yml中的配置获取到具体的receiveService
@Component
@EnableScheduling
@EnableAsync
@Slf4j
public class MultiThreadScheduleAnalyseTask {
@Autowired
private ReceiveAnnouncementService receiveService;
@Scheduled(cron = "0/5 * * * * ?")
@Async
public void receiveAnnouncement() {
String msg= receiveService.receiveAnnouncement();
}









网友评论