先看下这个注解都有什么属性
public @interface Import { /** * {@link Configuration}, {@link ImportSelector}, {@link ImportBeanDefinitionRegistrar} * or regular component classes to import. */ Class<?>[] value(); } 复制代码
看value属性上面的注解 value可以放两种重要的类 ImportSelector和ImportBeanDefinitionRegistrar,当然也可以放普通类,就是不继承这两种类,所以如果想了解@Import有什么作用就要了解ImportBeanDefinitionRegistrar和 ImportSelector有什么用
public interface ImportSelector { String[] selectImports(AnnotationMetadata importingClassMetadata); } 复制代码
ImportSelector 是一个接口,一般我们都是实现这个接口的selectImports方法,这个方法有什么作用?这个方法主要是会spring执行,返回值是我们想让spring管理的bean全类名。 比如我想让spring帮我管理A对象和B对象,这个方法就会返回一个数组{com.xx.a,cong.xx.b},spring收到返回值之后就会将这两个bean进行处理,入参AnnotationMetadata有什么作用?可以让selectImports这个方法拿到注解的内容,然后进行所需要的处理,比如说需要让bena管理的是从注解中获取到
典型的应用就是springboot自动装配用到的 AutoConfigurationImportSelector 这个类继承了ImportSelector,做了什么呢? 可以参考 juejin.im/post/5efd98… 有对这个类进行解释
public interface ImportBeanDefinitionRegistrar { public void registerBeanDefinitions( AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry); } 复制代码
ImportBeanDefinitionRegistrar 同样也是一个接口,一般我们也是实现ImportBeanDefinitionRegistrar#registerBeanDefinitions。这个方法顾名思义,就是可以注册beanDefinition。同样这个方法也是spring帮我们调用的,调用的过程会传入registry,beanDefinition注册器,通过这个我们可以自己实现注册想要注册的bean
在mybatis和spring整合过程中,MapperScannerRegistrar起到了关键的作用。MapperScannerRegistrar实现了ImportBeanDefinitionRegistrar#registerBeanDef 在这个方法中,对包进行扫描,然后将mapper注册到spring容器中,详情见 juejin.im/editor/draf…
所以@import 顾名思义就是导入,作用其实就是这两个类的作用,一个是返回需要spirng帮忙管理的bean名称字符串,一个是直接拿注册器,直接注册自己想要注册的类
可以看到很多@Enablexxx的注解里面其实都相当于继承了@Import比如:
@Import(AspectJAutoProxyRegistrar.class) public @interface EnableAspectJAutoProxy { } 复制代码
一般我们用这个注解表示开启aop开关,其实就是扫描@Import 然后调用AspectJAutoProxyRegistrar#registerBeanDefinitions方法,往spring容器中 注册 AnnotationAwareAspectJAutoProxyCreator 这个后置处理器去进行aop代理的处理