`
234390216
  • 浏览: 10193199 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
博客专栏
A5ee55b9-a463-3d09-9c78-0c0cf33198cd
Oracle基础
浏览量:460801
Ad26f909-6440-35a9-b4e9-9aea825bd38e
springMVC介绍
浏览量:1771787
Ce363057-ae4d-3ee1-bb46-e7b51a722a4b
Mybatis简介
浏览量:1395412
Bdeb91ad-cf8a-3fe9-942a-3710073b4000
Spring整合JMS
浏览量:393882
5cbbde67-7cd5-313c-95c2-4185389601e7
Ehcache简介
浏览量:678212
Cc1c0708-ccc2-3d20-ba47-d40e04440682
Cas简介
浏览量:529286
51592fc3-854c-34f4-9eff-cb82d993ab3a
Spring Securi...
浏览量:1178713
23e1c30e-ef8c-3702-aa3c-e83277ffca91
Spring基础知识
浏览量:461862
4af1c81c-eb9d-365f-b759-07685a32156e
Spring Aop介绍
浏览量:150116
2f926891-9e7a-3ce2-a074-3acb2aaf2584
JAXB简介
浏览量:66835
社区版块
存档分类
最新评论

Spring(33)——ImportBeanDefinitionRegistrar介绍

阅读更多

ImportBeanDefinitionRegistrar介绍

在上一篇博文http://elim.iteye.com/blog/2428994中介绍了ImportSelector的作用及其用法。本文需要介绍的ImportBeanDefinitionRegistrar的用法和作用跟ImportSelector类似。唯一的不同点是ImportBeanDefinitionRegistrar的接口方法void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry)的返回类型是void,且多了一个BeanDefinitionRegistry类型的参数,它允许我们直接通过BeanDefinitionRegistry对象注册bean。承接上文内容,为了扫描并注册HelloService类型的bean,我们可以自定义如下ImportBeanDefinitionRegistrar实现类。在实现类中可以使用ClassPathBeanDefinitionScanner进行扫描并自动注册,它是ClassPathScanningCandidateComponentProvider的子类,所以还是可以添加相同的TypeFilter,然后通过scanner.scan(basePackages)扫描指定的basePackage下满足条件的Class并注册它们为bean。

public class HelloImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {

    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
        Map<String, Object> annotationAttributes = importingClassMetadata.getAnnotationAttributes(ComponentScan.class.getName());
        String[] basePackages = (String[]) annotationAttributes.get("basePackages");
        
        ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(registry, false);
        TypeFilter helloServiceFilter = new AssignableTypeFilter(HelloService.class);
        scanner.addIncludeFilter(helloServiceFilter);
        scanner.scan(basePackages);
    }

}

此时我们的@Configuration配置类可以进行如下定义。

@Configuration
@ComponentScan("com.elim.spring.core.importselector")
@Import(HelloImportBeanDefinitionRegistrar.class)
public class HelloConfiguration {

}

为它定义一个特定的注解也是可以的,比如下面代码为HelloImportBeanDefinitionRegistrar定义了@HelloScan,其value属性和basePackages属性互为别名,用于指定需要扫描的basePackage。

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Import(HelloImportBeanDefinitionRegistrar.class)
public @interface HelloScan {

    @AliasFor("value")
    String[] basePackages() default {};
    
    @AliasFor("basePackages")
    String[] value() default {};
    
}

为了满足@HelloScan指定扫描的basePackage的需求,我们的HelloImportBeanDefinitionRegistrar需要改造为如下这样。

public class HelloImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {

    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
        Map<String, Object> annotationAttributes = importingClassMetadata.getAnnotationAttributes(HelloScan.class.getName());
        String[] basePackages = (String[]) annotationAttributes.get("basePackages");
        if (basePackages == null || basePackages.length == 0) {//HelloScan的basePackages默认为空数组
            String basePackage = null;
            try {
                basePackage = Class.forName(importingClassMetadata.getClassName()).getPackage().getName();
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
            basePackages = new String[] {basePackage};
        }
        
        ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(registry, false);
        TypeFilter helloServiceFilter = new AssignableTypeFilter(HelloService.class);
        scanner.addIncludeFilter(helloServiceFilter);
        scanner.scan(basePackages);
    }

}

此时我们的HelloConfiguration可以定义为如下这样,它的效果和之前是一模一样的。

@Configuration
@HelloScan("com.elim.spring.core.importselector")
public class HelloConfiguration {

}

(注:本文是基于Spring 5.0.7所写)

0
0
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics