中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

如何自定義springboot starter

發布時間:2021-09-29 17:28:03 來源:億速云 閱讀:134 作者:柒染 欄目:大數據

如何自定義springboot starter,相信很多沒有經驗的人對此束手無策,為此本文總結了問題出現的原因和解決方法,通過這篇文章希望你能解決這個問題。

自定義 springboot starter

搞一個demo看看,demo實現了兩個功能:

  1. 使用Aspectj方式的aop,來實現對某類函數參數監控;

  2. 定義一個自己的配置類,讀取我們在yml或properties里面配置的參數,同時提供一個service,用來獲取我們讀取的結果。

這里是示例工程starter.

starter

看了自動配置原理之后,應該知道META-INF/spring.facotires這個家伙是配置的重點了吧,我們很多個的東西都是在這個里頭。因此,我們自己的stater當然也少不了這個配置文件,先貼個工程結構。

spring-boot-myaop-starter
├─ pom.xml
├─ spring-boot-myaop-starter.iml
└─ src/main
        ├─ java
        └─ resources
            └─ META-INF
                └─ spring.factories

AOP部分

先按照正常工程把一些配置都配好,先來寫一個AspectJ的。

package com.wt.myaop.aspect;
@Aspect
@Component
public class MyAspect {

    @Pointcut("@annotation(myAnno)")
    public void myAspectPointCut(MyAopAnnotation myAnno) {
    }

    @Before("myAspectPointCut(myAnno)")
    public void performanceTrance2(JoinPoint joinPoint, MyAopAnnotation myAnno) throws Throwable {
        System.out.println("--------------myaop-starter args monitor start-----------------");
        Object[] args = joinPoint.getArgs();
        Class<?>[] types = myAnno.argTypes();
        for (int i = 0; i < Math.min(args.length, types.length); i++) {
            System.out.println("type:" + types[i] + "<--->arg:" + args[i]);
        }
        System.out.println("--------------myaop-starter args monitor end-----------------");
    }
}

我們這里使用的是@Before,在這個方法里面獲取到所有參數,然后將所有參數的類型和值都打印出來,方法前后輸出日志,比較簡單。

然后來看pointCut,這是一個基于注解的,這樣其他項目引入這個starter的時候就可以直接以注解來使用,對其他項目不具有侵入性。所以,我們還需要定義一個注解。

package com.wt.myaop.anno;

@Target(ElementType.METHOD)
@Documented
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAopAnnotation {
    Class<?>[] argTypes() default {};
}

注解里面有屬性,用來定義方法參數的類型順序,當然也可以不需要,放這里只是為了方便。

屬性讀取部分

屬性的讀取我們需要用到一個springboot的注解@ConfigurationProperties.來看看這個配置類,為了縮短代碼長度,都沒有貼getter/setter方法哦。

package com.wt.myaop.config;

@ConfigurationProperties(prefix = MyConfig.MY_PREFIX)
public class MyConfig {
    public static final String MY_PREFIX = "myconfig";
    /**
     * 不加該注解也能正常得到值
     */
    @NestedConfigurationProperty
    private UserConfig user;

    private String job;
}

代碼中我們定義了一個常量MY_PREFIX,這個是配置文件中的前綴,springboot會讀取這個前綴的配置來注入到這個實體當中,當然,配置肯定不會是在我們這個starter項目中來配置,是我們實際使用的project中配置的哦!要不然我還不如直接寫死,對吧,嘻嘻

除了基本屬性之外,還提供了一個實體屬性,UserConfig。來看看這個東西吧。

package com.wt.myaop.config;

public class UserConfig {
    private String username;
    private Integer age;
    private String sex;
}

配置信息的接收實體有了,我們現在來定義一個service,這個service的作用就是注入這個實體,然后輸出配置信息,以檢查我們的配置生效了。service的接口就不貼了哈,只貼實現類了。

package com.wt.myaop.service;

public class MyConfigServiceImpl implements MyConfigService {
    private final MyConfig myconfig;
    public MyConfigServiceImpl(MyConfig myConfig) {
        this.myconfig = myConfig;
    }
    @Override
    public void printMyConfig() {
        System.out.println(myConfig);
    }
}

看構造方法和屬性,構造方法注入了我們的配置,當然,我們如果需要使用這個service,我們就需要手動將這個配置注入進來,以確保service實例化時,myconfig不會為null,里面的方法很簡單,僅僅打印了我們的配置類MyConfig。

starter像這樣就算完了嗎?當然沒有,可以感受到以上這些其實都跟普通的project的配置沒有太多差別,很簡單。

回憶一下我們自動配置的核心是不是叫xxxAutoConfiguration的東西呢?spring.vactories中的哦!

好了,來吧,開始定義我們自己的AutoConfiguration。

package com.wt.myaop.autoconfig;

@Configuration
@ComponentScan({"com.wt.myaop.aspect"})
@AutoConfigureAfter(AopAutoConfiguration.class)
@EnableConfigurationProperties(MyConfig.class)
public class MyArgsMonitorAopAutoConfig {

    private MyConfig myConfig;

    public MyArgsMonitorAopAutoConfig(MyConfig myConfig) {
        this.myConfig = myConfig;
    }

    @Bean
    public MyConfigService getMyConfigService(){
        return new MyConfigServiceImpl(myConfig);
    }

}

我們現在來研究一下這個類都有什么。

