25、自動裝配[email protected]根據環境註冊bean
阿新 • • 發佈:2018-11-30
25、自動裝配[email protected]根據環境註冊bean
- 指定元件在哪個環境的情況下才能被註冊到容器中
- 加了環境標識的,只有這個環境被啟用才能註冊到元件中
- 預設是default環境
- 寫在類上,整個配置類的啟用的時候才能生效
- 沒有標註環境標識的bean,在任何環境下都是載入的
package org.springframework.context.annotation; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import org.springframework.core.env.AbstractEnvironment; import org.springframework.core.env.ConfigurableEnvironment; import org.springframework.core.env.Profiles; @Target({ElementType.TYPE, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Documented @Conditional(ProfileCondition.class) public @interface Profile { /** * 指定元件在哪個環境的情況下才能被註冊到容器中 * The set of profiles for which the annotated component should be registered. */ String[] value(); }
25.1 實現
package com.hw.springannotation.config; import com.mchange.v2.c3p0.ComboPooledDataSource; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.EmbeddedValueResolverAware; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Profile; import org.springframework.context.annotation.PropertySource; import org.springframework.stereotype.Component; import org.springframework.util.StringValueResolver; import javax.sql.DataSource; import java.beans.PropertyVetoException; /** * @Description Profile * @Author hw * @Date 2018/11/29 19:25 * @Version 1.0 */ @Component @PropertySource(value = {"classpath:/datasource.properties"}) public class MainConfigOfProfile implements EmbeddedValueResolverAware { @Value("${db.username}") private String username; private String driveClassName; private StringValueResolver resolver; public void setEmbeddedValueResolver(StringValueResolver resolver) { this.resolver = resolver; this.driveClassName = this.resolver.resolveStringValue("${db.driveClassName}"); } @Profile("default") @Bean public DataSource dataSourceTest(@Value("${db.password}") String password) throws PropertyVetoException { ComboPooledDataSource dataSource = new ComboPooledDataSource(); dataSource.setUser(username); dataSource.setPassword(password); dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/test"); dataSource.setDriverClass(driveClassName); return dataSource; } @Profile("dev") @Bean public DataSource dataSourceDev(@Value("${db.password}") String password) throws PropertyVetoException { ComboPooledDataSource dataSource = new ComboPooledDataSource(); dataSource.setUser(username); dataSource.setPassword(password); dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/mysql"); dataSource.setDriverClass(driveClassName); return dataSource; } @Profile("prod") @Bean public DataSource dataSourceProd(@Value("${db.password}") String password) throws PropertyVetoException { ComboPooledDataSource dataSource = new ComboPooledDataSource(); dataSource.setUser(username); dataSource.setPassword(password); dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/qm_dmp"); dataSource.setDriverClass(driveClassName); return dataSource; } }
執行:
25.2 切換環境-使用命令列動態引數
- 在執行時指定
-Dspring.profiles.active=prod
25.3 切換環境-使用程式碼的方式
- 之前使用的是有參構造器,配置載入完,容器就重新整理了,所以使用無參構造器
public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
this();
register(annotatedClasses);
refresh();
}
步驟
- 構造IOC容器
- 設定需要啟用的環境
- 注入配置類
- 啟動重新整理容器
@Test
public void test() {
// 1. 構造IOC容器
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
// 2. 設定需要啟用的環境(可以同時啟用多個)
applicationContext.getEnvironment().setActiveProfiles("test", "dev");
// 3. 注入配置類
applicationContext.register(MainConfigOfProfile.class);
// 4. 啟動重新整理容器
applicationContext.refresh();
String[] definitionNames = applicationContext.getBeanDefinitionNames();
for (String name : definitionNames) {
System.out.println(name);
}
}