概述

pageHelper的使用十分简单,无需手动添加任何注解,这是怎么做到的呢?
答案是,pageHelper使用了springboot的自动装配功能,springboot启动时自动装配pageHelper相关的bean。

自动装配Jar包

<dependency>
    <groupId>com.github.pagehelper</groupId>
    <artifactId>pagehelper-spring-boot-autoconfigure</artifactId>
    <version>1.2.13</version>
</dependency>

Jar包分析

jar包概览

在这里插入图片描述

spring.factories

该文件配置了自动配置类,作用是:Springboot启动时会自动扫描所有jar包里的META-INF目录下的spring.factories来自动加载bean对象到spring容器中。

# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.github.pagehelper.autoconfigure.PageHelperAutoConfiguration

自动配置类PageHelperAutoConfiguration.java

/**
 * 自定注入分页插件
 *
 * @author liuzh
 */
 // 标识该类是配置类,类似xml配置文件,给容器中添加bean
@Configuration
// 当spring的applicationContext容器中存在SqlSessionFactory类的bean时,当前配置类生效。
@ConditionalOnBean(SqlSessionFactory.class)
// 使能PageHelperProperties类的ConfigurationProperties功能;
// 所有配置文件中可配置的属性都在PageHelperProperties中封装着。
@EnableConfigurationProperties(PageHelperProperties.class)
// 加载了MybatisAutoConfiguration配置类后,再加载当前配置类(PageHelperAutoConfiguration)
@AutoConfigureAfter(MybatisAutoConfiguration.class)
public class PageHelperAutoConfiguration {

    @Autowired
    private List<SqlSessionFactory> sqlSessionFactoryList;

    // 会把PageHelperProperties 配置类定义的配置项内容读取到内存
    @Autowired
    private PageHelperProperties properties;

    /**
     * 接受分页插件额外的属性
     *
     * @return
     */
    @Bean
    @ConfigurationProperties(prefix = PageHelperProperties.PAGEHELPER_PREFIX)
    public Properties pageHelperProperties() {
        return new Properties();
    }

    @PostConstruct
    public void addPageInterceptor() {
        PageInterceptor interceptor = new PageInterceptor();
        Properties properties = new Properties();
        // 先把一般方式配置的属性放进去
        properties.putAll(pageHelperProperties());
        // 再中划线分割的放进去,由于类似close-conn 利用上面方式映射时,属性名就是 close-conn 而不是 closeConn,
        // 所以需要自定义get/set方法进行设置
        // 就是中划线与驼峰的转换
        properties.putAll(this.properties.getProperties());
        interceptor.setProperties(properties);
        for (SqlSessionFactory sqlSessionFactory : sqlSessionFactoryList) {
            sqlSessionFactory.getConfiguration().addInterceptor(interceptor);
        }
    }
}

源码解析

  • addPageInterceptor 方法会在PageHelperAutoConfiguration bean对象生成后执行,该方法会把配置在application.properties/application.yml中以pagehelper开头的配置全部读取到内存中。
  • pageHelperProperties()和 this.properties.getProperties() 会把定义在配置文件的属性加载到内存。
  • PageInterceptor 是pagehelper实现的拦截器, interceptor.setProperties(properties);把配置信息设置到pagehelper中。
  • sqlSessionFactoryList 是mybatis中的sqlSession工厂列表,这里把pagehelper的拦截器添加到mybatis中,这样就可以在执行sql时先通过paghelper的拦截器做一下自定义化的sql操作了。

pagehelper-spring-boot-starter启动包

该包的作用就是一个启动包,该包通过spring.provides配置文件把需要依赖的相关Jar包导入的工程中。
因此在springboot工程中只需要把pagehelper-spring-boot-starter引入即可,相关Jar包会自动导入,像下面这样
这正是springboot的原则,简洁,自动配置。

<dependency>
            <groupId>com.github.pagehelper</groupId>
            <artifactId>pagehelper-spring-boot-starter</artifactId>
            <version>1.2.13</version>
        </dependency>

spring.provides文件

provides: pagehelper-spring-boot-autoconfigure,pagehelper,mybatis-spring-boot-autoconfigure,mybatis,mybatis-spring

这个文件只是用来配置需要使用哪些jar包,springboot会自动引入,非常方便。
实际上这个文件非必要的,可要直接引入相关的jar即可。

spring boot 2.1 GA 后不再依赖 spring.provides

Remove spring.provides files
It does use pom parsing indirectly, since aether parses the poms. The info may look like its duplicating information but it isn’t exactly. The provides is used to resolve ambiguity. Basically if a provides file says that a ‘starter S provides X’… then ‘S’ takes priority over other things that also provide it.

It is surprising how many things end up multiple times in the dependency graph reachable from severral different things. The provides files were added to avoid some surprising/unwanted suggestions. Think of the provides file as a very strong hint to the ide that a boot developer thought ‘if I want to add X to my pom, you should use starter S’. The dependencies inferred from pom are often just accidental and not as ‘deliberate’. (Heuristics like dependency’s depth in the graph were explored but didn’t provide good results).

@dsyer helped with populating the provides files. This was a long time ago and i’m not sure if it has been kept up to date, so the quality of the info in the various provides file may not be as good/complete as it once was. It has also been a bit of a controversial feature. I’m sure a few people like it, but there’s also a lot of folks who have asked how to turn it of.

具体详见 https://github.com/spring-projects/spring-boot/issues/12435

Stop relying on spring.provides files before Spring Boot 2.1 is GA
spring boot 2.1 GA 后不再依赖 spring.provides

总结

启动包的作用就是声明需要使用的jar包,springboot自动引入,用起来简单方便。

Logo

瓜分20万奖金 获得内推名额 丰厚实物奖励 易参与易上手

更多推荐