1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        只需4步,自己搞個 Spring Boot Starter !

        共 6003字,需瀏覽 13分鐘

         ·

        2020-08-09 02:19


        點(diǎn)擊上方藍(lán)色“程序猿DD”,選擇“設(shè)為星標(biāo)”

        回復(fù)“資源”獲取獨(dú)家整理的學(xué)習(xí)資料!

        作者 | 溫安適

        來源 |?https://my.oschina.net/floor/blog/4435699

        引言

        只要你用Springboot,一定會用到各種spring-boot-starter。其實(shí)寫一個spring-boot-starter

        ,僅需4步。下面我們就寫一個starter,它將實(shí)現(xiàn),在日志中打印方法執(zhí)行時間。

        第一步 創(chuàng)建maven項(xiàng)目

        在使用spring-boot-starter,會發(fā)現(xiàn),有的項(xiàng)目名稱是 XX-spring-boot-starter,有的是

        spring-boot-starter-XX,這個項(xiàng)目的名稱有什么講究呢?

        從springboot官方文檔摘錄如下:

        Do not start your module names with spring-boot, even if you use a different Maven groupId. We may offer official support for the thing you auto-configure in the future.

        As a rule of thumb, you should name a combined module after the starter.

        從這段話可以看出spring-boot-starter命名的潛規(guī)則。

        命名潛規(guī)則

        spring-boot-starter-XX是springboot官方的starter

        XX-spring-boot-starter是第三方擴(kuò)展的starter

        打印方法執(zhí)行時間的功能,需要用到aop,咱們的項(xiàng)目就叫做

        aspectlog-spring-boot-starter吧。

        項(xiàng)目的pom文件如下:


        <project?xmlns="http://maven.apache.org/POM/4.0.0"
        ?????????xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        ?????????xsi:schemaLocation="http://maven.apache.org/POM/4.0.0?http://maven.apache.org/xsd/maven-4.0.0.xsd">

        ????<modelVersion>4.0.0modelVersion>

        ????<groupId>org.examplegroupId>
        ????<artifactId>aspectlog-spring-boot-starterartifactId>
        ????<version>1.0.2version>
        ????<parent>
        ????????<groupId>org.springframework.bootgroupId>
        ????????<artifactId>spring-boot-starter-parentartifactId>
        ????????<version>2.1.15.RELEASEversion>
        ????parent>
        ????
        ????<dependencies>
        ????????<dependency>
        ????????????<groupId>org.springframework.bootgroupId>
        ????????????<artifactId>spring-boot-autoconfigureartifactId>
        ????????dependency>
        ????????<dependency>
        ????????????<groupId>org.springframework.bootgroupId>
        ????????????<artifactId>spring-boot-starter-aopartifactId>
        ????????dependency>
        ????????<dependency>
        ????????????<groupId>org.springframework.bootgroupId>
        ????????????<artifactId>spring-boot-configuration-processorartifactId>
        ????????????<optional>trueoptional>
        ????????dependency>
        ????dependencies>

        project>

        關(guān)于spring-boot-configuration-processor的說明,引自springBoot官方文檔:

        Spring Boot uses an annotation processor to collect the conditions on auto-configurations in a metadata file ( META-INF/spring-autoconfigure-metadata.properties ). If that file is present, it is used to eagerly filter auto-configurations that do not match, which will improve startup time. It is recommended to add the following dependency in a module that contains auto-configurations:

        org.springframework.boot

        spring-boot-autoconfigure-processor

        true

        簡單說就是:寫starter時,在pom中配置spring-boot-autoconfigure-processor,在編譯時會自動收集配置類的條件,寫到一個META-INF/spring-autoconfigure-metadata.properties中。

        第二步寫自動配置邏輯

        各種condition

        類型注解說明
        Class Conditions類條件注解@ConditionalOnClass當(dāng)前classpath下有指定類才加載
        @ConditionalOnMissingClass當(dāng)前classpath下無指定類才加載
        Bean ConditionsBean條件注解@ConditionalOnBean當(dāng)期容器內(nèi)有指定bean才加載
        @ConditionalOnMissingBean當(dāng)期容器內(nèi)無指定bean才加載
        Property Conditions環(huán)境變量條件注解(含配置文件)@ConditionalOnPropertyprefix 前綴name 名稱havingValue 用于匹配配置項(xiàng)值matchIfMissing 沒找指定配置項(xiàng)時的默認(rèn)值
        ResourceConditions 資源條件注解@ConditionalOnResource有指定資源才加載
        Web Application Conditionsweb條件注解@ConditionalOnWebApplication是web才加載
        @ConditionalOnNotWebApplication不是web才加載
        SpEL Expression Conditions@ConditionalOnExpression符合SpEL 表達(dá)式才加載

        本次我們就選用@ConditionalOnProperty。即配置文件中有aspectLog.enable=true,才加載我們的配置類。

        下面開始寫自動配置類

        2.1.定義AspectLog注解,該注解用于標(biāo)注需要打印執(zhí)行時間的方法。

        package?com.shanyuan.autoconfiguration.aspectlog;
        import?java.lang.annotation.ElementType;
        import?java.lang.annotation.Retention;
        import?java.lang.annotation.RetentionPolicy;
        import?java.lang.annotation.Target;
        /**
        ?*?class_name:?ScheduleManage
        ?*?describe:???用于控制定時任務(wù)的開啟與關(guān)閉
        ?*?對應(yīng)切面
        ?*?creat_user:?wenl
        ?*?creat_time:??2018/11/10?18:45
        ?**/

        @Target(ElementType.METHOD)
        @Retention(RetentionPolicy.RUNTIME)
        public?@interface???AspectLog?{
        }

        2.2定義配置文件對應(yīng)類

        package?com.shanyuan.autoconfiguration.aspectlog;
        import?org.springframework.boot.context.properties.ConfigurationProperties;

        @ConfigurationProperties("aspectLog")
        public?class?AspectLogProperties?{
        ????private?boolean?enable;
        ????public?boolean?isEnable()?{
        ????????return?enable;
        ????}
        ????public?void?setEnable(boolean?enable)?{
        ????????this.enable?=?enable;
        ????}
        }

        2.3定義自動配置類

        package?com.shanyuan.autoconfiguration.aspectlog;

        import?org.aspectj.lang.ProceedingJoinPoint;
        import?org.aspectj.lang.annotation.Around;
        import?org.aspectj.lang.annotation.Aspect;
        import?org.slf4j.Logger;
        import?org.slf4j.LoggerFactory;
        import?org.springframework.boot.autoconfigure.condition.*;
        import?org.springframework.context.annotation.Configuration;
        import?org.springframework.context.annotation.EnableAspectJAutoProxy;
        import?org.springframework.core.PriorityOrdered;

        @Aspect
        @EnableAspectJAutoProxy(exposeProxy?=?true,?proxyTargetClass?=?true)
        @Configuration
        @ConditionalOnProperty(prefix?=?"aspectLog",?name?=?"enable",
        ?????????????????????havingValue?=?"true",?matchIfMissing?=?true)
        public?class?AspectLogAutoConfiguration?implements?PriorityOrdered?{

        ????protected?Logger?logger?=?LoggerFactory.getLogger(getClass());

        @Around("@annotation(com.shanyuan.autoconfiguration.aspectlog.AspectLog)?")
        ????public?Object?isOpen(ProceedingJoinPoint?thisJoinPoint)?
        ????????????????????????????????????????throws?Throwable?
        {
        ????????//執(zhí)行方法名稱?
        ????????String?taskName?=?thisJoinPoint.getSignature()
        ????????????.toString().substring(
        ????????????????thisJoinPoint.getSignature()
        ????????????????????.toString().indexOf("?"),?
        ????????????????????thisJoinPoint.getSignature().toString().indexOf("("));
        ????????taskName?=?taskName.trim();
        ????????long?time?=?System.currentTimeMillis();
        ????????Object?result?=?thisJoinPoint.proceed();
        ????????logger.info("method:{}?run?:{}?ms",?taskName,?
        ????????????????????????????(System.currentTimeMillis()?-?time));
        ????????return?result;
        ????}
        ????@Override
        ????public?int?getOrder()?{
        ????????//保證事務(wù)等切面先執(zhí)行
        ????????return?Integer.MAX_VALUE;
        ????}
        }

        配置類簡要說明:

        @ConditionalOnProperty(prefix?=?"aspectLog",?name?=?"enable",havingValue?=?"true",?matchIfMissing?=?true)

        當(dāng)配置文件有aspectLog.enable=true時開啟,如果配置文件沒有設(shè)置aspectLog.enable也開啟。

        第三步META-INF/spring.factories

        META-INF/spring.factories是spring的工廠機(jī)制,在這個文件中定義的類,都會被自動加載。多個配置使用逗號分割,換行用\

        如果有興趣可以查看這2篇blog:

        2.@Enable驅(qū)動原理(設(shè)置連接)

        3.@EnableAutoConfiguration處理邏輯(設(shè)置連接)

        org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
        com.shanyuan.autoconfiguration.aspectlog.AspectLogAutoConfiguration

        第四步打包測試

        這是我們最終的目錄結(jié)構(gòu)

        在IDEA中,進(jìn)行mvn intall

        打包完成后,在其他項(xiàng)目中的pom中引入進(jìn)行測試


        參考資料

        • https://docs.spring.io/spring-boot/docs/2.1.15.RELEASE/reference/html/boot-features-developing-auto-configuration.html#boot-features-custom-starter


        往期推薦

        說說你知道的數(shù)據(jù)庫常用架構(gòu)方案?

        ArrayList 為什么要實(shí)現(xiàn) RandomAccess 接口?

        為什么阿里規(guī)定需要在事務(wù)注解@Transactional中指定rollbackFor?

        面試:說說參數(shù)驗(yàn)證 @Validated 和 @Valid 的區(qū)別?

        SQL查找是否"存在",別再count了!


        歡迎加入我的知識星球,聊技術(shù)、說職場、侃社會。



        星球兩大分享內(nèi)容

        瀏覽 67
        點(diǎn)贊
        評論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報
        評論
        圖片
        表情
        推薦
        點(diǎn)贊
        評論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            国产精品嫩草影院ccm | 天天综合性网 | 国产精品黑丝在线观看 | 国产美女啪 | 韩国三色片 | 九哥操逼视频 | 国产AAA级黄片 | 青青草视频免费看 | 草草草视频在线观看 | 欧美亚洲图片小说 |