常用注解

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;//这是个集合
}

返回顶部

posted @ 2020-03-27 11:36  平淡454  阅读(89)  评论(0编辑  收藏  举报