@Configuration: 表明這個類是一個配置類;
@ComponentScan: 指出需要掃描的包,可以看到上面掃描的包中包含了Aspect注解的配置,當然使用aop這部分是必不可少的;
@AutoConfigureAfter: 指出當前類需要再某個自動配置完成之后才開始配置;
@EnableConfigurationProperties: 為@ConfigurationProperties注解提供支持,什么意思呢;
	解釋一下這個,把@ConfigurationProperties標注的類(MyConfig)注冊成bean,以支持依賴注入,本身這些類
	是不會被注冊成bean的,當然我們可以在配置類上加@Component注解。使用這個注解可以在我們需要某個配置類
	注冊成bean的時候,就使用,侵入性小,避免了配置類上加@Component注解。

從上面代碼中可以看到我們的配置類MyConfig通過構造方法被注入到了MyArgsMonitorAopAutoConfig當中,而MyArgsMonitorAopAutoConfig是一個配置類,里面通過@Bean的方式配置了MyConfigService。

看起來很簡答吧,實際上也很簡單,autoConfiguration的配置類就好了,引入這個類,就相當于引入了一個Myconfig的配置類,和一個我們能夠使用的MyConfigService

自動配置的類有了,需要放到spring.factories中才能生效。

# META-INF/spring.factories
org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.wt.myaop.autoconfig.MyArgsMonitorAopAutoConfig

這樣starter部分就算是完成了。

Tips: 自動配置其實很簡單,把需要的配置都放到一個叫做starter的工程里面,然后創建一個XxxAutoConfiguration的自動配置類,把需要的配置都放到這個類里面配置好。最后把這個自動配置類加到META-INF/spring.factories中就行了,是不是很容易,嘻嘻。

demo

demo其實也是使用的之前分析源碼那個工程,下面有地址。重點來配置和啟動一下我們自己的starter。

這里是示例工程demo.

有了starter之后,使用mvn clean install命令將其jar安裝到本地。

在demo工程中引入這個依賴。

<dependency>
    <groupId>com.wt.starter</groupId>
    <artifactId>spring-boot-myaop-starter</artifactId>
    <version>1.0-SNAPSHOT</version>
</dependency>

使用MyConfig配置

我們starter里面有個MyConfig的配置對吧,好了,現在我們可以在yml或者properties文件中來定義了。我這里用的是yml哈。

myconfig:
  job: programer
  user:
    username: wt
    age: 25
    sex: real_man

注意我們的前綴是myconfig,下面的job和user都是實體類MyConfig的屬性,因為user是個實體了類,因此下面也列出了它的屬性username,age,sex.(可以去前面的MyConfig和UserConfig兩個實體的屬性進行對比)。

使用參數監控AOP

starter中除了上面的MyConfig之外,還有個aop監控參數的功能,我們馬上把它用起來。

先定義一個service,接口就不貼了

@Service
public class MyStarterServiceImpl implements MyStarterService {

    @Override
    @MyAopAnnotation(argTypes = {String.class})
    public void helloStarter(String msg, Long currentTime) {
        System.out.println("----hello starter,msg = " + msg + ",currentTime = " + currentTime);
    }
}

方法加上了注解MyAopAnnotation,為了被starter當中的aop攔截到。

再來定義一個controller用來測試。

@RestController
@RequestMapping("/starter")
public class MyStarterController {

    @Autowired
    private MyConfigService myConfigService;

    @Autowired
    private MyStarterService myStarterService;

    @RequestMapping("/test")
    public Object starter() {
        myConfigService.printMyConfig();
        myStarterService.helloStarter("wt", System.currentTimeMillis());
        return "success";
    }
}

注意區分一下,MyConfigService是我們starter里面的,MyStarterService是我們demo工程里面的。

現在啟動工程,訪問http://127.0.0.1:8080/starter/test試試!

來看看輸出(復制了輸出,沒有使用截圖):

MyConfig{user=UserConfig{username='wt', age=25, sex='real_man'}, job='programer'}
------------------myaop-starter args monitor start--------------------
type:class java.lang.String<--->arg:wt
------------------myaop-starter args monitor end--------------------
----hello starter,msg = wt,currentTime = 1564472340205

第一行是 myConfigService.printMyConfig()的輸出,他輸出了我們的在yml中的配置,這個輸出說明了我們的配置被成功賦值給MyConfig了。說明我們的config生效了。

第二行和第四行是starter當中aop部分@Before方法的前后輸出,中間第三行輸出了參數類型String和參數的值wt,因為我們注解上只指定了一個String.class,因此在這里沒有把第二個參數也輸出來,具體邏輯就去看starter當中aop的那個@Before的方法了。

最后一行是被加強的方法的輸出,打印了msg和currentTime。

現在可以來想象一下springboot在yml或properties文件中的Datasource等配置咯!

看到這里starter部分就算結束了

看完上述內容,你們掌握如何自定義springboot starter的方法了嗎?如果還想學到更多技能或想了解更多相關內容,歡迎關注億速云行業資訊頻道,感謝各位的閱讀!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

庆安县| 永州市| 英山县| 张家川| 吉林省| 巴南区| 十堰市| 星子县| 巩留县| 布拖县| 铜陵市| 安龙县| 库车县| 蚌埠市| 河东区| 张家界市| 襄垣县| 金川县| 大连市| 偃师市| 崇信县| 兴隆县| 夹江县| 叶城县| 枣庄市| 苍溪县| 佳木斯市| 溆浦县| 常山县| 宜兴市| 定安县| 阳原县| 湘阴县| 玛纳斯县| 晋城| 江安县| 屯昌县| 长沙市| 龙泉市| 华容县| 文山县|