springboot分析——与其他组件的整合(druid/mybatis)

 

  springboot本身提供了许多自动配置,帮助开发者提供开发效率,当然如果我们有一些个性化的需求,springboot

也提供了良好的扩展,只需要配置starter依赖或者简单的properties配置即可实现功能,下面我们分析几种和其他组件

整合的案例。

一:与Druid数据源的整合

  druid是alibaba提供的一种数据源框架,内置了许多监控的功能,如果想使用可以很方便和springboot整合。

1:添加依赖和配置

		<dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>druid-spring-boot-starter</artifactId>
			<version>1.1.21</version>
		</dependency>

		<dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>druid</artifactId>
			<version>1.0.26</version>
		</dependency>
#连接池的配置信息
## 初始化大小,最小,最大
spring.datasource.druid.url=jdbc:mysql://localhost:3306/study
spring.datasource.druid.username=root
spring.datasource.druid.password=root
spring.datasource.druid.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.druid.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.druid.initialSize=2
spring.datasource.druid.minIdle=2
spring.datasource.druid.maxActive=2
## 配置获取连接等待超时的时间
spring.datasource.druid.maxWait=60000
# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
spring.datasource.druid.timeBetweenEvictionRunsMillis=60000
# 配置一个连接在池中最小生存的时间,单位是毫秒
spring.datasource.druid.minEvictableIdleTimeMillis=300000
spring.datasource.druid.validationQuery=SELECT 1 FROM DUAL
spring.datasource.druid.testWhileIdle=true
spring.datasource.druid.testOnBorrow=false
spring.datasource.druid.testOnReturn=false
spring.datasource.druid.poolPreparedStatements=true
spring.datasource.druid.maxPoolPreparedStatementPerConnectionSize=20
# 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙
spring.datasource.druid.filters=stat,wallWWW
# 通过connectProperties属性来打开mergeSql功能;慢SQL记录
spring.datasource.druid.connectionProperties=druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000

