springBoot @Enable* 注解的使用
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加载配置
@target({elementtype.type}) @retention(retentionpolicy.runtime) @documented @inherited @autoconfigurationpackage @import({autoconfigurationimportselector.class}) public @interface enableautoconfiguration
可以看到@import中,其实是导入了一个autoconfigurationimportselector的类。最关键的是,该类实现了接口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); }
这是importselector的描述,大概意思就是,该方法返回的bean 会自动的被注入,被spring所管理。
接着来看 autoconfigurationimportselector中 selectimports 的实现
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 一样。
public interface importbeandefinitionregistrar { public void registerbeandefinitions( annotationmetadata importingclassmetadata, beandefinitionregistry registry); }
在registerbeandefinitions方法中,可以用beandefinitionregistry 注入我们想要注入的bean。
代码示例:
使用@import编写自己的@enable
1、创建2个测试bean
public class role { } public class user { }
2、自定义enable注解
@target({elementtype.type}) @retention(retentionpolicy.runtime) @documented @import(myenableautoconfig.class) public @interface enablebean { }
3、实现自己的enableautoconfiguration类
public class myenableautoconfig implements importselector{ @override public string[] selectimports(annotationmetadata importingclassmetadata) { return new string[]{"com.xhn2.role","com.xhn2.user"}; } }
4、编写启动类
@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
<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
@configuration public class mytest { @bean public runnable runnable() { return ()->{}; } }
在resources下新建meta-inf/spring.factories文件,加入以下配置
org.springframework.boot.autoconfigure.enableautoconfiguration=com.edu.mytest
3、将项目安装到本地maven仓库:mvn install
4、主工程引入刚才安装到本地的jar。
<dependency> <groupid>org.csp</groupid> <artifactid>hello</artifactid> <version>1.0.0</version> </dependency>
5、获取刚才配置的runnable
@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
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。