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,返回动态代理。

浙公网安备 33010602011771号