成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

SpringBoot 手動配置 @Enable 的秘密

開發 后端
今天我們就來探究一下這個 @EnableXXX給我們做了哪些工作,或者我們應該怎么通過自定義的方式開發我們自己的功能模塊。

在 Spring Boot開發過程中,我們經常會看到使用 @EnableXXX來激活我們某一個功能性的模塊,通過類注解激活后我們就能使用所激活的配置給我們帶來的功能。

今天我們就來探究一下這個 @EnableXXX給我們做了哪些工作,或者我們應該怎么通過自定義的方式開發我們自己的功能模塊。

演示環境

  • IntelliJ IDEA 2020.2.1 (Community Edition)
  • Maven 3.5.4
  • Spring Boot 2.1.1.RELEASE

走進源碼

在 SpringBoot中 @Enable的實現方式用兩種。

一種是注解驅動的方式,我們以 @EnableWebMvc為例進行探究;

另外一種是接口編程的方式,我們以 @EnableCaching為例進行探究。

1、注解驅動方式(@EnableWebMvc)

在 Spring Boot項目中,當我們可以使用 @EnableWebMvc注解用來激活我們的 Spring MVC相關的配置,接下來進入源碼一探究竟。

@Retention(RetentionPolicy.RUNTIME)  
@Target(ElementType.TYPE)
@Documented
@Import(DelegatingWebMvcConfiguration.class)
public @interface EnableWebMvc {
}

通過觀察上面的源碼,我們就可以大膽的猜測,其實使用 @EnableWebMvc注解的作用就是導入 DelegatingWebMvcConfiguration.class這個類,接下來我們就進入這個類看看。

@Configuration  
public class DelegatingWebMvcConfiguration extends WebMvcConfigurationSupport {
........
@Override
protected void addInterceptors(InterceptorRegistry registry) {
this.configurers.addInterceptors(registry);
}
@Override
protected void addResourceHandlers(ResourceHandlerRegistry registry) {
this.configurers.addResourceHandlers(registry);
}
........
}

進入到這個類中我們發現了這個 @Configuration注解,到這兒我們好像明白了寫什么。首先這個 DelegatingWebMvcConfiguration類繼承了 WebMvcConfigurationSupport類,重寫了里面的關于 WebMvc的相關配置,然后作為一個配置類加載到我們的 Spring容器中。至此來實現啟動(激活)WebMvc模塊。

2、接口編程的方式(@EnableCaching)

在 Spring Boot項目中,當我們可以使用 @EnableCaching注解用來激活我們的緩存相關的配置,接著進入源碼看看到底做了什么。

@Target(ElementType.TYPE)  
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(CachingConfigurationSelector.class)
public @interface EnableCaching {
boolean proxyTargetClass() default false;
AdviceMode mode() default AdviceMode.PROXY;
int order() default Ordered.LOWEST_PRECEDENCE;
}

這里 @EnableCaching同樣是使用 @Import導入了一個配置類,而它導入的是 CachingConfigurationSelector,接著我進入這個類看一看。

public class CachingConfigurationSelector extends AdviceModeImportSelector<EnableCaching> {  
.....
@Override
public String[] selectImports(AdviceMode adviceMode) {
switch (adviceMode) {
case PROXY:
return getProxyImports();
case ASPECTJ:
return getAspectJImports();
default:
return null;
}
}
.....
}

發現其實這個類沒有被注解標注,但是它繼承了 AdviceModeImportSelector<enablecaching>,而這個類又繼承了 ImportSelector,并且我們可以看看 ImportSelector的代碼:

public interface ImportSelector {  
/**
* Select and return the names of which class(es) should be imported based on
* the {@link AnnotationMetadata} of the importing @{@link Configuration} class.
*/
String[] selectImports(AnnotationMetadata importingClassMetadata);
}

