@Import注解是Spring中非常重要的一个类,主要用来将类注入到Spring容器中。Spring源码中各种以Enable开头的注解都用到了@Import注解,比如 @EnableAspectJAutoProxy注解,用来开启动态代理。第三方框架集成Spring时经常使用到该注解,比如Mybatis整合Spring时用到的@MapperScan注解。
目录
三、实现了ImportBeanDefinitionRegistrar接口的类
源码
@EnableAspectJAutoProxy注解源码
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy {
/**
* Indicate whether subclass-based (CGLIB) proxies are to be created as opposed
* to standard Java interface-based proxies. The default is {@code false}.
*/
boolean proxyTargetClass() default false;
/**
* Indicate that the proxy should be exposed by the AOP framework as a {@code ThreadLocal}
* for retrieval via the {@link org.springframework.aop.framework.AopContext} class.
* Off by default, i.e. no guarantees that {@code AopContext} access will work.
* @since 4.3.1
*/
boolean exposeProxy() default false;
}
@MapperScan注解源码
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Import(MapperScannerRegistrar.class)
@Repeatable(MapperScans.class)
public @interface MapperScan {
/**
* Alias for the {@link #basePackages()} attribute. Allows for more concise annotation declarations e.g.:
* {@code @MapperScan("org.my.pkg")} instead of {@code @MapperScan(basePackages = "org.my.pkg"})}.
*
* @return base package names
*/
String[] value() default {};
/**
* Base packages to scan for MyBatis interfaces. Note that only interfaces with at least one method will be
* registered; concrete classes will be ignored.
*
* @return base package names for scanning mapper interface
*/
String[] basePackages() default {};
/**
* Type-safe alternative to {@link #basePackages()} for specifying the packages to scan for annotated components. The
* package of each class specified will be scanned.
* <p>
* Consider creating a special no-op marker class or interface in each package that serves no purpose other than being
* referenced by this attribute.
*
* @return classes that indicate base package for scanning mapper interface
*/
Class<?>[] basePackageClasses() default {};
/**
* The {@link BeanNameGenerator} class to be used for naming detected components within the Spring container.
*
* @return the class of {@link BeanNameGenerator}
*/
Class<? extends BeanNameGenerator> nameGenerator() default BeanNameGenerator.class;
/**
* This property specifies the annotation that the scanner will search for.
* <p>
* The scanner will register all interfaces in the base package that also have the specified annotation.
* <p>
* Note this can be combined with markerInterface.
*
* @return the annotation that the scanner will search for
*/
Class<? extends Annotation> annotationClass() default Annotation.class;
/**
* This property specifies the parent that the scanner will search for.
* <p>
* The scanner will register all interfaces in the base package that also have the specified interface class as a
* parent.
* <p>
* Note this can be combined with annotationClass.
*
* @return the parent that the scanner will search for
*/
Class<?> markerInterface() default Class.class;
/**
* Specifies which {@code SqlSessionTemplate} to use in the case that there is more than one in the spring context.
* Usually this is only needed when you have more than one datasource.
*
* @return the bean name of {@code SqlSessionTemplate}
*/
String sqlSessionTemplateRef() default "";
/**
* Specifies which {@code SqlSessionFactory} to use in the case that there is more than one in the spring context.
* Usually this is only needed when you have more than one datasource.
*
* @return the bean name of {@code SqlSessionFactory}
*/
String sqlSessionFactoryRef() default "";
/**
* Specifies a custom MapperFactoryBean to return a mybatis proxy as spring bean.
*
* @return the class of {@code MapperFactoryBean}
*/
Class<? extends MapperFactoryBean> factoryBean() default MapperFactoryBean.class;
/**
* Whether enable lazy initialization of mapper bean.
*
* <p>
* Default is {@code false}.
* </p>
*
* @return set {@code true} to enable lazy initialization
* @since 2.0.2
*/
String lazyInitialization() default "";
}
@Import注解源码
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Import {
/**
* {@link Configuration @Configuration}, {@link ImportSelector},
* {@link ImportBeanDefinitionRegistrar}, or regular component classes to import.
*/
Class<?>[] value();
}
根据注释可知,可传入的Class类型有4种
- 加了@Configuration注解的配置类
- 实现了ImportSelector接口的类
- 实现了ImportBeanDefinitionRegistrar接口的类
- 普通的可作为Spring Bean的类
下面将逐一展示用法
一、加了@Configuration注解的配置类
public class Dog {
public String getName() {
return "dog";
}
}
public class Cat {
public String getName() {
return "cat";
}
}
@Configuration
@Import(CatConfig.class)
public class DogConfig {
@Bean
public Dog dog() {
return new Dog();
}
}
@Configuration
public class CatConfig {
@Bean
public Cat cat() {
return new Cat();
}
}
public class Test {
public static void main(String[] args) {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(DogConfig.class);
Cat cat = applicationContext.getBean(Cat.class);
// 输出 cat
System.out.println(cat.getName());
}
}
二、实现了ImportSelector接口的类
public class Dog {
public String getName() {
return "dog";
}
}
public class DogImportSelector implements ImportSelector {
@Override
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
// 返回Dog类的全限定类名
return new String[] {Dog.class.getName()};
}
}
@Configuration
@Import(DogImportSelector.class)
public class DogConfig {
}
public class Test {
public static void main(String[] args) {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(DogConfig.class);
Dog dog = applicationContext.getBean(Dog.class);
// 输出 dog
System.out.println(dog.getName());
}
}
三、实现了ImportBeanDefinitionRegistrar接口的类
public class Dog {
public String getName() {
return "dog";
}
}
public class DogImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
// 注册dog的bean定义,其中beanName为dogBean
registry.registerBeanDefinition("dogBean", BeanDefinitionBuilder.genericBeanDefinition(Dog.class).getBeanDefinition());
}
}
@Configuration
@Import(DogImportBeanDefinitionRegistrar.class)
public class DogConfig {
}
public class Test {
public static void main(String[] args) {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(DogConfig.class);
// 根据beanName获取
Dog dog = applicationContext.getBean("dogBean", Dog.class);
// 输出 dog
System.out.println(dog.getName());
}
}
四、普通的可作为Spring Bean的类
public class Dog {
public String getName() {
return "dog";
}
}
@Configuration
@Import(Dog.class)
public class DogConfig {
}
public class Test {
public static void main(String[] args) {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(DogConfig.class);
Dog dog = applicationContext.getBean(Dog.class);
// 输出 dog
System.out.println(dog.getName());
}
}