【spring注解驱动开发】- 自动装配 - @Profile

本博客demo源码地址
https://github.com/suchahaerkang/spring-annotation.git

1 @Profile的作用

@Profile的作用:切换不同的环境,可以动态的将不同的组件注册到容器中去
现在有这么一个需求,我们都知道我们在开发项目的时候一般都会有开发(dev),测试(test)和生产(prod)环境。每个环境的数据源都不一样,我们现在怎么实现只用切换环境,相应的组件将动态的注册到容器呢?
下面开始写代码
首先向项目中引入数据源的包,这里我们就用c3p0。然后引入一个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>

写个配置类,将容器中注册三个组件(开发数据源 devDataSource,测试数据源testDataSource,生成数据源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;
    }
}

默认情况下这三个数据源都将会注册到容器中去
写个测试用例

@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);
    }
}

运行结果
在这里插入图片描述
测试结果可以看出,三个数据源都注册进容器了,但是这不是我们想要的,我们是想要在什么样的环境就注册什么样的数据源。下面我们通过@Profile注解来实现这个功能,加上@Profile注解的配置类

/**
 * @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 激活环境的两种方式

1)使用命令行动态参数,在虚拟机参数位置加上'-Dspring.profiles.active=dev'
在这里插入图片描述
运行结果
在这里插入图片描述
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);
    }
}

运行结果
在这里插入图片描述

发布了78 篇原创文章 · 获赞 32 · 访问量 9万+

猜你喜欢

转载自blog.csdn.net/suchahaerkang/article/details/104730490