這個類中只用一個方法,那就是 selectImports。也就是說當我們重寫了這個方法之后,我們可以在方法中添加自己的邏輯判斷,來決定最后導入哪些配置類。這樣就可以實現靈活的加載配置。這個方法的返回值 String[]里面存放的是所有復合條件的配置類的全路徑信息。

自定義實現

通過上面的分析我們已經完成了對 @EnableXXX套路的了解,接下來我們自己動手實現下。首先需要準備一個 Spirng Boot的項目,這里我已經準備好了。

1、注解驅動方式的自定義實現

根據我們分析源碼的步驟我們首先需要準備一個配置類。接下來在 configuration包下,創建一個 HelloConfiguration。代碼如下:

/**  
* Hello模塊的配置
*/
@Configuration
public class HelloConfiguration {
@Bean
public String hello() { // method name is bean name
System.out.println("Bean : hello is loading.");
return "hello word !";
}
}

這里被 @Bean標注的方法,方法名會作為 bean對象的名稱。而且當該 bean被加載的時候我們還會在控制臺輸出一段話 Bean : hello is loading.。

配置類我們已經準備好了,接下來我們在 annotation包中編寫激活配置的注解。

/**  
* 激活Hello模塊配置
*
* @author Jerome Zhu
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Import(HelloConfiguration.class) // 模塊裝配:注解驅動實現
public @interface EnableHello {
}

最后我們在 bootstrap包中編寫驗證我們 @EnableHello模塊的啟動類。

/**  
* 驗證自定義 {@link EnableHello} 模塊化裝配
*
* @author Jerome Zhu
*/
@EnableHello
public class EnableHelloBootstrap {
public static void main(String[] args) {
ConfigurableApplicationContext context = new SpringApplicationBuilder(EnableHelloBootstrap.class)
.web(WebApplicationType.NONE)
.run(args);
String helloBean = context.getBean("hello", String.class);
System.out.println("hello Bean: " + helloBean);
context.close();
}
}

我們在我們啟動類上標注了 @EnableHello來激活我們的 Hello模塊,并且在 Spring Boot項目啟動后,獲取到了應用的上下文 ConfigurableApplicationContext。然后我們根據我們注入的 bean的名字 hello來獲取 bean,接著打印 bean的內容,最后關閉上下文。

我們啟動程序后,可以在控制臺中看到這樣兩行輸出:

Bean : hello is loading.  
hello Bean: hello word !

這剛好就是我們配置的內容,到這兒我們就完成了基于注解驅動方式激活(啟動)配置。

2、接口編程方式自定義實現

根據我們讀過源碼后,我們首先最重要的是有一個繼承 ImportSelector的實現類。在 annotation包中創建一個 HelloImportSelector配置類。

/**  
* Hello {@link ImportSelector} 的實現
*/
public class HelloImportSelector implements ImportSelector {
private final String key = "jerome";
@Override
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
if ("jerome".equals(key)) {
return new String[]{HelloJeromeConfiguration.class.getName()};
}
return new String[]{HelloConfiguration.class.getName()};
}
}

這里為了體現出 selectImports方法的作用,我們在本類中添加一個 key字段。當 key的值為 jerome的時候我們去加載 HelloJeromeConfiguration這個配置類。首先看一個這個配置類的內容。

/**  
* Hello模塊的配置
*
* @author Jerome Zhu
*/
@Configuration
public class HelloJeromeConfiguration {
@Bean
public String hello() { // method name is bean name
System.out.println("Bean : hello is loading.");
return "hello jerome !";
}
}

加載這個配置類后 bean的名字還是 hello但是內容變成了 hello jerome !。接著我們對 @EnableHello注解進行改造改造成 @EnableHellos。

