1. 程式人生 > >spring實戰-條件裝配bean

spring實戰-條件裝配bean

在做大型專案時,我們的系統會有多個執行環境,如開發人員自己的本地環境dev,測試人員的測試環境sit,上線前的預生產環境pre,線上環境prd

在不同環境中我們可能需要不同的配置,如資料庫配置,MQ配置等,在不同的環境都有相應的不同的配置,這時候我們需要根據不同的環境來建立不同的配置

強大的Spring為我們提供了條件化裝配Bean和profile的bean裝配

如下:

TestMain

package com.halfworlders.test;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import com.halfworlders.dao.DataSource;
import com.halfworlders.dao.DataSourceConfig;

/**
 * profile的需要兩個引數:spring.profile.active和Spring.profile.default
 * 有多種方式配置這兩個屬性
 * 1,作為DispatcherServlet的初始化函式
 * 2,作為Web應用的上下文引數
 * 3,作為JNDI條目
 * 4,作為環境變數
 * 5,作為JVM的系統屬性
 * 6,在整合測試環境上,使用@ActiveProfiles註解
 */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes=DataSourceConfig.class)
@ActiveProfiles("prd")
public class TestMain {

	@Autowired(required=false)
	private DataSource dataSource;
	
	@Test
	public void test(){
		System.out.println(dataSource.getClass().getName());
	}
}
DataSourceConfig
package com.halfworlders.dao;

import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;

@Configuration
@Import({MysqlDataSourceConfig.class,OracleDataSourceConfig.class,DB2DataSourceConfig.class})
public class DataSourceConfig {

}
MysqlDataSourceConfig
package com.halfworlders.dao;


import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;

@Configuration
public class MysqlDataSourceConfig {

	@Bean
	@Profile("prd")
	public DataSource dataSource(){
		return new MysqlDataSource();
	}
}
OracleDataSourceConfig
package com.halfworlders.dao;


import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;

@Configuration
public class OracleDataSourceConfig {

	@Bean(destroyMethod="shutdown")
	@Profile("dev")
	public DataSource dataSource() {
		return new OracleDataSource();
	}
}
DB2DataSourceConfig
package com.halfworlders.dao;


import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;

import com.halfworlders.condition.MyCondition;

@Configuration
public class DB2DataSourceConfig {

	/*
	 * 基於自定義條件MyCondition決定是否注入此Bean
	 */
	@Bean
	@Conditional(MyCondition.class)
	public DataSource dataSource(){
		return new DB2DataSource();
	}
}
MyCondition
package com.halfworlders.condition;

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 MyCondition implements Condition {

	/*
	 * 條件化Bean
	 * 如果環境變數中設定了sit,不管這個sit的環境變數值是什麼,被@Conditional註解中引用MyCondition的Bean都會被建立
	 */
	@Override
	public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
		Environment evm = context.getEnvironment();
		return evm.containsProperty("sit");
	}

}
DataSource
package com.halfworlders.dao;

public interface DataSource {
	void open();
	void shutdown();
}

public class MysqlDataSource implements DataSource {
	public void open(){
		
	}
	public void shutdown(){
		
	}
}

public class OracleDataSource implements DataSource {
	public void open(){
		
	}
	public void shutdown(){
		
	}
}

public class DB2DataSource implements DataSource {
	public void open(){
		
	}
	public void shutdown(){
		
	}
}