常用注解
import
@Import用在类上 ,通过快速导入的方式把对象实例加入spring容器中
有三种用法:
1、直接在类上标注上要导入的class
2、ImportSelector方式【重点】
3、ImportBeanDefinitionRegistrar方式
直接在类上标注上要导入的class
可以导入多个,用逗号分隔
@Import({ 类名.class , 类名.class... })
public class TestDemo {
}
ImportSelector方式
public static void main(String[] args) {
//指定加载TestDemo到spring容器
AnnotationConfigApplicationContext applicationContext=new AnnotationConfigApplicationContext(TestDemo.class);
String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames();
for (String name : beanDefinitionNames){
System.out.println(name);
}
}
@Import({Myclass.class})
class TestDemo {
}
class Myclass implements ImportSelector {
@Override
public String[] selectImports(AnnotationMetadata annotationMetadata) {
return new String[]{"com.longfor.ads2.TestDemo3"};
}
}
class TestDemo3 {
}
spring容器在实例化TestDemo时,发现其类上的import注解导入Myclass,Myclass实现ImportSelector ,Myclass方法selectImports返回值也会被spring容器加载。
ImportBeanDefinitionRegistrar方式
该方式支持自定义bean,即在实例化bean的时候可以根据我们自定义规则动态加载bean。
举个例子帮助理解。
在容器加载testDemo的时候,我们要把所有带自定义注解@MyMapper的类都加载到容器。
实现该功能还需要一个负责扫描的工具ClassPathBeanDefinitionScanner,该类是spring提供的,可以自动按照规则扫描出我们要的类,并且添加到BeanDefinitionRegistrar中。
public static void main(String[] args) {
AnnotationConfigApplicationContext applicationContext=new AnnotationConfigApplicationContext(TestDemo.class);
String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames();
for (String name : beanDefinitionNames){
System.out.println(name);
}
}
@Import({Myclass.class})
class TestDemo {
}
class Myclass implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
//通过构造器将BeanDefinitionRegistry传递到扫描工具类
MyClassPathBeanDefinitionScanner scanner = new MyClassPathBeanDefinitionScanner(registry, false);
//添加扫描规则
scanner.registerFilters();
//开始扫描,MyClassPathBeanDefinitionScanner内部会自动将扫描出来的类注册到BeanDefinitionRegistry
scanner.doScan("com.longfor.ads2");
}
}
//扫描工具类
class MyClassPathBeanDefinitionScanner extends ClassPathBeanDefinitionScanner {
public MyClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters) {
super(registry, useDefaultFilters);
}
//该方法定义扫描规则
protected void registerFilters() {
addIncludeFilter(new AnnotationTypeFilter(MyMapper.class));//扫描MyMapper注解的类
}
//该方法定义扫描路径
@Override
protected Set<BeanDefinitionHolder> doScan(String... basePackages) {
return super.doScan(basePackages);
}
}
//自定义注解
@Documented
@Inherited
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER})
@interface MyMapper {
}
//要加载到容器的目标
@MyMapper
class CountryMapper {
}
Qualifier
@Qualifier和@Autowired配合使用。
有两种用法:
1、指定注入bean的名称
@Service
interface TestService{
}
@Service("testServiceImpl1")
class TestServiceImpl1 implements TestService{
}
@Service("testServiceImpl2")
class TestServiceImpl2 implements TestService{
}
@Controller
class TestController{
@Autowired
@Qualifier("testServiceImpl1")//如果没有这个注解,这里不知道该注入哪个实现
private TestService testService;
}
2、按照自定义规则批量注入。
ribbon注解@LoadBalanced就使用的这种用法来批量获取RestTemplate实例。
@Target({TYPE,METHOD,FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Qualifier//注意这个注解
@interface MyAnno {
}
@Service
interface TestService{
}
@MyAnno//自定义注解
@Service("testServiceImpl1")
class TestServiceImpl1 implements TestService{
}
@MyAnno//自定义注解
@Service("testServiceImpl2")
class TestServiceImpl2 implements TestService{
}
@Controller
class TestController{
@Autowired
@MyAnno //这个自定义注解上边有@Qualifier,配合@Autowired,将所有含有@MyAnno注解的类都注入进来
private List<TestService> testService;//这是个集合
}