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