рд╕реНрдкреНрд░рд┐рдВрдЧ рдмреВрдЯ рдСрдЯреЛ-рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдХреИрд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ

рдХреА рджреБрдирд┐рдпрд╛ рдореЗрдВ рджреАрдк рд╡рд┐рд╕рд░реНрдЬрди рд╕реНрдкреНрд░рд┐рдВрдЧ рдмреВрдЯ @Conditional рдПрдиреЛрдЯреЗрд╢рди рдХреА рдЕрдЪреНрдЫреА рддрд░рд╣ рд╕реЗ рд╡рд┐рдХрд╕рд┐рдд рдЙрджрд╛рд╣рд░рдг рдХреЗ рд╕рд╛рде рдореЛрдВрдЧреЛ рдФрд░ MySQL рдбреЗрдЯрд╛рдмреЗрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рд╡рд░реНрдЧ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди ред


рдореЗрд░реА рдкреЛрд╕реНрдЯ рдореЗрдВ тАЬ рд╕реНрдкреНрд░рд┐рдВрдЧ рдмреВрдЯ рдХреНрдпреЛрдВ? "рд╕реНрдкреНрд░рд┐рдВрдЧ рдмреВрдЯ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЗ рдирд┐рд░реНрдорд╛рдг рдХреА рд╕рдореАрдХреНрд╖рд╛ рдХреА рдЧрдИ, рдЬрд┐рд╕рдореЗрдВ рд╕реЗ рдЖрдк рд╢рд╛рдпрдж рд╣реА рд╕рдордЭ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рдкрд░реНрджреЗ рдХреЗ рдкреАрдЫреЗ рдХреНрдпрд╛ рдЪрд▓ рд░рд╣рд╛ рд╣реИред рд╢рд╛рдпрдж рдЖрдк рд╕реНрдкреНрд░рд┐рдВрдЧ рдмреВрдЯ рдСрдЯреЛ-рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдЬрд╛рджреВ рдХреЛ рд╕рдордЭрдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВред


рдЗрд╕рд╕реЗ рдкрд╣рд▓реЗ, рдЖрдкрдХреЛ рд╡рд╕рдВрдд рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ @Conditional рдПрдиреЛрдЯреЗрд╢рди рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╕реАрдЦрдирд╛ рдЪрд╛рд╣рд┐рдП , рдЬреЛ рд╕рднреА рд╕реНрдкреНрд░рд┐рдВрдЧ рдмреВрдЯ рдСрдЯреЛ-рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдЬрд╛рджреВ рдкрд░ рдирд┐рд░реНрднрд░ рдХрд░рддрд╛ рд╣реИред


рдЕрдиреНрд╡реЗрд╖рдг @Conditional рд╕реБрд╡рд┐рдзрд╛рдПрдБ


рд╡рд╕рдВрдд рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдЕрдиреБрдкреНрд░рдпреЛрдЧреЛрдВ рдХреЛ рд╡рд┐рдХрд╕рд┐рдд рдХрд░рддреЗ рд╕рдордп, рдЖрдкрдХреЛ рд╕реЗрдо рдШрдЯрдХреЛрдВ рдХреЛ рд╕рд╢рд░реНрдд рд░реВрдк рд╕реЗ рдкрдВрдЬреАрдХреГрдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛ рд╕рдХрддреА рд╣реИред


рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЖрдк рдбреЗрдЯрд╛рд╕реЛрд░реНрд╕ рдмреАрди рдХреЛ рдкрдВрдЬреАрдХреГрдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдЬреЛ рдХрд┐ рдбреАрдИрд╡реА рдбреЗрдЯрд╛рдмреЗрд╕ рдХреЛ рдЗрдВрдЧрд┐рдд рдХрд░рддрд╛ рд╣реИ рдЬрдм рдПрдкреНрд▓рд┐рдХреЗрд╢рди рд╕реНрдерд╛рдиреАрдп рд░реВрдк рд╕реЗ рд╢реБрд░реВ рд╣реЛрддрд╛ рд╣реИ, рдФрд░ рдЙрддреНрдкрд╛рджрди рд╡рд╛рддрд╛рд╡рд░рдг рдореЗрдВ рдХрд╛рдо рдХрд░рддреЗ рд╕рдордп рдХрд┐рд╕реА рдЕрдиреНрдп рдкреНрд░реЛрдбрдХреНрд╢рди рдбреЗрдЯрд╛рдмреЗрд╕ рдХреЛ рдЗрдВрдЧрд┐рдд рдХрд░рддрд╛ рд╣реИред


