This is the seventh day of my participation in the August More text Challenge. For details, see:August is more challenging

Continue above: Use of custom Druid data sources for SpringBoot data access

Druid Spring Boot Starter

Start by adding druid-spring-boot-starter dependencies to your Spring Boot project.

Blogger version: 1.1.17 SpringBoot: 2.5.3

<dependency>
   <groupId>com.alibaba</groupId>
   <artifactId>druid-spring-boot-starter</artifactId>
   <version>The version number</version>
</dependency>
Copy the code

Let’s look at auto-configuration in Druid (two ways) :

  1. Can find DruidDataSourceAutoConfigure double-click the shift to open the search

Source code analysis:

Why importing an initiator can use Druid data sources.

@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(a) {
        LOGGER.info("Init DruidDataSource");
        return newDruidDataSourceWrapper(); }}Copy the code

Look at the following two notes:

@ConditionalOnClass(DruidDataSource.class)
@AutoConfigureBefore(DataSourceAutoConfiguration.class)
Copy the code
  1. When this class is in the container (import the initiator, satisfy the condition)
  2. At the back of the content in this class (DataSourceAutoConfiguration. Class) before execution

Why is this set up?

Enter DataSourceAutoConfiguration introduced found after class 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());
			}
			returndataSource; }}Copy the code

As you can see from the code above, the default configuration source is HikariDataSource, with one requirement:

@ConditionalOnMissingBean(DataSource.class)

If there is no data source in the container, the following code takes effect, using HikariDataSource, but if there is already a developer-created data source in the container, the developer-created data source takes precedence.

If the default source is declared after the default source, the Druid data source will not take effect, because the automatic configuration of Druid determines:

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

ConditionalOnMissingBean the Druid source is not valid if the default source is already in the Container.

Function implementation introduction:

You can see what it does by looking at what classes it imports.

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

DruidSpringAopConfiguration corresponding function

This class is used to configure Spring monitoring. Click to enter and you can see the related Settings:

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

With our manual configuration of the same, do not understand the friends can simply understand the previous article:

  1. A custom Druid for SpringBoot data access
  2. Personal blog: Custom Druid for SpringBoot data access

Through the configuration properties on the class attribute binding, @ ConditionalOnProperty (” spring. The datasource. The druid. Aop – patterns “)

Configuration items: spring datasource. The druid. Aop – patterns

So we can configure the Springd monitoring functionality in the application.yaml file.

DruidStatViewServletConfiguration

This class implements the function of opening the monitor page, which is equivalent to the StatViewServlet we wrote earlier

Custom writing:

/** * Configure the monitoring page */
@Bean
public ServletRegistrationBean staViewServlet(a){
    // Instantiate StatViewServlet
    StatViewServlet statViewServlet = new StatViewServlet();
	 // Pass the instantiated StatViewServlet into the ServletRegistrationBean and set the access path
    ServletRegistrationBean<StatViewServlet> registrationBean = new ServletRegistrationBean<>(statViewServlet, "/druid/*");

    return registrationBean;
}
Copy the code

Druid-start druid-start druid-start

Basically the same, the custom function is relatively single.

So we use the Druid – start to simplify operation, before we can pass DruidStatViewServletConfiguration configuration properties in the configuration:

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

Configuration items: spring datasource. The druid. Stat – view – servlet. Enabled.

Extension (havingValue) :

ConditionalOnProperty. This annotation controls whether a configuration is valid. This is done with two properties, name and havingValue. Name is used to read the value of an attribute from application.properties. If the value is null, false is returned. If the value is not empty, it is compared to the value specified by havingValue, and true is returned if it is the same; Otherwise return false. If the return value is false, the configuration does not take effect. The value takes effect if it is true

Through the above paragraph, SpringBoot would first go to the spring. The datasource. The druid. Stat – view – servlet what value is found in the configuration item is enabled, if the value is compared with havingValue specified value, as it returns true, Then the Bean takes effect, and the component or function is turned on. You can verify the correctness of this conclusion by setting it in the configuration file.

The latter two classes are basically the same method, everyone to view, omitted here.

DruidWebStatFilterConfiguration   // The Web application is started
DruidFilterConfiguration		  / / Filter
Copy the code

Enable configuration properties:

Configure mandatory properties:

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

Open the monitoring page:

Opening the monitoring page is to add the StatViewServlet component.

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
Copy the code

Let’s take a look at the default configuration of Enabled, click Enabled, go to the private property and see:

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

The default is false, which supports the above conclusion.

The complete basic YAML configuration is as follows:

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     # Enable bottom layer function, stat (SQL monitor), wall (firewall)

      stat-view-servlet:   # Configure the monitoring page function
        enabled: true
        login-username: admin
        login-password: admin
        resetEnable: false

      web-stat-filter:  # monitoring web
        enabled: true
        urlPattern: / *
        exclusions: '*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*'


      filter:
        stat:    Configure the stat in the filters above
          slow-sql-millis: 1000
          logSlowSql: true
          enabled: true
        wall:
          enabled: true
          config:
            drop-table-allow: false
Copy the code

Since the main thing we monitor is SQL, we need to send a Controller SQL to test the functionality. The following code:

@Controller
public class Mycontro {
    @Autowired
    JdbcTemplate jdbcTemplate;

    @ResponseBody   // Not through the view parser
    @GetMapping("/sql")
    public String druidquery(a){
        Long aLong = jdbcTemplate.queryForObject("select count(*) from user",Long.class);
        returnaLong.toString(); }}Copy the code

An error occurred during configuration

When the AOP-patterns are configured and the interface is refreshed, they do not take effect, i.e. they are not monitored.

Found a lot of methods on the Internet, also saw the official document, or not.

Finally, the original method is used, and the version number is reduced. The Druid is available for 1.1.17.

Reference:

havingValue

Druid Spring Boot Starter

SpringBoot2 Getting started with springBoot

The end:

If you see here or just to help you, I hope you can point to follow or recommend, thank you;

If there are any errors, please point them out in the comments and the author sees them will be corrected.