通常将一个对象交给Spring来管理,有三种做法:
1、@Bean
2、@Componet(@Service等归为一类)
3、@import
这里主要讲第三种做法,打开Spring源码
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@documented
public @interface import {
Class>[] value();
}
@import注解只有一个value方法,注释中指明该注解必须作用于@Configuration定义的类上,value可以为想要交给Spring管理的类文件数组、importSelector或importBeanDefinitionRegistrar,接下来我们依次执行三种做法
1、通过指定class数组方式首先定义两个类
public class A {
}
public class B {
}
然后定义配置类,并用@import注解装饰,输入两个自定义类
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.import;
@Configuration
@import({A.class, B.class})
public class AppConfig {
}
2、实现importSelector接口
定义一个新的实体C,自定义selector实现importSelector接口,在方法中返回自定义的类路径,Spring会自动将该路径下的类注入到容器中.
import org.springframework.context.annotation.importSelector;
import org.springframework.core.type.Annotationmetadata;
public class MyimportSelector implements importSelector {
public String[] selectimports(Annotationmetadata annotationmetadata) {
return new String[]{"com.test.C"};
}
}
在配置代码中加入@import,并且参数给定MyimportSelector,这样C也能被注入容器
@Configuration
@import({A.class,B.class, MyimportSelector.class})
public class Config {
}
3、实现importBeanDefinitionRegistrar接口
这种方式跟importSelector类似,都是需要自己定义实现类,不同得是,这种可以自定义bean名称,其余两种则是全类名。
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.context.annotation.importBeanDefinitionRegistrar;
import org.springframework.core.type.Annotationmetadata;
public class MyRegistrar implements importBeanDefinitionRegistrar {
public void registerBeanDefinitions(Annotationmetadata annotationmetadata, BeanDefinitionRegistry beanDefinitionRegistry) {
RootBeanDefinition beanDefinition = new RootBeanDefinition(D.class);
beanDefinitionRegistry.registerBeanDefinition("ddddd", beanDefinition);
}
}
总结:在平时的业务开发当中,将对象放入容器,使用@Bean和@Compont基本就能够满足需求,但是@import注解能够方便扩展功能,比如控制类得注册时机,我希望能够通过一个简单的开关来控制是否注入A类,我们可以定义一个注解
1、控制类注入时机
我希望能够通过一个简单的开关来控制是否注入Berry类,我们可以定义一个注解@EnableC。在这个注解上添加@import,把需要控制是否注入的类用上述三种方式引入,标记@EnableC用来注入,不加@EnableC则不注入。SpringCloud中的@EnableEureka、@EnableDiscoveryClient就是利用这个原理
import org.springframework.context.annotation.import;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
@import({MyimportSelector .class})
public @interface EnableC {
}
@Configuration
@import({A.class,B.class})
@EnableC
public class Config {
}