рдЖрдк рдбреЗрдЯрд╛рдмреЗрд╕ рдХрдиреЗрдХреНрд╢рди рд╕реЗрдЯрд┐рдВрдЧреНрд╕ рдХреЛ рдЧреБрдг рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдкрд░реНрдпрд╛рд╡рд░рдг рд╕реЗ рдореЗрд▓ рдЦрд╛рдиреЗ рд╡рд╛рд▓реА рдлрд╝рд╛рдЗрд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдЬрдм рднреА рдЖрдкрдХреЛ рдПрдХ рдЕрд▓рдЧ рд╡рд╛рддрд╛рд╡рд░рдг рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рдиреЗ рдФрд░ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдмрдирд╛рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ, рддреЛ рдЖрдкрдХреЛ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдХреЛ рдмрджрд▓рдирд╛ рд╣реЛрдЧрд╛ред


рдЗрд╕ рд╕рдорд╕реНрдпрд╛ рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╕реНрдкреНрд░рд┐рдВрдЧ 3.1 рдиреЗ рдкреНрд░реЛрдлрд╛рдЗрд▓ (рдкреНрд░реЛрдлрд╝рд╛рдЗрд▓) рдХреА рдЕрд╡рдзрд╛рд░рдгрд╛ рдкреЗрд╢ рдХреА ред рдЖрдк рдПрдХ рд╣реА рдкреНрд░рдХрд╛рд░ рдХреА рдХрдИ рдмреАрдиреНрд╕ рдХреЛ рдкрдВрдЬреАрдХреГрдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдЙрдиреНрд╣реЗрдВ рдПрдХ рдпрд╛ рдЕрдзрд┐рдХ рдкреНрд░реЛрдлрд╛рдЗрд▓ рдХреЗ рд╕рд╛рде рдЬреЛрдбрд╝ рд╕рдХрддреЗ рд╣реИрдВред рдЬрдм рдЖрдк рдПрдкреНрд▓рд┐рдХреЗрд╢рди рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдЖрдк рд╕рдХреНрд░рд┐рдп рдкреНрд░реЛрдлрд╛рдЗрд▓ рд╕реЗ рдЬреБрдбрд╝реЗ рдЖрд╡рд╢реНрдпрдХ рдкреНрд░реЛрдлрд╛рдЗрд▓ рдФрд░ рдШрдЯрдХреЛрдВ рдХреЛ рд╕рдХреНрд░рд┐рдп рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдФрд░ рдХреЗрд╡рд▓ рдЗрди рдкреНрд░реЛрдлрд╛рдЗрд▓ рдХреЛ рдкрдВрдЬреАрдХреГрдд рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред


@Configuration
public class AppConfig
{
     @Bean
     @Profile("DEV")
     public DataSource devDataSource() {
        ...
     }

     @Bean
     @Profile("PROD")
     public DataSource prodDataSource() {
        ...
     }
}

рдлрд┐рд░ рдЖрдк рд╕рд┐рд╕реНрдЯрдо рдкреНрд░реЙрдкрд░реНрдЯреА - Dspring.profiles.active = DEV рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд╕рдХреНрд░рд┐рдп рдкреНрд░реЛрдлрд╝рд╛рдЗрд▓ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ ред


