SpringBoot引入外部xml配置文件&SpringBoot多数据源支持

使用SpringBoot的主要思想是习惯大于配置。使用Java配置代替XML配置。
在实际应用开发过程中也会存在不得不添加配置文件的情况,例如集成其他框架或者需要配置一些中间件等,在这种情况下,就需要引入自定义的xml配置文件。
@SpringBootApplication会自动扫描当前包以及子包中的bean
模拟创建一个不和启动类在同一个包中的bean,编写spring配置文件由容器负责实例化。

package other;
public class OtherBean {
	public OtherBean(){
		System.out.println("我是有外部xml实例化的");
	}
}

编写spring配置文件

    


	

在启动类上添加注解:
@ImportResource(locations= {“classpath:application-bean.xml”})

测试启动时,控制台会打印构造方法中输出的内容。

7.SpringBoot多数据源支持
实际项目中,可能不仅会面临单一数据源的状况,甚至还会遇到多数据源的状况。
使用DBCP、和Druid 数据源,连接MySql中不同的Database
创建2个Database

create database master; -- 主库  使用DBCP数据源
create database cluster; -- 从库   使用Druid数据源
添加依赖

		

org.springframework.boot
		spring-boot-starter-parent
		1.5.4.RELEASE
	
	
		
			org.springframework.boot
			spring-boot-starter-web
		
		
			org.springframework.boot
			spring-boot-starter-jdbc
		
		
			commons-dbcp
			commons-dbcp
		

			mysql
			mysql-connector-java
			runtime
	
application.properties 
spring.datasource.master.url=jdbc:mysql://localhost:3306/master
spring.datasource.master.username=root
spring.datasource.master.password=root
spring.datasource.master.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.master.type=org.apache.commons.dbcp.BasicDataSource

spring.datasource.cluster.url=jdbc:mysql://localhost:3306/cluster
spring.datasource.cluster.username=root
spring.datasource.cluster.password=root
spring.datasource.cluster.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.cluster.type=com.alibaba.druid.pool.DruidDataSource

创建一个类,设置数据源

@Configuration
public class DataSourceConfig {
	@Bean(name ="masterDataSource")
	@Primary
	@ConfigurationProperties(prefix = "spring.datasource.master")
	public DataSource masterDataSource() {
		DataSource dataSource = new BasicDataSource();
		return dataSource;
	}

	@Bean(name = "clusterDataSource")
	@ConfigurationProperties(prefix = "spring.datasource.cluster")
	public DataSource clusterDataSource() {
		DataSource dataSource = new DruidDataSource();
		return dataSource;
	}
}

@Configuration
@Bean
@Primary众多相同的bean中,优先使用用@Primary注解的bean。同一个类型有多个实例,但我们需要注入一个的时候,我们必须采取措施,不然spring容器
会报错:…required a single bean, but 2 were found:…
有时候我们能保证同一个类型在spring容器中只有一个实例,有时候我们保证不了。这个时候@Primary注解就非常重要了
@ConfigurationProperties prefix 指定前缀和application.properties内容一致。读取内容,绑定到BasicDataSource 和 DruidDataSource的属性上。
测试

@SpringBootApplication
public class SpringBootDataSourceApplication {
	public static void main(String[] args) throws SQLException {
		ConfigurableApplicationContext context = SpringApplication.run(SpringBootDataSourceApplication.class,args);
        DataSource master = context.getBean("masterDataSource",DataSource.class);
        System.out.println(master.getClass().getName());  
        DataSource ds = context.getBean(DataSource.class);
        System.out.println(ds.getClass().getName());  //会获取有@Primary设置的对象
        DataSource cluster = context.getBean("clusterDataSource",DataSource.class);
        System.out.println(cluster.getClass().getName());  
	}
}

如果持久层使用JDBC设计实现,需要在DataSourceConfig 类中添加获取JdbcTemplete的方法。需要指定JdbcTemplete是由哪个数据源提供的。

//创建由主库 主数据源提供的JdbcTemplete
	@Bean(name = "masterJdbcTemplate")
	public JdbcTemplate primaryJdbcTemplate(
			@Qualifier("masterDataSource") DataSource dataSource) {
		return new JdbcTemplate(dataSource);
	}
	//创建由从库 从数据源提供的JdbcTemplete
	@Bean(name = "clusterJdbcTemplate")
	public JdbcTemplate secondaryJdbcTemplate(
			@Qualifier("clusterDataSource") DataSource dataSource) {
		return new JdbcTemplate(dataSource);
}

