[Spring] annotation-driven development - automatic assembly - @Profile

This blog demo source address
https://github.com/suchahaerkang/spring-annotation.git

1 @Profile role

@Profile的作用:切换不同的环境,可以动态的将不同的组件注册到容器中去
Now there is such a demand, we all know that we in the development of the project when the general will have to develop (dev), test (test) and production (prod) environment. Each environment data sources are not the same, how we realize now only switched environment, the respective components will be dynamically registered with the container it?
Let's start writing code
first introduced packet data source to the project, here we use c3p0. It is then introduced into a driver package mysql

<!-- https://mvnrepository.com/artifact/c3p0/c3p0 -->
<dependency>
	<groupId>c3p0</groupId>
	<artifactId>c3p0</artifactId>
	<version>0.9.1.2</version>
</dependency>

<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
	<groupId>mysql</groupId>
	<artifactId>mysql-connector-java</artifactId>
	<version>5.1.44</version>
</dependency>

Write a configuration class, the three components of the container register (source data developed devDataSource, test data source testDataSource, generates a data source prodDataSource)

/**
 * @description:
 * @author: sukang
 * @date: 2020-03-08 12:40
 */
@PropertySource(value = {"classpath:/db.properties"})
@Configuration
public class MainConfigOfProfile {

    @Value("${database.username}")
    private String userName;

    @Value("${database.password}")
    private String password;

    @Value("${database.driver}")
    private String driver;

    @Bean("devDataSource")
    public DataSource dataSourceOfDev() throws PropertyVetoException {
        ComboPooledDataSource dataSource = new ComboPooledDataSource();
        dataSource.setJdbcUrl("http://localhost:3306/dev");
        dataSource.setUser(userName);
        dataSource.setPassword(password);
        dataSource.setDriverClass(driver);
        return dataSource;
    }

    @Bean("testDataSource")
    public DataSource dataSourceOfTest() throws PropertyVetoException {
        ComboPooledDataSource dataSource = new ComboPooledDataSource();
        dataSource.setJdbcUrl("http://localhost:3306/test");
        dataSource.setUser(userName);
        dataSource.setPassword(password);
        dataSource.setDriverClass(driver);
        return dataSource;
    }

    @Bean("prodDataSource")
    public DataSource dataSourceOfProd() throws PropertyVetoException {
        ComboPooledDataSource dataSource = new ComboPooledDataSource();
        dataSource.setJdbcUrl("http://localhost:3306/prod");
        dataSource.setUser(userName);
        dataSource.setPassword(password);
        dataSource.setDriverClass(driver);
        return dataSource;
    }
}

By default, these three data sources will be registered to the container to
write test cases

@Test
public void test01(){
    //创建容器
    ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfigOfProfile.class);
    //获取容器中组件为DataSource的所有名字
    String[] beanNames = applicationContext.getBeanNamesForType(DataSource.class);

    for (String name : beanNames) {
        System.out.println(name);
    }
}

Operating results
Here Insert Picture Description
test results can be seen, three data sources are registered into the container, but this is not what we want, we are in what kind of environment you want to register what kind of data source. Let us achieve this by @Profile notes, plus @Profile annotated class configuration

/**
 * @description:
 * @author: sukang
 * @date: 2020-03-08 12:40
 */
@PropertySource(value = {"classpath:/db.properties"})
@Configuration
public class MainConfigOfProfile {

    @Value("${database.username}")
    private String userName;

    @Value("${database.password}")
    private String password;

    @Value("${database.driver}")
    private String driver;

    @Profile("dev")
    @Bean("devDataSource")
    public DataSource dataSourceOfDev() throws PropertyVetoException {
        ComboPooledDataSource dataSource = new ComboPooledDataSource();
        dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/dev");
        dataSource.setUser(userName);
        dataSource.setPassword(password);
        dataSource.setDriverClass(driver);
        return dataSource;
    }

    @Profile("test")
    @Bean("testDataSource")
    public DataSource dataSourceOfTest() throws PropertyVetoException {
        ComboPooledDataSource dataSource = new ComboPooledDataSource();
        dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/test");
        dataSource.setUser(userName);
        dataSource.setPassword(password);
        dataSource.setDriverClass(driver);
        return dataSource;
    }

    @Profile("prod")
    @Bean("prodDataSource")
    public DataSource dataSourceOfProd() throws PropertyVetoException {
        ComboPooledDataSource dataSource = new ComboPooledDataSource();
        dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/prod");
        dataSource.setUser(userName);
        dataSource.setPassword(password);
        dataSource.setDriverClass(driver);
        return dataSource;
    }
}

在配置类中加上@Profile之后,还没有效果,必须在启动启动容器的时候激活某个环境才能生效

2 are two ways to activate the environment

1)使用命令行动态参数,在虚拟机参数位置加上'-Dspring.profiles.active=dev'
Here Insert Picture Description
operation result
Here Insert Picture Description
2)另外一种方法是通过写代码的方式

@Test
public void test02(){
    //创建容器调用无参构造函数
    AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
    //激活测试环境
    applicationContext.getEnvironment().setActiveProfiles("test");
    //注册MainConfigOfProfile组件
    applicationContext.register(MainConfigOfProfile.class);
    //刷新容器
    applicationContext.refresh();

    //获取容器中组件为DataSource的所有名字
    String[] beanNames = applicationContext.getBeanNamesForType(DataSource.class);

    for (String name : beanNames) {
        System.out.println(name);
    }
}

operation result
Here Insert Picture Description

Published 78 original articles · won praise 32 · views 90000 +

Guess you like

Origin blog.csdn.net/suchahaerkang/article/details/104730490