рдпрд╣ рджреГрд╖реНрдЯрд┐рдХреЛрдг рд╕рд░рд▓ рдорд╛рдорд▓реЛрдВ рдХреЗ рд▓рд┐рдП рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ, рдЬреИрд╕реЗ рд╕рдХреНрд░рд┐рдп рдкреНрд░реЛрдлрд╛рдЗрд▓ рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдШрдЯрдХ рдкрдВрдЬреАрдХрд░рдг рдХреЛ рд╕рдХреНрд╖рдо рдпрд╛ рдЕрдХреНрд╖рдо рдХрд░рдирд╛ред рд▓реЗрдХрд┐рди рдЕрдЧрд░ рдЖрдк рдХреБрдЫ рд╕рд╢рд░реНрдд рддрд░реНрдХ рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдмреАрди рдШрдЯрдХреЛрдВ рдХреЛ рдкрдВрдЬреАрдХреГрдд рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рддреЛ рдкреНрд░реЛрдлрд╝рд╛рдЗрд▓ рджреГрд╖реНрдЯрд┐рдХреЛрдг рд╣реА рдкрд░реНрдпрд╛рдкреНрдд рдирд╣реАрдВ рд╣реИред


bean- Spring, Spring 4 @Conditional. @Conditional, , .


, , :


  • classpath
  • Spring bean ApplicationContext
  • /

, , .


, Spring's @Conditional.


, UserDAO . UserDAO, JdbcUserDAO, MySQL, MongoUserDAO, MongoDB.


JdbcUserDAO MongoUserDAO System Property, , dbType.


: java -jar myapp.jar -DdbType = MySQL, JdbcUserDAO. , : java -jar myapp.jar -DdbType = MONGO, MongoUserDAO.


JdbcUserDAO MongoUserDAO UserDAO :


public interface UserDAO
{
    List<String> getAllUserNames();
}
public class JdbcUserDAO implements UserDAO
{
    @Override
    public List<String> getAllUserNames()
    {
          System.out.println("**** Getting usernames from RDBMS *****");
          return Arrays.asList("Siva","Prasad","Reddy");
    }
}
public class MongoUserDAO implements UserDAO
{
    @Override
    public List<String> getAllUserNames()
    {
          System.out.println("**** Getting usernames from MongoDB *****");
          return Arrays.asList("Bond","James","Bond");
    }
}

Condition MySQLDatabaseTypeCondition, , System Property dbType ┬лMYSQL┬╗ :


public class MySQLDatabaseTypeCondition implements Condition
{
    @Override
    public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata metadata)
    {
        String enabledDBType = System.getProperty("dbType");
        return (enabledDBType != null && enabledDBType.equalsIgnoreCase("MYSQL"));
    }
}

Condition MongoDBDatabaseTypeCondition, , System Property dbType ┬лMONGODB┬╗ :


public class MongoDBDatabaseTypeCondition implements Condition
{
    @Override
    public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata metadata)
    {
        String enabledDBType = System.getProperty("dbType");
        return (enabledDBType != null && enabledDBType.equalsIgnoreCase("MONGODB"));
    }
}

bean- JdbcUserDAO MongoUserDAO, @Conditional :


@Configuration
public class AppConfig
{
    @Bean
    @Conditional(MySQLDatabaseTypeCondition.class)
    public UserDAO jdbcUserDAO(){
        return new JdbcUserDAO();
    }

    @Bean
    @Conditional(MongoDBDatabaseTypeCondition.class)
    public UserDAO mongoUserDAO(){
        return new MongoUserDAO();
    }
}

: java -jar myapp.jar -DdbType = MYSQL, bean- JdbcUserDAO.


System property: -DdbType = MONGODB, bean- MongoUserDAO.


, System Property.


, bean- MongoUserDAO , classpath Java MongoDB "com.mongodb.Server", , bean- JdbcUserDAO.


Condition MongoDB "com.mongodb.Server" :


