1、為什么使用@springbootapplication注解,即可做到自動配置?
答:@springbootapplication,內部起作用的注解其實有3個。@enableautoconfiguration,@componentscan,@configuration。這篇文章主要是講解@enablexx注解
2、為什么使用了@enableautoconfiguration。當使用了@configurationproperties時,即可自動導入.yml 或者.properties里面的配置項?
答:在@enableautoconfiguration內部,使用了@import注解。導入autoconfigurationimportselector幫助springboot將符合條件的configuration加載到ioc容器中。但是內部其實使用了springfactoriesloader來完成。類似與java spi的功能
,即從/meta-inf/spring.factories加載配置
1
2
3
4
5
6
7
|
@target ({elementtype.type}) @retention (retentionpolicy.runtime) @documented @inherited @autoconfigurationpackage @import ({autoconfigurationimportselector. class }) public @interface enableautoconfiguration |
可以看到@import中,其實是導入了一個autoconfigurationimportselector的類。最關鍵的是,該類實現了接口importselector
1
2
3
4
5
6
7
8
|
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); } |
這是importselector的描述,大概意思就是,該方法返回的bean 會自動的被注入,被spring所管理。
接著來看 autoconfigurationimportselector中 selectimports 的實現
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
public string[] selectimports(annotationmetadata annotationmetadata) { if (! this .isenabled(annotationmetadata)) { return no_imports; } else { autoconfigurationmetadata autoconfigurationmetadata = autoconfigurationmetadataloader.loadmetadata( this .beanclassloader); annotationattributes attributes = this .getattributes(annotationmetadata); list<string> configurations = this .getcandidateconfigurations(annotationmetadata, attributes); configurations = this .removeduplicates(configurations); set<string> exclusions = this .getexclusions(annotationmetadata, attributes); this .checkexcludedclasses(configurations, exclusions); configurations.removeall(exclusions); configurations = this .filter(configurations, autoconfigurationmetadata); this .fireautoconfigurationimportevents(configurations, exclusions); return stringutils.tostringarray(configurations); } } |
代碼都寫得很清楚。就不解釋了。
在@import中,可以看到 有個鏈接指向了 importbeandefinitionregistrar。這同樣是一個接口,作用跟 importselector 一樣。
1
2
3
4
5
|
public interface importbeandefinitionregistrar { public void registerbeandefinitions( annotationmetadata importingclassmetadata, beandefinitionregistry registry); } |
在registerbeandefinitions方法中,可以用beandefinitionregistry 注入我們想要注入的bean。
代碼示例:
使用@import編寫自己的@enable
1、創建2個測試bean
1
2
3
4
5
|
public class role { } public class user { } |
2、自定義enable注解
1
2
3
4
5
6
|
@target ({elementtype.type}) @retention (retentionpolicy.runtime) @documented @import (myenableautoconfig. class ) public @interface enablebean { } |
3、實現自己的enableautoconfiguration類
1
2
3
4
5
6
|
public class myenableautoconfig implements importselector{ @override public string[] selectimports(annotationmetadata importingclassmetadata) { return new string[]{ "com.xhn2.role" , "com.xhn2.user" }; } } |
4、編寫啟動類
1
2
3
4
5
6
7
8
9
|
@enablebean @componentscan ( "com.xhn2" ) public class main { public static void main(string[] args) { configurableapplicationcontext context = springapplication.run(main. class , args); system.out.println(context.getbean(user. class )); system.out.println(context.getbean(role. class )); } } |
5、運行結果
com.xhn2.user@496bc455
com.xhn2.role@59402b8f
控制臺成功打印。
代碼示例2,自動裝配第3方jar包的bean
新建maven工程
1、pom.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
<modelversion> 4.0 . 0 </modelversion> <groupid>org.csp</groupid> <artifactid>hello</artifactid> <version> 1.0 . 0 </version> <properties> <maven.compiler.source> 1.8 </maven.compiler.source> <maven.compiler.target> 1.8 </maven.compiler.target> <project.build.sourceencoding>utf- 8 </project.build.sourceencoding> </properties> <dependencies> <dependency> <groupid>org.springframework</groupid> <artifactid>spring-context</artifactid> <version> 4.3 . 17 .release</version> </dependency> </dependencies> |
2、編寫configuration
1
2
3
4
5
6
7
|
@configuration public class mytest { @bean public runnable runnable() { return ()->{}; } } |
在resources下新建meta-inf/spring.factories文件,加入以下配置
1
|
org.springframework.boot.autoconfigure.enableautoconfiguration=com.edu.mytest |
3、將項目安裝到本地maven倉庫:mvn install
4、主工程引入剛才安裝到本地的jar。
1
2
3
4
5
|
<dependency> <groupid>org.csp</groupid> <artifactid>hello</artifactid> <version> 1.0 . 0 </version> </dependency> |
5、獲取剛才配置的runnable
1
2
3
4
5
6
7
8
|
@springbootapplication public class main { public static void main(string[] args) { springapplication application = new springapplication(main. class ); configurableapplicationcontext context = application.run(args); system.out.println(context.getbean(runnable. class )); } } |
6、控制臺打印
com.edu.mytest$$lambda$153/284686302@2c07545f
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。
原文鏈接:https://segmentfault.com/a/1190000015188776