您好,欢迎来到三六零分类信息网!老站,搜索引擎当天收录,欢迎发信息

SpringBoot中的@Import注解怎么使用

2025/11/27 11:28:50发布28次查看
一、 @import引入普通类通过使用@import注解,我们可以将普通的类定义为bean。@import可以添加在@springbootapplication(启动类)、@configuration(配置类)、@component(组件类)对应的类上。
注意:@restcontroller、@service、@repository都属于@component
@springbootapplication@import(importbean.class) // 通过@import注解把importbean添加到ioc容器里面去public class mybatisapplication { public static void main(string[] args) { springapplication.run(mybatisapplication.class, args); }}
二、 @import引入配置类(@configuration修饰的类)@import除了可以把普通的类定义为bean,@import还可以引入一个@configuration修饰的类(引入配置类),从而把让配置类生效(配置类下的所有bean添加到ioc容器里面去)。在自定义starter的时候经常会用到。
如果配置类在标准的springboot包结构下(springbootapplication启动类包的根目录下)。spring boot会自动处理配置类的导入,不需要手动使用@import注解。通常,这种情况适用于@configuration配置类不在标准的spring boot包结构之内。所以一般在自定义starter的时候用到。
@configuration(proxybeanmethods = false)@import({ // import了两个哈 xxxdataconfiguration.xxxpartoneconfiguration.class, xxxdataconfiguration.xxxparttwoconfiguration.class})public class xxxdataautoconfiguration {}public class xxxdataconfiguration { @configuration(proxybeanmethods = false) static class xxxpartoneconfiguration { @bean @conditionalonmissingbean public beanforioc beanforioc() { return new beanforioc(); } } @configuration(proxybeanmethods = false) static class xxxparttwoconfiguration { /** * 省略了@bean的使用 */ }}
三 、@import引入importselector的实现类@import还可以引入importselector的实现类,把importselector接口selectimports()方法返回的class名称都定义为bean。注意selectimports()方法的参数annotationmetadata,通过这个参数我们可以获取到@import标注的class的各种信息。这一点特别有用,用于做一些参数的传递。springboot的自动配置和@enablexxx注解都各自存在。
public interface importselector { /** * 用于指定需要注册为bean的class名称 * 当在@configuration标注的class上使用@import引入了一个importselector实现类后,会把实现类中返回的class名称都定义为bean。 * * 通过其参数annotationmetadata importingclassmetadata可以获取到@import标注的class的各种信息, * 包括其class名称,实现的接口名称、父类名称、添加的其它注解等信息,通过这些额外的信息可以辅助我们选择需要定义为spring bean的class名称 */ string[] selectimports(annotationmetadata importingclassmetadata);}
关于@import引入importselector的实现类的使用,我们举几个简单的使用场景(实际开发肯定比这复杂的多的)。
3.1 静态import场景(注入已知的类)静态场景(注入已知的类),很简单通过实现importselector类把我们需要定义为bean的类直接返回就好, 比如下面的例子。我们来一个enablexxx的注解,通过xxxconfigurationselector注入一个已知的类xxx。
/** * xxxconfigurationselector一定要配合@import使用 */public class xxxconfigurationselector implements importselector { @override @nonnull public string[] selectimports(@nonnull annotationmetadata importingclassmetadata) { // 把xxx对应的类,定义为bean return new string[]{xxx.class.getname()}; }}/** * 注意 @import(xxxconfigurationselector.class) */@target(elementtype.type)@retention(retentionpolicy.runtime)@documented@import(xxxconfigurationselector.class)public @interface enablexxx {}@springbootapplication@enablexxx // 使之生效public class mybatisapplication { public static void main(string[] args) { springapplication.run(mybatisapplication.class, args); }}
3.2 动态import场景(注入指定条件的类)我们做一个这样的功能,我们需要把指定包路径下所有实现了helloservice接口的类做为bean添加到ioc容器里面去。@componentscan注解用来帮我们指定路径。具体实现如下:
public interface helloservice { void function();}public class dynamicselectimport implements importselector { /** * dynamicselectimport需要配合@import()注解使用 * <p> * 通过其参数annotationmetadata importingclassmetadata可以获取到@import标注的class的各种信息, * 包括其class名称,实现的接口名称、父类名称、添加的其它注解等信息,通过这些额外的信息可以辅助我们选择需要定义为spring bean的class名称 */ @override public string[] selectimports(annotationmetadata importingclassmetadata) { // 第一步:获取到通过componentscan指定的包路径 string[] basepackages = null; // @import注解对应的类上的componentscan注解 if (importingclassmetadata.hasannotation(componentscan.class.getname())) { map<string, object> annotationattributes = importingclassmetadata.getannotationattributes(componentscan.class.getname()); basepackages = (string[]) annotationattributes.get("basepackages"); } if (basepackages == null || basepackages.length == 0) { //componentscan的basepackages默认为空数组 string basepackage = null; try { // @import注解对应的类的包名 basepackage = class.forname(importingclassmetadata.getclassname()).getpackage().getname(); } catch (classnotfoundexception e) { e.printstacktrace(); } basepackages = new string[]{basepackage}; } // 第er步,知道指定包路径下所有实现了helloservice接口的类(classpathscanningcandidatecomponentprovider的使用) classpathscanningcandidatecomponentprovider scanner = new classpathscanningcandidatecomponentprovider(false); typefilter helloservicefilter = new assignabletypefilter(helloservice.class); scanner.addincludefilter(helloservicefilter); set<string> classes = new hashset<>(); for (string basepackage : basepackages) { scanner.findcandidatecomponents(basepackage).foreach(beandefinition -> classes.add(beandefinition.getbeanclassname())); } // 第三步,返回添加到ioc容器里面去 return classes.toarray(new string[0]); }}@configuration@componentscan("com.tuacy.collect.mybatis") // 指定路径@import(dynamicselectimport.class)public class dynamicselectconfig {}
四、 @import引入importbeandefinitionregistrar的实现类@import引入importbeandefinitionregistrar的实现类。一般用来动态注册bean。最重要的一点是还可以对这些beandefinition进行额外的修改或增强。咱们经常使用的mybatis @mapperscan就是用这种方式实现的。
/** * importbeandefinitionregistrar,我们一般会实现importbeandefinitionregistrar类,然后配合一个自定义的注解一起使用。而且在注解类上@import我们的这个实现类。 * 通过自定义注解的配置,拿到注解的一些元数据。然后在importbeandefinitionregistrar的实现类里面做相应的逻辑处理,比如把自定义注解标记的类添加到spring ioc容器里面去。 */public interface importbeandefinitionregistrar { /** * 根据注解的给定注释元数据,根据需要注册bean定义 * @param importingclassmetadata 可以拿到@import的这个class的annotation metadata * @param registry beandefinitionregistry 就可以拿到目前所有注册的beandefinition,然后可以对这些beandefinition进行额外的修改或增强。 */ void registerbeandefinitions(annotationmetadata importingclassmetadata, beandefinitionregistry registry);}
关于@import引入importbeandefinitionregistrar的使用强烈建议大家去看看mybatis关于@mapperscan的处理源码。特别有意思。我们也举一个非常简单的实例,来让大家直观的看到importbeandefinitionregistrar的使用,比如我们想把指定包路径下所有添加了beanioc注解的类注册为bean。
具体实现如下:
/** * 我们会把添加了该注解的类作为bean */@retention(retentionpolicy.runtime)@target(elementtype.type)@documentedpublic @interface beanioc {}/** * 定义包路径。(指定包下所有添加了beanioc注解的类作为bean) * 注意这里 @import(beaniocscannerregister.class) 的使用 */@retention(retentionpolicy.runtime)@target(elementtype.type)@documented@import(beaniocscannerregister.class)public @interface beaniocscan { string[] basepackages() default "";}/** * 搜索指定包下所有添加了beanioc注解的类,并且把这些类添加到ioc容器里面去 */public class beaniocscannerregister implements importbeandefinitionregistrar, resourceloaderaware { private final static string package_name_key = "basepackages"; private resourceloader resourceloader; @override public void registerbeandefinitions(annotationmetadata annotationmetadata, beandefinitionregistry beandefinitionregistry) { //1. 从beaniocscan注解获取到我们要搜索的包路径 annotationattributes annoattrs = annotationattributes.frommap(annotationmetadata.getannotationattributes(beaniocscan.class.getname())); if (annoattrs == null || annoattrs.isempty()) { return; } string[] basepackages = (string[]) annoattrs.get(package_name_key); // 2. 找到指定包路径下所有添加了beanioc注解的类,并且把这些类添加到ioc容器里面去 classpathbeandefinitionscanner scanner = new classpathbeandefinitionscanner(beandefinitionregistry, false); scanner.setresourceloader(resourceloader); scanner.addincludefilter(new annotationtypefilter(beanioc.class)); scanner.scan(basepackages); } @override public void setresourceloader(resourceloader resourceloader) { this.resourceloader = resourceloader; }}/** * 使用,使beaniocscan生效 */@configuration@beaniocscan(basepackages = "com.tuacy.collect.mybatis")public class beaniocscanconfig {}
以上就是springboot中的@import注解怎么使用的详细内容。
该用户其它信息

VIP推荐

免费发布信息,免费发布B2B信息网站平台 - 三六零分类信息网 沪ICP备09012988号-2
企业名录 Product