public class MongoDriverPresentsCondition implements Condition
{
    @Override
    public boolean matches(ConditionContext conditionContext,AnnotatedTypeMetadata metadata)
    {
        try {
            Class.forName("com.mongodb.Server");
            return true;
        } catch (ClassNotFoundException e) {
            return false;
        }
    }
}

public class MongoDriverNotPresentsCondition implements Condition
{
    @Override
    public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata metadata)
    {
        try {
            Class.forName("com.mongodb.Server");
            return false;
        } catch (ClassNotFoundException e) {
            return true;
        }
    }
}

, bean- classpath.


bean- MongoUserDAO, Spring- UserDAO .


Condition, , - bean- , :


public class UserDAOBeanNotPresentsCondition implements Condition
{
    @Override
    public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata metadata)
    {
         UserDAO userDAO = conditionContext.getBeanFactory().getBean(UserDAO.class);
         return (userDAO == null);
    }
}

bean- MongoUserDAO, app.dbType = MONGO?


Condition :


public class MongoDbTypePropertyCondition implements Condition
{
    @Override
    public boolean matches(ConditionContext conditionContext,
    AnnotatedTypeMetadata metadata)
    {
        String dbType = conditionContext.getEnvironment()
                            .getProperty("app.dbType");
        return "MONGO".equalsIgnoreCase(dbType);
    }
}

Condition. Condition . Condition MYSQL MongoDB DatabaseType :


