Spring Boot2.x-06Spring Boot基础-使用@Conditional注解根据特定的条件装配bean
概述
假设在某些特定的场景下,希望根据特定的条件去加载某个或某些bean,我们可以使用@Condtional注解, Spring 4.0的时候加入的这个注解。
例子
假设,我们在配置了数据库的几个属性时,才去实例化bean,否则不初始化这个bean。这个例子可能不太合适,权当理解这个注解的用法了
Step1 实现Condition接口,重写matches方法
package com.artisan.springbootmaster.conditional;
import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.env.Environment;
import org.springframework.core.type.AnnotatedTypeMetadata;
/**
*
*/
public class DatabaseCondtional implements Condition {
/**
* 数据库bean的装配条件
*
* @param context 上下文
* @param metadata 注释类型的元数据
* @return true 装配Bean ,否则不装配
*/
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
// 根据context取出对应的Env信息
Environment environment = context.getEnvironment();
// 判断属性文件是否存在对应的数据库配置
return environment.containsProperty("datasource.driverName")
&& environment.containsProperty("datasource.url")
&& environment.containsProperty("datasource.username")
&& environment.containsProperty("datasource.password");
}
}
Step2 在对应的@Bean上使用@Conditional注解
package com.artisan.springbootmaster.conditional;
import org.apache.commons.dbcp2.BasicDataSourceFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.*;
import javax.sql.DataSource;
import java.util.Properties;
@Configuration
@PropertySource(value = "classpath:jdbc.properties",ignoreResourceNotFound = true)
public class Config {
@Bean(name = "datasource" ,destroyMethod = "close")
@Conditional(DatabaseCondtional.class)
public DataSource initDataSource(
@Value("${datasource.driverName}") String driver,
@Value("${datasource.url}") String url,
@Value("${datasource.username}") String username,
@Value("${datasource.password}") String password){
System.out.println("driver:" + driver + "\n url:" + url+ "\n username:" + username
+ "\n password:" + password) ;
Properties properties = new Properties();
properties.setProperty("driver",driver);
properties.setProperty("url",url);
properties.setProperty("username",username);
properties.setProperty("password",password);
DataSource dataSource = null;
try {
dataSource = BasicDataSourceFactory.createDataSource(properties);
} catch (Exception e) {
e.printStackTrace();
}
return dataSource;
}
}
测试
package com.artisan.springbootmaster.conditional;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import javax.sql.DataSource;
public class Test {
public static void main(String[] args){
ApplicationContext ctx = new AnnotationConfigApplicationContext(Config.class);
//DataSource dataSource = (DataSource) ctx.getBean("datasource");
DataSource dataSource = ctx.getBean(DataSource.class);
System.out.println("datasource:" + dataSource);
}
}
结果
当我们修改掉某个属性后,DatabaseCondtional#matches方法肯定返回false, 按照推测,该bean不会被加载到IoC容器中,我们来验证下
将 datasource.driverName 改为 datasource.driverName1
重新测试,抛出了异常。
因为我们在获取bean的时候,IoC容器中并不存在该bean。