zoukankan      html  css  js  c++  java
  • SpringBoot数据访问之Druid启动器的使用

    数据访问之Druid启动器的使用

    承接上文:SpringBoot数据访问之Druid数据源的自定义使用

    官方文档:

    Druid Spring Boot Starter

    首先在在 Spring Boot 项目中加入druid-spring-boot-starter依赖 。

    博主版本:1.1.17 SpriongBoot:2.5.3

    <dependency>
       <groupId>com.alibaba</groupId>
       <artifactId>druid-spring-boot-starter</artifactId>
       <version>版本号</version>
    </dependency>
    

    我们来看下Druid中的自动配置(两种方式):

    1. 可以双击shift打开搜索找到DruidDataSourceAutoConfigure
    2. image-20210806161823666

    源码分析:

    为什么导入启动器就能使用Druid数据源。

    @Configuration
    @ConditionalOnClass(DruidDataSource.class)
    @AutoConfigureBefore(DataSourceAutoConfiguration.class)
    @EnableConfigurationProperties({DruidStatProperties.class, DataSourceProperties.class})
    @Import({DruidSpringAopConfiguration.class,
        DruidStatViewServletConfiguration.class,
        DruidWebStatFilterConfiguration.class,
        DruidFilterConfiguration.class})
    public class DruidDataSourceAutoConfigure {
    
        private static final Logger LOGGER = LoggerFactory.getLogger(DruidDataSourceAutoConfigure.class);
    
        @Bean(initMethod = "init")
        @ConditionalOnMissingBean
        public DataSource dataSource() {
            LOGGER.info("Init DruidDataSource");
            return new DruidDataSourceWrapper();
        }
    }
    

    看以下两个注解:

    @ConditionalOnClass(DruidDataSource.class)
    @AutoConfigureBefore(DataSourceAutoConfiguration.class)
    
    1. 当容器中有这个类
    2. 后面的内容在这个类(DataSourceAutoConfiguration.class)之前执行

    为什么这样设置呢?

    进入DataSourceAutoConfiguration类后找到引入的DataSourceConfiguration.Hikari.class,。

    	@Configuration(proxyBeanMethods = false)
    	@ConditionalOnClass(HikariDataSource.class)
    	@ConditionalOnMissingBean(DataSource.class)
    	@ConditionalOnProperty(name = "spring.datasource.type", havingValue = "com.zaxxer.hikari.HikariDataSource",
    			matchIfMissing = true)
    	static class Hikari {
    
    		@Bean
    		@ConfigurationProperties(prefix = "spring.datasource.hikari")
    		HikariDataSource dataSource(DataSourceProperties properties) {
    			HikariDataSource dataSource = createDataSource(properties, HikariDataSource.class);
    			if (StringUtils.hasText(properties.getName())) {
    				dataSource.setPoolName(properties.getName());
    			}
    			return dataSource;
    		}
    
    	}
    

    由上述代码可以发现,默认的配置源是HikariDataSource,但是有一个要求:

    @ConditionalOnMissingBean(DataSource.class)

    就是如果在容器中没有数据源,下面代码生效,也就是使用HikariDataSource,但是若容器中已经有开发者创建的数据源,那么开发者创建的优先。

    所以Druid的创建必须要在默认源之前声明,如果在默认源之后声明,Druid数据源将不生效,由于Druid的自动配置决定的:

    @ConditionalOnMissingBean
        public DataSource dataSource() {
            LOGGER.info("Init DruidDataSource");
            return new DruidDataSourceWrapper();
        }
    

    ConditionalOnMissingBean:容器中已经有了默认源的话,那么Druid的源是不生效的。

    功能实现介绍:

    查看具体的功能只要分析它导入了哪些类就能明白它所实现的功能。

    • DruidSpringAopConfiguration.class,
    • DruidStatViewServletConfiguration.class,
    • DruidWebStatFilterConfiguration.class,
    • DruidFilterConfiguration.class

    DruidSpringAopConfiguration对应功能

    image-20210806170156460

    该类是配置Spring的监控的,点击进入,可以看到相关的设置:

    @Bean
    @ConditionalOnProperty(name = "spring.aop.auto",havingValue = "false")
    public DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator() {
        DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
        advisorAutoProxyCreator.setProxyTargetClass(true);
        return advisorAutoProxyCreator;
    }
    

    与我们手动配置的如出一辙,不明白的朋友可以简单了解z下之前的文章:

    1. 掘金: SpringBoot数据访问之自定义Druid
    2. 个人博客:SpringBoot数据访问之自定义Druid

    通过该类上的属性配置进行属性绑定,@ConditionalOnProperty("spring.datasource.druid.aop-patterns")

    配置项:spring.datasource.druid.aop-patterns

    所以我们可以在application.yaml文件中配置Springd监控的功能。

    DruidStatViewServletConfiguration

    该类是实现开启监控页的功能,相当于我们之前写的StatViewServlet

    自定义写法:

    /**
    * 配置监控页
    */
    @Bean
    public ServletRegistrationBean staViewServlet(){
        //实例化StatViewServlet
        StatViewServlet statViewServlet = new StatViewServlet();
    	 //将实例化的实例化StatViewServlet 传入ServletRegistrationBean,并设置访问路径
        ServletRegistrationBean<StatViewServlet> registrationBean = new ServletRegistrationBean<>(statViewServlet, "/druid/*");
    
        return registrationBean;
    }
    

    Druid-start中的配置:

    image-20210806171124269

    基本上也是如出一辙,自定义的功能比较单一。

    所以我们使用Druid-start来简化我们之前的操作,可以通过DruidStatViewServletConfiguration中的配置属性配置:

    @ConditionalOnProperty(name = "spring.datasource.druid.stat-view-servlet.enabled", havingValue = "true")
    

    配置项:spring.datasource.druid.stat-view-servlet.enabled。

    扩展(havingValue):

    @ConditionalOnProperty,这个注解能够控制某个configuration是否生效。具体操作是通过其两个属性name以及havingValue来实现的,其中name用来从application.properties中读取某个属性值,如果该值为空,则返回false;如果值不为空,则将该值与havingValue指定的值进行比较,如果一样则返回true;否则返回false。如果返回值为false,则该configuration不生效;为true则生效

    通过上述文章的所说,SpringBoot首先会去spring.datasource.druid.stat-view-servlet该配置项中找到enabled的值是什么,如果该值与havingValue指定的值进行比较,一样则返回true,这样该Bean就会生效,也就是该组件或者功能开启。在配置文件中我们设置后可以佐证该结论是否正确。

    后面两个类也基本是相同的方法,各位自行查看,在此省略。

    DruidWebStatFilterConfiguration   //web应用开启DruidFilterConfiguration		  //Filter开启
    

    开启配置属性:

    配置必须属性:

    spring:  datasource:    url: jdbc:mysql://localhost:3306/vuesite    username: root    password: 123456    driver-class-name: com.mysql.jdbc.Driver
    

    开启监控页:

    开启监控页也就是增加StatViewServlet组件。

    spring:  datasource:    url: jdbc:mysql://localhost:3306/vuesite    username: root    password: 123456    driver-class-name: com.mysql.jdbc.Driver    druid:      stat-view-servlet:        enabled: true
    

    我们看一下enabled的默认配置,点击enabled,找到私有属性可知:

    /** * Enable StatViewServlet, default false. */private boolean enabled;
    

    默认为false,这也就佐证了上述的结论。

    完整的yaml基本配置如下:

    spring:  datasource:    url: jdbc:mysql://localhost:3306/vuesite    username: root    password: 123456    driver-class-name: com.mysql.jdbc.Driver    druid:      aop-patterns: com.xbhog.*      filters: stat,wall     # 底层开启功能,stat(sql监控),wall(防火墙)      stat-view-servlet:   # 配置监控页功能        enabled: true        login-username: admin        login-password: admin        resetEnable: false      web-stat-filter:  # 监控web        enabled: true        urlPattern: /*        exclusions: '*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*'      filter:        stat:    #对上面filters里面的stat的详细配置          slow-sql-millis: 1000          logSlowSql: true          enabled: true        wall:          enabled: true          config:            drop-table-allow: false
    

    因为我们监控主要事情是sql,所以测试功能的时候需要发送一个controller sql.如下代码:

    @Controllerpublic class Mycontro {    @Autowired    JdbcTemplate jdbcTemplate;    @ResponseBody   //不经过视图解析器    @GetMapping("/sql")    public String druidquery(){        Long aLong = jdbcTemplate.queryForObject("select count(*) from user",Long.class);        return aLong.toString();    }}
    

    在配置的时候出现的错误

    aop-patterns配置好以后,打开界面刷新,发现并没有生效,也就是没有监控到。

    在网上找了很多方法,也看了官方文档,还是不行。

    最后使用了原始的方法,降版本号,亲测在 Druid在1.1.17可以使用。

    image-20210806215242510

    参考:

    havingValue

    Druid Spring Boot Starter

    SpringBoot2零基础入门springboot全套完整版

    结束:

    如果你看到这里或者正好对你有所帮助,希望能点个关注或者推荐,感谢;

    有错误的地方,欢迎在评论指出,作者看到会进行修改。

  • 相关阅读:
    web中的懒加载
    数据库表的关系
    struts2的MVC模式
    servlet与tomcat的关系
    servlet解析
    解决Mac外接显示器字体模糊的问题
    insmod: ERROR: could not insert module dm-snapshot.ko: Unknown symbol in module
    linux ssh tunnel
    Permission denied (publickey,gssapi-keyex,gssapi-with-mic).错误的解决
    Best practices for a new Go developer
  • 原文地址:https://www.cnblogs.com/xbhog/p/15111758.html
Copyright © 2011-2022 走看看