Using Spring @Conditional annotation you can conditionally register a component. With @Conditional annotation you need to specify a condition and the component is registered only if the condition is true.
For specifying the condition you need to implement org.springframework.context.annotation.Condition
interface.
Where to use @Conditional annotation
The @Conditional annotation may be used in one of the following ways:
- As a type-level annotation on any class directly or indirectly annotated with @Component, including @Configuration classes. If a @Configuration class is marked with @Conditional, all of the @Bean methods, @Import annotations, and @ComponentScan annotations associated with that class will be subject to the conditions.
- As a meta-annotation, for the purpose of composing custom stereotype annotations. You can see @Profile annotation in Spring framework uses @Conditional annotation.
@Target(value={TYPE,METHOD}) @Retention(value=RUNTIME) @Documented @Conditional(value=org.springframework.context.annotation.ProfileCondition.class) public @interface Profile
- As a method-level annotation on any @Bean method
Condition interface
org.springframework.context.annotation.Condition is a functional interface with a single abstract method matches().
matches(ConditionContext context, AnnotatedTypeMetadata metadata)
matches() method has to be implemented and the condition checked with in this method returns true or false. If true is returned then the component is registered otherwise not.
Spring @Conditional annotation examples
With this basic knowledge about @Conditional annotation and Condition interface let’s see an example depicting the usage.
What we need to do is to register either a "dev" datasource or "prod" datasource based on the value in the properties file.
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=prodConfig classes
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(); } }Condition class implementations
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 interface
public interface UserDAO { public void getUsers(); }UserDAOImpl class
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()); } }Class to run this example.
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(); } }Output
In getUsers method Driver class name- oracle.jdbc.driver.OracleDriver DB User- sysuser DB URL- jdbc:oracle:thin:@192.156.134.111:1523/XEPDB1
As you can see prodDataSource Bean is registered because db.env=prod is set. In db.properties if you change db.env=dev and run it then devDataSource Bean is registered. With that output is
In getUsers method Driver class name- oracle.jdbc.driver.OracleDriver DB User- test DB URL- jdbc:oracle:thin:@localhost:1521/XEPDB1
That's all for the topic Spring @Conditional Annotation. If something is missing or you have something to share about the topic please write a comment.
You may also like
- Spring @Scope Annotation
- Spring @Value Annotation
- Spring Boot Properties File: @ConfigurationProperties Example
- Java HashMap With Examples
- Java Stream Collectors averagingInt(), averagingLong(), averagingDouble()
- ReentrantLock in Java With Examples
- Parquet File Format in Hadoop
- tempfile Module in Python - Create Temporary File and Directory
No comments:
Post a Comment