Spring中@Import注解

@Import注解是Spring中非常重要的一个类,主要用来将类注入到Spring容器中。Spring源码中各种以Enable开头的注解都用到了@Import注解,比如 @EnableAspectJAutoProxy注解,用来开启动态代理。第三方框架集成Spring时经常使用到该注解,比如Mybatis整合Spring时用到的@MapperScan注解。

目录

源码

@EnableAspectJAutoProxy注解源码

@MapperScan注解源码

@Import注解源码

一、加了@Configuration注解的配置类

二、实现了ImportSelector接口的类

三、实现了ImportBeanDefinitionRegistrar接口的类

四、普通的可作为Spring Bean的类


源码

@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种

  1. 加了@Configuration注解的配置类
  2. 实现了ImportSelector接口的类
  3. 实现了ImportBeanDefinitionRegistrar接口的类
  4. 普通的可作为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());
    }
}

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值