/**  
* 激活Hellos模塊配置
*
* @author Jerome Zhu
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Import(HelloImportSelector.class) // 模塊裝配:接口驅動實現 優點可選bean
public @interface EnableHellos {
}

這里使用了 HelloImportSelector來實現我們的模塊裝配。

這里 @EnableHellos可能不符合命名規范,這里只做演示使用,不要噴我。

最后我們在 bootstrap包中編寫驗證我們 @EnableHello模塊的啟動類。

/**  
* 驗證自定義 {@link EnableHellos} 模塊化裝配
*
* @author Jerome Zhu
*/
@EnableHellos
public class EnableHellosBootstrap {
public static void main(String[] args) {
ConfigurableApplicationContext context = new SpringApplicationBuilder(EnableHellosBootstrap.class)
.web(WebApplicationType.NONE)
.run(args);
String helloBean = context.getBean("hello", String.class);

System.out.println("hello Bean: " + helloBean);
context.close();
}
}

這里和基于注解驅動方式激活(啟動)配置的驗證方法一樣,我就是直接拷貝的,主要修改了 @EnableHellos這個激活注解。

我們啟動程序后,可以在控制臺中看到這樣兩行輸出:  

Bean : hello is loading.  
hello Bean: hello jerome !

這剛好就是我們配置的內容,到這兒我們就完成了基于接口編程方式激活(啟動)配置。

總結

我們通過上面了解了 @EnableXXX的兩種實現方式。其中基于注解驅動方式激活(啟動)配置的方式是相對方便的一個實現,需要激活什么就直接導入該配置類即可;而基于接口編程方式激活(啟動)配置的方式相對更加靈活,可以根據自定義的規則來選擇激活哪些配置類,不激活哪些配置類,這是一種比較靈活的方式,方便我們對其進行擴展。

總之這兩種方式都是手動激活的方式,換言之我們需要在啟動類上添加 @Enable***的注解,來手動激活配置,這種方式在某些場景并不是很方便。

責任編輯:龐桂玉 來源: Java知音
相關推薦

2021-09-22 05:55:18

Eslint disble算法

2021-05-13 16:34:20

TCP客戶端

2020-06-19 10:02:53

JVMJava語言

2023-07-31 07:25:27

2017-05-16 09:56:44

2011-08-29 09:59:26

2020-09-15 12:57:46

C 語言浮點數內存

2013-11-27 11:04:05

震網病毒震網Stuxnet

2019-12-05 12:11:37

DevOps開發應用程序

2020-04-15 13:55:28

Kubernetes容器

2021-08-11 22:18:43

Socket函數監聽

2022-09-19 07:33:17

Spring@Enable注解

2020-02-28 07:46:05

物聯網產品開發IOT

2012-04-08 14:47:52

iPad

2019-10-24 10:04:33

技術債務開發軟件

2011-01-05 15:29:03

職場

2013-10-16 09:28:14

亞馬遜AWSSDN

2024-09-02 09:06:34

2012-06-29 10:22:36

系統架構

2022-12-29 08:00:00

Transforme架構深度學習
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 一本色道久久综合亚洲精品高清 | 第一区在线观看免费国语入口 | 欧美精品在线免费观看 | 羞羞视频在线网站观看 | 国内精品久久久久 | 国产精品成人一区二区 | 在线一区 | 91天堂| 黄色大片免费网站 | 高清久久久 | 九九热这里 | 中文字幕在线三区 | 在线观看国产精品视频 | 亚洲 成人 av | 黄网站免费入口 | 国产福利在线看 | 麻豆精品一区二区三区在线观看 | 免费观看一级视频 | 国产精品免费看 | 日本精品视频 | 免费一区二区 | 国产激情一区二区三区 | 99精品免费视频 | 久久久久av| 国产久 | 成人精品一区二区三区 | 欧美不卡在线 | 成人欧美一区二区三区黑人孕妇 | 国产高清性xxxxxxxx | 成人午夜网站 | 国产精品一二三区 | 免费成人av| 亚洲最大av| 国产一区二区精品在线 | 亚洲国产精品一区二区第一页 | 尤物在线视频 | 欧美在线观看一区 | 欧美视频成人 | 在线观看av不卡 | 玖玖免费| 久久精品男人的天堂 |