在主库中创建表
create table master_user (id int primary key auto_increment,name varchar(200))
在从库中创建表
create table cluster_user (id int primary key auto_increment,name varchar(200))
分别建立MasterUser 和 ClusterUser 对应表
public class MasterUser {
private Integer id;
private String name;
}
public class ClusterUser {
private Integer id;
private String name;
}

建立MasterUserDao 和 ClusterUserDao 接口和实现类
public interface MasterUserDao {
MasterUser getUserById(Integer id);
}
public interface ClusterUserDao {
MasterUser getUserById(Integer id);
}

@Repository
public class MasterUserDaoImpl implements MasterUserDao {
	@Autowired
	@Qualifier("masterJdbcTemplate")//自动装配主库提供的JdbcTemplete
	private JdbcTemplate jdbcTemplate;
	@Override
	public MasterUser getUserById(Integer id) {
		List list = jdbcTemplate.query(
				"select * from master_user where id = ?", new Object[] { id },
				new BeanPropertyRowMapper(MasterUser.class));
		if (list.size() > 0) {
			return list.get(0);
		}
		return null;
	}
}

@Repository
public class ClusterUserDaoImpl implements ClusterUserDao {
	@Autowired
	@Qualifier("clusterJdbcTemplate")//自动装配从库提供的JdbcTemplete
	private JdbcTemplate jdbcTemplate;
	@Override
	public ClusterUser getUserById(Integer id) {

		List list = jdbcTemplate.query(
				"select * from cluster_user where id = ?", new Object[] { id },
				new BeanPropertyRowMapper(ClusterUser.class));
		if (list.size() > 0) {
			return list.get(0);
		}
		return null;
	}
}

启动类中添加测试代代码:
MasterUserDao mud = context.getBean(MasterUserDao.class);
System.out.println(mud.getUserById(1));
ClusterUserDao cud = context.getBean(ClusterUserDao.class);
System.out.println(cud.getUserById(1));
事务管理,使用单独的数据源的事务管理
在DataSourceConfig类中添加方法

@Bean(name="masterTransactionManager")
	public PlatformTransactionManager masterTransactionManager(
			@Qualifier("masterDataSource") DataSource masterDataSource) {
		return new DataSourceTransactionManager(masterDataSource);
	}

	@Bean(name="clusterTransactionManager")
	public PlatformTransactionManager clusterTransactionManager(
			@Qualifier("clusterDataSource") DataSource clusterDataSource) {
		return new DataSourceTransactionManager(clusterDataSource);
	}

在需要事务绑定的方法上添加注解
@Transactional(value = “masterTransactionManager”)使用主库数据源的事务管理器
@Transactional(value = “clusterTransactionManager”)使用从库数据源的事务管理器

如果持久层使用MyBatis实现,需要由不同的数据源创建不同的SqlSessionFactory
添加mybatis-spring-boot-starter依赖


    	
    org.mybatis.spring.boot
    			mybatis-spring-boot-starter
    			1.1.1
    	

