springboot中的@import注解怎么使用-mile米乐体育
springboot中的@import注解怎么使用
这篇文章主要介绍了springboot中的@import注解怎么使用的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇springboot中的@import注解怎么使用文章都会有所收获,下面我们一起来看看吧。
一、 @import引入普通类
@import引入普通的类可以帮助我们把普通的类定义为bean。@import可以添加在@springbootapplication(启动类)、@configuration(配置类)、@component(组件类)对应的类上。
注意:@restcontroller、@service、@repository都属于@component
@springbootapplication@import(importbean.class)//通过@import注解把importbean添加到ioc容器里面去publicclassmybatisapplication{publicstaticvoidmain(string[]args){springapplication.run(mybatisapplication.class,args);}}
二、 @import引入配置类(@configuration修饰的类)
@import除了可以把普通的类定义为bean,@import还可以引入一个@configuration修饰的类(引入配置类),从而把让配置类生效(配置类下的所有bean添加到ioc容器里面去)。在自定义starter的时候经常会用到。
如果配置类在标准的springboot包结构下(springbootapplication启动类包的根目录下)。是不需要@import导入配置类的,springboot自动帮做了。上面的情况一般用于@configuration配置类不在标准的springboot包结构下面。所以一般在自定义starter的时候用到。
@configuration(proxybeanmethods=false)@import({//import了两个哈xxxdataconfiguration.xxxpartoneconfiguration.class,xxxdataconfiguration.xxxparttwoconfiguration.class})publicclassxxxdataautoconfiguration{}publicclassxxxdataconfiguration{@configuration(proxybeanmethods=false)staticclassxxxpartoneconfiguration{@bean@conditionalonmissingbeanpublicbeanforiocbeanforioc(){returnnewbeanforioc();}}@configuration(proxybeanmethods=false)staticclassxxxparttwoconfiguration{/***省略了@bean的使用*/}}
三 、@import引入importselector的实现类
@import还可以引入importselector的实现类,把importselector接口selectimports()方法返回的class名称都定义为bean。注意selectimports()方法的参数annotationmetadata,通过这个参数我们可以获取到@import标注的class的各种信息。这一点特别有用,用于做一些参数的传递。在springboot的自动化配置和@enablexxx(功能性注解)都有它的存在。
publicinterfaceimportselector{/***用于指定需要注册为bean的class名称*当在@configuration标注的class上使用@import引入了一个importselector实现类后,会把实现类中返回的class名称都定义为bean。**通过其参数annotationmetadataimportingclassmetadata可以获取到@import标注的class的各种信息,*包括其class名称,实现的接口名称、父类名称、添加的其它注解等信息,通过这些额外的信息可以辅助我们选择需要定义为springbean的class名称*/string[]selectimports(annotationmetadataimportingclassmetadata);}
关于@import引入importselector的实现类的使用,我们举几个简单的使用场景(实际开发肯定比这复杂的多的)。
3.1 静态import场景(注入已知的类)
静态场景(注入已知的类),很简单通过实现importselector类把我们需要定义为bean的类直接返回就好, 比如下面的例子。我们来一个enablexxx的注解,通过xxxconfigurationselector注入一个已知的类xxx。
/***xxxconfigurationselector一定要配合@import使用*/publicclassxxxconfigurationselectorimplementsimportselector{@override@nonnullpublicstring[]selectimports(@nonnullannotationmetadataimportingclassmetadata){//把xxx对应的类,定义为beanreturnnewstring[]{xxx.class.getname()};}}/***注意@import(xxxconfigurationselector.class)*/@target(elementtype.type)@retention(retentionpolicy.runtime)@documented@import(xxxconfigurationselector.class)public@interfaceenablexxx{}@springbootapplication@enablexxx//使之生效publicclassmybatisapplication{publicstaticvoidmain(string[]args){springapplication.run(mybatisapplication.class,args);}}
3.2 动态import场景(注入指定条件的类)
我们做一个这样的功能,我们需要把指定包路径下所有实现了helloservice接口的类做为bean添加到ioc容器里面去。@componentscan注解用来帮我们指定路径。具体实现如下:
publicinterfacehelloservice{voidfunction();}publicclassdynamicselectimportimplementsimportselector{/***dynamicselectimport需要配合@import()注解使用**通过其参数annotationmetadataimportingclassmetadata可以获取到@import标注的class的各种信息,*包括其class名称,实现的接口名称、父类名称、添加的其它注解等信息,通过这些额外的信息可以辅助我们选择需要定义为springbean的class名称*/@overridepublicstring[]selectimports(annotationmetadataimportingclassmetadata){//第一步:获取到通过componentscan指定的包路径string[]basepackages=null;//@import注解对应的类上的componentscan注解if(importingclassmetadata.hasannotation(componentscan.class.getname())){map
annotationattributes=importingclassmetadata.getannotationattributes(componentscan.class.getname());basepackages=(string[])annotationattributes.get("basepackages");}if(basepackages==null||basepackages.length==0){//componentscan的basepackages默认为空数组stringbasepackage=null;try{//@import注解对应的类的包名basepackage=class.forname(importingclassmetadata.getclassname()).getpackage().getname();}catch(classnotfoundexceptione){e.printstacktrace();}basepackages=newstring[]{basepackage};}//第er步,知道指定包路径下所有实现了helloservice接口的类(classpathscanningcandidatecomponentprovider的使用)classpathscanningcandidatecomponentproviderscanner=newclasspathscanningcandidatecomponentprovider(false);typefilterhelloservicefilter=newassignabletypefilter(helloservice.class);scanner.addincludefilter(helloservicefilter);set classes=newhashset<>();for(stringbasepackage:basepackages){scanner.findcandidatecomponents(basepackage).foreach(beandefinition->classes.add(beandefinition.getbeanclassname()));}//第三步,返回添加到ioc容器里面去returnclasses.toarray(newstring[0]);}}@configuration@componentscan("com.tuacy.collect.mybatis")//指定路径@import(dynamicselectimport.class)publicclassdynamicselectconfig{}
四、 @import引入importbeandefinitionregistrar的实现类
@import引入importbeandefinitionregistrar的实现类。一般用来动态注册bean。最重要的一点是还可以对这些beandefinition进行额外的修改或增强。咱们经常使用的mybatis @mapperscan就是用这种方式实现的。
/***importbeandefinitionregistrar,我们一般会实现importbeandefinitionregistrar类,然后配合一个自定义的注解一起使用。而且在注解类上@import我们的这个实现类。*通过自定义注解的配置,拿到注解的一些元数据。然后在importbeandefinitionregistrar的实现类里面做相应的逻辑处理,比如把自定义注解标记的类添加到springioc容器里面去。*/publicinterfaceimportbeandefinitionregistrar{/***根据注解的给定注释元数据,根据需要注册bean定义*@paramimportingclassmetadata可以拿到@import的这个class的annotationmetadata*@paramregistrybeandefinitionregistry就可以拿到目前所有注册的beandefinition,然后可以对这些beandefinition进行额外的修改或增强。*/voidregisterbeandefinitions(annotationmetadataimportingclassmetadata,beandefinitionregistryregistry);}
关于@import引入importbeandefinitionregistrar的使用强烈建议大家去看看mybatis关于@mapperscan的处理源码。特别有意思。我们也举一个非常简单的实例,来让大家直观的看到importbeandefinitionregistrar的使用,比如我们想把指定包路径下所有添加了beanioc注解的类注册为bean。
具体实现如下:
/***我们会把添加了该注解的类作为bean*/@retention(retentionpolicy.runtime)@target(elementtype.type)@documentedpublic@interfacebeanioc{}/***定义包路径。(指定包下所有添加了beanioc注解的类作为bean)*注意这里@import(beaniocscannerregister.class)的使用*/@retention(retentionpolicy.runtime)@target(elementtype.type)@documented@import(beaniocscannerregister.class)public@interfacebeaniocscan{string[]basepackages()default"";}/***搜索指定包下所有添加了beanioc注解的类,并且把这些类添加到ioc容器里面去*/publicclassbeaniocscannerregisterimplementsimportbeandefinitionregistrar,resourceloaderaware{privatefinalstaticstringpackage_name_key="basepackages";privateresourceloaderresourceloader;@overridepublicvoidregisterbeandefinitions(annotationmetadataannotationmetadata,beandefinitionregistrybeandefinitionregistry){//1.从beaniocscan注解获取到我们要搜索的包路径annotationattributesannoattrs=annotationattributes.frommap(annotationmetadata.getannotationattributes(beaniocscan.class.getname()));if(annoattrs==null||annoattrs.isempty()){return;}string[]basepackages=(string[])annoattrs.get(package_name_key);//2.找到指定包路径下所有添加了beanioc注解的类,并且把这些类添加到ioc容器里面去classpathbeandefinitionscannerscanner=newclasspathbeandefinitionscanner(beandefinitionregistry,false);scanner.setresourceloader(resourceloader);scanner.addincludefilter(newannotationtypefilter(beanioc.class));scanner.scan(basepackages);}@overridepublicvoidsetresourceloader(resourceloaderresourceloader){this.resourceloader=resourceloader;}}/***使用,使beaniocscan生效*/@configuration@beaniocscan(basepackages="com.tuacy.collect.mybatis")publicclassbeaniocscanconfig{}
关于“springboot中的@import注解怎么使用”这篇文章的内容就介绍到这里,感谢各位的阅读!相信大家对“springboot中的@import注解怎么使用”知识都有一定的了解,大家如果还想学习更多知识,欢迎关注恰卡编程网行业资讯频道。