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