@Target({ ElementType.TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Conditional(DatabaseTypeCondition.class)
public @interface DatabaseType
{
    String value();
}

DatabaseTypeCondition, DatabaseType :


public class DatabaseTypeCondition implements Condition
{
    @Override
    public boolean matches(ConditionContext conditionContext,
 AnnotatedTypeMetadata metadata)
    {
        Map<String, Object> attributes = metadata.getAnnotationAttributes(DatabaseType.class.getName());
        String type = (String) attributes.get("value");
        String enabledDBType = System.getProperty("dbType","MYSQL");
        return (enabledDBType != null && type != null && enabledDBType.equalsIgnoreCase(type));
    }
}

@DatabaseType :


@Configuration
@ComponentScan
public class AppConfig
{
    @Bean
    @DatabaseType("MYSQL")
    public UserDAO jdbcUserDAO(){
        return new JdbcUserDAO();
    }

    @Bean
    @DatabaseType("MONGO")
    public UserDAO mongoUserDAO(){
        return new MongoUserDAO();
    }
}

DatabaseType dbType , , .


, , , @Conditional.


Spring Boot @Conditional bean- .


Condition, SpringBoot org.springframework.boot.autoconfigure spring-boot-autoconfigure-{version}.jar.


Spring Boot @Conditional , .


?


, .


Spring Boot AutoConfiguration


Spring Boot тАФ @EnableAutoConfiguration. , , @SpringBootApplication, , , :


@Configuration
@EnableAutoConfiguration
@ComponentScan
public class Application
{

}

@EnableAutoConfiguration Spring ApplicationContext , .


Spring Boot AutoConfiguration spring-boot-autoconfigure-{version}.jar, .


AutoConfiguration @Configuration, Spring, @EnableConfigurationProperties .


, org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration.


@Configuration
@ConditionalOnClass({ DataSource.class, EmbeddedDatabaseType.class })
@EnableConfigurationProperties(DataSourceProperties.class)
@Import({ Registrar.class, DataSourcePoolMetadataProvidersConfiguration.class })
public class DataSourceAutoConfiguration 
{
    ...
    ...
    @Conditional(DataSourceAutoConfiguration.EmbeddedDataSourceCondition.class)
    @ConditionalOnMissingBean({ DataSource.class, XADataSource.class })
    @Import(EmbeddedDataSourceConfiguration.class)
    protected static class EmbeddedConfiguration {

    }

    @Configuration
    @ConditionalOnMissingBean(DataSourceInitializer.class)
    protected static class DataSourceInitializerConfiguration {
        @Bean
        public DataSourceInitializer dataSourceInitializer() {
        return new DataSourceInitializer();
        }
    }

    @Conditional(DataSourceAutoConfiguration.NonEmbeddedDataSourceCondition.class)
    @ConditionalOnMissingBean({ DataSource.class, XADataSource.class })
    protected static class NonEmbeddedConfiguration {
        @Autowired
        private DataSourceProperties properties;

        @Bean
        @ConfigurationProperties(prefix = DataSourceProperties.PREFIX)
        public DataSource dataSource() {
            DataSourceBuilder factory = DataSourceBuilder
                    .create(this.properties.getClassLoader())
                    .driverClassName(this.properties.getDriverClassName())
                    .url(this.properties.getUrl()).username(this.properties.getUsername())
                    .password(this.properties.getPassword());
            if (this.properties.getType() != null) {
                factory.type(this.properties.getType());
            }
            return factory.build();
        }
    }
    ...
    ...
    @Configuration
    @ConditionalOnProperty(prefix = "spring.datasource", name = "jmx-enabled")
    @ConditionalOnClass(name = "org.apache.tomcat.jdbc.pool.DataSourceProxy")
    @Conditional(DataSourceAutoConfiguration.DataSourceAvailableCondition.class)
    @ConditionalOnMissingBean(name = "dataSourceMBean")
    protected static class TomcatDataSourceJmxConfiguration {
        @Bean
        public Object dataSourceMBean(DataSource dataSource) {
        ....
        ....
        }
    }
    ...
    ...
}

DataSourceAutoConfiguration @ConditionalOnClass({DataSource.class,EmbeddedDatabaseType.class}), , bean- DataSourceAutoConfiguration , DataSource.class EmbeddedDatabaseType.class classpath.


@EnableConfigurationProperties(DataSourceProperties.class), application.properties DataSourceProperties.


@ConfigurationProperties(prefix = DataSourceProperties.PREFIX)
public class DataSourceProperties implements BeanClassLoaderAware, EnvironmentAware, InitializingBean {

    public static final String PREFIX = "spring.datasource";
    ...
    ...
    private String driverClassName;
    private String url;
    private String username;
    private String password;
    ...
    //setters and getters
}

, spring.datasource.*, DataSourceProperties.


spring.datasource.url=jdbc:mysql://localhost:3306/test
spring.datasource.username=root
spring.datasource.password=secret
spring.datasource.driver-class-name=com.mysql.jdbc.Driver

bean-, SpringBoot, @ConditionalOnMissingBean, @ConditionalOnClass @ConditionalOnProperty ..


bean- ApplicationContext, .


spring-boot-autoconfigure-{version}.jar, :


  • org.springframework.boot.autoconfigure.web.DispatcherServletAutoConfiguration
  • org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration
  • org.springframework.boot.autoconfigure.data.jpa.JpaRepositoriesAutoConfiguration
  • org.springframework.boot.autoconfigure.jackson.JacksonAutoConfigurationetc, рдЗрддреНрдпрд╛рджрд┐ред

рдореБрдЭреЗ рдЙрдореНрдореАрдж рд╣реИ рдХрд┐ рдЕрдм рдЖрдкрдХреЛ рд╕рдордЭ рдореЗрдВ рдЖ рдЬрд╛рдПрдЧрд╛ рдХрд┐ рдХреИрд╕реЗ рд╕реНрдкреНрд░рд┐рдВрдЧ рдмреВрдЯ рдСрдЯреЛрдХреЙрдиреНрдлрд┐рдЧрд░реЗрд╢рди @ рдСрдЯреЛрдХреИрдбреНрдпреВрдЕрд▓ рдлреАрдЪрд░реНрд╕ рдХреЗ рд╕рд╛рде-рд╕рд╛рде рд╡рд┐рднрд┐рдиреНрди рдСрдЯреЛрдХреЙрдиреНрдлрд┐рдЧрд░реЗрд╢рди рд╡рд░реНрдЧреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ ред


All Articles