项目结构:
SpringBoot引入外部xml配置文件&SpringBoot多数据源支持_第1张图片
application.properties
同上
POJO设计Mapper接口设计同上
映射文件,注意Mapper代理开发时namespace的取值
主库对应数据源设置 MasterDataSourceConfig

    //集成MyBatis
    @Configuration
    // 扫描 Mapper 接口并容器管理
    @MapperScan(basePackages = MasterDataSourceConfig.PACKAGE, sqlSessionFactoryRef = "masterSqlSessionFactory")
    public class MasterDataSourceConfig {
    	// 精确到 master目录,以便跟其他数据源隔离
    	// 主库对应的mapper接口所在包
    	static final String PACKAGE = "com.hf.master.mapper";
    	// 主库对应的POJO所在包
    	static final String TYPEALIASES = "com.hf.master.pojo";
    	// 主库对应的mapper映射文件对应的位置
    	static final String MAPPER_LOCATION = "classpath:mybatis/master/mapper/*.xml";
    
    	// 设置主库,主数据源
    	@Bean(name = "masterDataSource")
    	@Primary
    	@ConfigurationProperties(prefix = "spring.datasource.master")
    	public DataSource

 masterDataSource() {
		DataSource dataSource = new BasicDataSource();
		return dataSource;
	}

	@Bean(name = "masterSqlSessionFactory")
	@Primary
	public SqlSessionFactory masterSqlSessionFactory(
			@Qualifier("masterDataSource") DataSource masterDataSource)
			throws Exception {
		final SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
		sessionFactory.setDataSource(masterDataSource);
		sessionFactory
				.setMapperLocations(new PathMatchingResourcePatternResolver()
						.getResources(MasterDataSourceConfig.MAPPER_LOCATION));
		sessionFactory.setTypeAliasesPackage(TYPEALIASES);
		return sessionFactory.getObject();
	}

	@Bean(name = "masterSqlSessionTemplate")
	@Primary
	public SqlSessionTemplate testSqlSessionTemplate(
			@Qualifier("masterSqlSessionFactory") SqlSessionFactory masterSqlSessionFactory)
			throws Exception {
		return new SqlSessionTemplate(masterSqlSessionFactory);
	}

	// 事务管理器
	@Bean(name = "masterTransactionManager")
	public PlatformTransactionManager masterTransactionManager(
			@Qualifier("masterDataSource") DataSource masterDataSource) {
		return new DataSourceTransactionManager(masterDataSource);
	}
}

从库对应数据源设置 ClusterDataSourceConfig

//集成MyBatis
@Configuration
// 扫描 Mapper 接口并容器管理
@MapperScan(basePackages = ClusterDataSourceConfig.PACKAGE, sqlSessionFactoryRef = "clusterSqlSessionFactory")
public class ClusterDataSourceConfig {
	// 精确到 cluster目录,以便跟其他数据源隔离
	// 从库对应的mapper接口所在包
	static final String PACKAGE = "com.hf.cluster.mapper";
	// 从库对应的POJO所在包
	static final String TYPEALIASES = "com.hf.cluster.pojo";
	// 从库对应的mapper映射文件对应的位置
	static final String MAPPER_LOCATION = "classpath:mybatis/cluster/mapper/*.xml";

	// 设置主库,从数据源
	@Bean(name = "clusterDataSource")
	@ConfigurationProperties(prefix = "spring.datasource.cluster")
	public DataSource clusterDataSource() {
		DataSource dataSource = new DruidDataSource();
		return dataSource;
	}

	@Bean(name = "clusterSqlSessionFactory")
	public SqlSessionFactory clusterSqlSessionFactory(
			@Qualifier("clusterDataSource") DataSource clusterDataSource)
			throws Exception {
		final SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
		sessionFactory.setDataSource(clusterDataSource);
		sessionFactory
				.setMapperLocations(new PathMatchingResourcePatternResolver()
						.getResources(ClusterDataSourceConfig.MAPPER_LOCATION));
		sessionFactory.setTypeAliasesPackage(TYPEALIASES);
		return sessionFactory.getObject();
	}

	@Bean(name = "clusterSqlSessionTemplate")
	public SqlSessionTemplate testSqlSessionTemplate(
			@Qualifier("clusterSqlSessionFactory") SqlSessionFactory clusterSqlSessionFactory)
			throws Exception {
		return new SqlSessionTemplate(clusterSqlSessionFactory);
	}

	// 事务管理器
	@Bean(name = "clusterTransactionManager")
	public PlatformTransactionManager clusterTransactionManager(
			@Qualifier("clusterDataSource") DataSource clusterDataSource) {
		return new DataSourceTransactionManager(clusterDataSource);
	}

}

启动类

@SpringBootApplication
public class SpringBootDataSourceApplication {
	public static void main(String[] args) throws SQLException {
		ConfigurableApplicationContext context = SpringApplication.run(SpringBootDataSourceApplication.class,args);
		MasterUserMapper mum = context.getBean(MasterUserMapper.class);
		System.out.println(mum.getUserById(1));
		ClusterUserMapper cum = context.getBean(ClusterUserMapper.class);
		System.out.println(cum.getUserById(1));
	}
}

你可能感兴趣的:(SpringBoot)