Spring @条件注释
时间:2020-01-09 10:44:33 来源:igfitidea点击:
使用Spring @Conditional注释,可以有条件地注册组件。使用@Conditional注释时,我们需要指定条件,并且仅在条件为true时才注册组件。
为了指定条件,我们需要实现org.springframework.context.annotation.Condition接口。
在哪里使用@Conditional注释
@Conditional注释可以通过以下方式之一使用:
- 作为任何直接或者间接用@Component注释的类的类型级别注释,包括@Configuration类。如果@Configuration类标记有@Conditional,则与该类关联的所有@Bean方法,@ Import注释和@ComponentScan注释将受条件限制。
- 作为元注释,用于组成自定义构造型注释。我们可以在Spring框架中使用@Conditional注释看到@Profile注释。
@Target(value={TYPE,METHOD}) @Retention(value=RUNTIME) @Documented @Conditional(value=org.springframework.context.annotation.ProfileCondition.class) public @interface Profile
- 作为任何@Bean方法的方法级注释
条件界面
org.springframework.context.annotation.Condition是具有单个抽象方法match()的功能接口。
matches(ConditionContext context, AnnotatedTypeMetadata metadata)
必须实现match()方法,并且用此方法检查的条件返回true或者false。如果返回true,则该组件已注册,否则未注册。
Spring @Conditional注释示例
有了有关@Conditional注释和Condition接口的基本知识,我们来看一个描述用法的示例。
我们需要做的是根据属性文件中的值注册" dev"数据源或者" prod"数据源。
src / main / resources / db.properties
#DB configuration for dev db.dev.url=jdbc:oracle:thin:@localhost:1521/XEPDB1 db.dev.user=test db.dev.password=test db.dev.driver_class_name=oracle.jdbc.driver.OracleDriver #DB configuration for prod db.prod.url=jdbc:oracle:thin:@192.156.134.111:1523/XEPDB1 db.prod.user=sysuser db.prod.password=test db.prod.driver_class_name=oracle.jdbc.driver.OracleDriver db.env=prod
配置类
import org.apache.commons.dbcp2.BasicDataSource; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Conditional; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.PropertySource; import org.springframework.core.env.Environment; @Configuration("dbConfig") @PropertySource(value="classpath:properties/db.properties") public class DBConfiguration { @Autowired private Environment env; @Bean @Conditional(DevDBCondition.class) public BasicDataSource devDataSource() { BasicDataSource ds = new BasicDataSource(); ds.setDriverClassName(env.getProperty("db.dev.driver_class_name")); ds.setUrl(env.getProperty("db.dev.url")); ds.setUsername(env.getProperty("db.dev.user")); ds.setPassword(env.getProperty("db.dev.password")); return ds; } @Bean @Conditional(ProdDBCondition.class) public BasicDataSource prodDataSource() { BasicDataSource ds = new BasicDataSource(); ds.setDriverClassName(env.getProperty("db.prod.driver_class_name")); ds.setUrl(env.getProperty("db.prod.url")); ds.setUsername(env.getProperty("db.prod.user")); ds.setPassword(env.getProperty("db.prod.password")); return ds; } }
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class UserConfig { @Bean public UserDAO userDAO() { return new UserDAOImpl(); } }
条件类的实现
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 DevDBCondition implements Condition { @Override public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { Environment env = context.getEnvironment(); return env.getProperty("db.env").equals("dev"); } }
public class ProdDBCondition implements Condition { @Override public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { Environment env = context.getEnvironment(); return env.getProperty("db.env").equals("prod"); } }
UserDAO界面
public interface UserDAO { public void getUsers(); }
UserDAOImpl类
public class UserDAOImpl implements UserDAO { @Autowired BasicDataSource ds; public void getUsers() { System.out.println("In getUsers method"); System.out.println("Driver class name- " + ds.getDriverClassName()); System.out.println("DB User- " + ds.getUsername()); System.out.println("DB URL- " + ds.getUrl()); } }
运行该示例的类。
public class App { public static void main(String[] args) { AbstractApplicationContext context = new AnnotationConfigApplicationContext(DBConfiguration.class, UserConfig.class); UserDAO userDAO = context.getBean("userDAO", UserDAOImpl.class); userDAO.getUsers(); context.close(); } }
输出:
In getUsers method Driver class name- oracle.jdbc.driver.OracleDriver DB User- sysuser DB URL- jdbc:oracle:thin:@192.156.134.111:1523/XEPDB1
如我们所见,由于设置了db.env = prod,因此prodDataSource Bean已注册。如果我们更改db.env = dev并运行它,则在db.properties中,将注册devDataSource Bean。与该输出是
In getUsers method Driver class name- oracle.jdbc.driver.OracleDriver DB User- test DB URL- jdbc:oracle:thin:@localhost:1521/XEPDB1