#mybatis sql配置文件
mybatis.mapperLocations=classpath:com/mapper/*.xml

  

2:配置druid监控

@Data
@Configuration
//@ConfigurationProperties(prefix = "spring.druid",ignoreInvalidFields = true)
public class DruidConfig {

	//因为Springboot内置了servlet容器,所以没有web.xml,替代方法就是将ServletRegistrationBean注册进去
	//加入后台监控
	//这里其实就相当于servlet的web.xml
	@Bean
	public ServletRegistrationBean statViewServlet() {
		ServletRegistrationBean<StatViewServlet> bean =
				new ServletRegistrationBean<StatViewServlet>(new StatViewServlet(), "/druid/*");

		//后台需要有人登录,进行配置
		//bean.addUrlMappings(); 这个可以添加映射,我们在构造里已经写了
		//设置一些初始化参数
		Map<String, String> initParas = new HashMap<String, String>();
		initParas.put("loginUsername", "admin");//它这个账户密码是固定的
		initParas.put("loginPassword", "123456");
		//允许谁能防伪
		initParas.put("allow", "");//这个值为空或没有就允许所有人访问,ip白名单
		//initParas.put("allow","localhost");//只允许本机访问,多个ip用逗号,隔开
		//initParas.put("deny","");//ip黑名单,拒绝谁访问 deny和allow同时存在优先deny
		initParas.put("resetEnable", "false");//禁用HTML页面的Reset按钮
		bean.setInitParameters(initParas);
		return bean;
	}

	//再配置一个过滤器,Servlet按上面的方式注册Filter也只能这样
	@Bean public FilterRegistrationBean webStatFilter() {
		FilterRegistrationBean bean = new FilterRegistrationBean();
		//可以设置也可以获取,设置一个阿里巴巴的过滤器
		bean.setFilter(new WebStatFilter());
		bean.addUrlPatterns("/*");
		//可以过滤和排除哪些东西
		Map<String, String> initParams = new HashMap<String, String>();
		//把不需要监控的过滤掉,这些不进行统计
		initParams.put("exclusions", "*.js,*.css,/druid/*");
		bean.setInitParameters(initParams);
		return bean;
	}
}

  

测试代码:

@Controller
public class DemoController {

	@Value("${study.enable}")
	private String env;

	@Autowired
	private DataSource dataSource;

	@RequestMapping("/hello")
	@ResponseBody
	public String hello(){
		try{
			Connection connection = dataSource.getConnection();
			String sql = "select * from user";
			PreparedStatement ps = connection.prepareStatement(sql);
			ResultSet resultSet = ps.executeQuery();
			List<User> list = new ArrayList<>();
			while(resultSet.next()){
				String name = resultSet.getString("name");
				String age = resultSet.getString("age");
				User user = new User();
				user.setAge(age);
				user.setName(name);
				list.add(user);
			}
			return JSON.toJSONString(list);
		}catch (Exception e){
			e.printStackTrace();
			return null;
		}
	}
}

运行结果:

 看一下监控平台:

 

 

 

 

 

 指标监控正常,说明springboot整合druid数据源成功!,简单看一下源码,从配置启动依赖starter开始看

springboot的自动配置 是基于SPI机制,在spring容器启动的时候,会加载META-INF 下的spring.factories 目录的文件,解析里面的配置项

 

 

 

 

看一下DruidDataSourceAutoConfigure类:

 

 

 

 

 

 

 最后把DruidDataSource这个对象缓存到spring容器中。

 

二:与mybatis的整合

操作数据库用的最多的还是mybatis框架,作为比较优秀的orm框架,深得程序员的喜欢,下面我们来看一下怎么整合?

1:添加依赖和配置

		<!--4: 整合mybatis-->
		<dependency>
			<groupId>org.mybatis.spring.boot</groupId>
			<artifactId>mybatis-spring-boot-starter</artifactId>
			<version>RELEASE</version>
		</dependency>

 

#mybatis sql配置文件
mybatis.mapperLocations=classpath:com/mapper/*.xml

  

在@Configuration配置项上加入@MapperScan注解,配置扫描包路径

 

  

在dao目录新建一个UserMapper类

public interface UserMapper {
	List<User> listUsers();
}

在mapper目录新建一个UserMapper.xml文件

<?xml version="1.0" encoding="UTF-8" ?>  
<!DOCTYPE mapper PUBLIC "-//ibatis.apache.org//DTD Mapper 3.0//EN"      
"http://ibatis.apache.org/dtd/ibatis-3-mapper.dtd">

<mapper namespace="com.dao.UserMapper">

	<resultMap id="baseResultMap" type="com.model.User">
		<result column="name" property="name" jdbcType="VARCHAR"></result>
		<result column="age" property="age" jdbcType="VARCHAR"></result>
		<result column="currency" property="currency" jdbcType="VARCHAR"></result>
	</resultMap>

	<select id="listUsers" resultMap="baseResultMap">
		select * from user
	</select>

</mapper>

  

测试类改为:

@Controller
public class DemoController {

	@Value("${study.enable}")
	private String env;

//	@Autowired
//	private DataSource dataSource;

	@Autowired
	private UserMapper mapper;

	@RequestMapping("/hello")
	@ResponseBody
	public String hello(){
		try{
			/*
			Connection connection = dataSource.getConnection();
			String sql = "select * from user";
			PreparedStatement ps = connection.prepareStatement(sql);
			ResultSet resultSet = ps.executeQuery();
			List<User> list = new ArrayList<>();
			while(resultSet.next()){
				String name = resultSet.getString("name");
				String age = resultSet.getString("age");
				User user = new User();
				user.setAge(age);
				user.setName(name);
				list.add(user);
			}*/
			List<User> list = mapper.listUsers();
			return JSON.toJSONString(list);
		}catch (Exception e){
			e.printStackTrace();
			return null;
		}
	}
}

  

运行结果:

 

 springboot整合mybatis成功!

下面看一下源码如何实现的?从mybatis的starter启动类开始看

mybatis-spring-boot-starter是一个父类工程,pom文件,依赖引入了上面的jar包

 

 mybatis-spring-boot-autoconfigure中有spring.factories文件:

 

 

 

 

看一下这个类里面的方法,在这个方法中会解析mybatis-config.xml ,以及mapper.xml文件,完成MapperStatement的解析缓存以及命名空间的解析,

全限定名id与MapperProxyFactory的映射缓存。

 

@MapperScan注解扫描会在ConfigurationClassPostProcessor中进行,由于这个注解扫描比较复杂,后面再进行分析,主要工作是:

扫描包路径,创建MapperFactoryBean,然后代理通过beanName调用会getObject,调到sqlSession.getMapper,返回动态代理。

 

posted @ 2020-07-09 18:14  程序员三藏  阅读(351)  评论(0编辑  收藏  举报