解析spring.xml文件,自定义导入Bean

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

解析spirng配置文件中的componentScan标签,目的是得到Autowired注解的后置处理器的由来和自定义ImportSelector 注册Bean


一、spring.xml文件?

在这里插入图片描述

二、解析obtainFreshBeanFactory源码

ApplicationContext刷新 中进入
方法概述:
该方法会解析所有 Spring 配置文件(通常我们会放在 resources 目录下),将所有 Spring 配置文件中的 bean 定义封装成 BeanDefinition,加载到 BeanFactory 中。常见的,如果解析到<context:component-scan base-package=“” /> 配置时,会扫描 base-package 指定的目录,利用包路径和各种typeFilter去得到候选BeanDefinition(比如@Controller、@Service、@Component、@Repository注解下的Bean),加载到 BeanFactory 中。
BeanFactory 中的内容主要指的是添加到以下3个缓存:
beanDefinitionMap:所有被加载到 BeanFactory ,存储 beanName为key,definition为Value
beanDefinitionNames:所有被加载到 BeanFactory ,存储beanName
aliasMap缓存:所有被加载到 BeanFactory 中的 bean 的 beanName 和别名映射。

最终方法路径:
refreshBeanFactory
loadBeanDefinitions (得到DefaultListableBeanFactory)
loadBeanDefinitions(XmlBeanDefinitionReader reader) 得到配置文件路径(classpath*:config/spring/appcontext-*.xml )
loadBeanDefinitions(String location):使用XmlWebApplicationContext去解析该路径得到 Resource 类型的资源
loadBeanDefinitions(Resource… resources)
loadBeanDefinitions(Resource resource)
loadBeanDefinitions(EncodedResource encodedResource)
doLoadBeanDefinitions(InputSource inputSource, Resource resource)
doLoadDocument(inputSource, resource) 封装resource变成Document
registerBeanDefinitions(Document doc, Resource resource)
registerBeanDefinitions(Document doc, XmlReaderContext readerContext) 这个XmlReaderContext 就是DefaultNamespaceHandlerResolver
doRegisterBeanDefinitions
parseBeanDefinitions
parseCustomElement
这个handler根据命名空间取对应的
handler.parse(ele, new ParserContext(this.readerContext, this, containingBd));(主要是这个方法解析的conponent-scan)


三.进入源码

代码如下(示例):

@Override
public BeanDefinition parse(Element element, ParserContext parserContext) {
    // 1.拿到<context:component-scan>节点的base-package属性值
    String basePackage = element.getAttribute(BASE_PACKAGE_ATTRIBUTE);
    // 2.解析占位符, 例如 ${basePackage}
    basePackage = parserContext.getReaderContext().getEnvironment().resolvePlaceholders(basePackage);
    // 3.解析base-package(允许通过 ",; \t\n" 中的任一符号填写多个),例如: com.joonwhee.open.one;com.joonwhee.open.two
    String[] basePackages = StringUtils.tokenizeToStringArray(basePackage,
            ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS);
 
    // Actually scan for bean definitions and register them.
    // 4.构建和配置ClassPathBeanDefinitionScanner
    ClassPathBeanDefinitionScanner scanner = configureScanner(parserContext, element);
    // 5.使用scanner在指定的basePackages包中执行扫描,返回已注册的bean定义
    Set<BeanDefinitionHolder> beanDefinitions = scanner.doScan(basePackages);
    // 6.组件注册(包括注册一些内部的注解后置处理器、触发注册事件)
    registerComponents(parserContext.getReaderContext(), beanDefinitions, element);
 
    return null;
}

configureScanner 源码:

protected ClassPathBeanDefinitionScanner configureScanner(ParserContext parserContext, Element element) {
    // 1.解析use-default-filters属性,默认为true,用于指示是否使用默认的filter
    boolean useDefaultFilters = true;
    if (element.hasAttribute(USE_DEFAULT_FILTERS_ATTRIBUTE)) {
        useDefaultFilters = Boolean.valueOf(element.getAttribute(USE_DEFAULT_FILTERS_ATTRIBUTE));
    }
 
    // Delegate bean definition registration to scanner class.
    // 2.构建ClassPathBeanDefinitionScanner,将bean定义注册委托给scanner类
    ClassPathBeanDefinitionScanner scanner = createScanner(parserContext.getReaderContext(), useDefaultFilters);
    scanner.setBeanDefinitionDefaults(parserContext.getDelegate().getBeanDefinitionDefaults());
    scanner.setAutowireCandidatePatterns(parserContext.getDelegate().getAutowireCandidatePatterns());
 
    // 3.解析resource-pattern属性
    if (element.hasAttribute(RESOURCE_PATTERN_ATTRIBUTE)) {
        scanner.setResourcePattern(element.getAttribute(RESOURCE_PATTERN_ATTRIBUTE));
    }
 
    try {
        // 4.解析name-generator属性
        parseBeanNameGenerator(element, scanner);
    }
    catch (Exception ex) {
        parserContext.getReaderContext().error(ex.getMessage(), parserContext.extractSource(element), ex.getCause());
    }
 
    try {
        // 5.解析scope-resolver、scoped-proxy属性
        parseScope(element, scanner);
    }
    catch (Exception ex) {
        parserContext.getReaderContext().error(ex.getMessage(), parserContext.extractSource(element), ex.getCause());
    }
 
    // 6.解析类型过滤器
    parseTypeFilters(element, scanner, parserContext);
 
    return scanner;
}

createScanner 源码

protected ClassPathBeanDefinitionScanner createScanner(XmlReaderContext readerContext, boolean useDefaultFilters) {
    return new ClassPathBeanDefinitionScanner(readerContext.getRegistry(), useDefaultFilters,
            readerContext.getEnvironment(), readerContext.getResourceLoader());
}
 
// ClassPathBeanDefinitionScanner.java
public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters,
        Environment environment, ResourceLoader resourceLoader) {
 
    Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
    this.registry = registry;
 
    if (useDefaultFilters) {
        // 1.注册默认的filter
        registerDefaultFilters();
    }
    setEnvironment(environment);
    setResourceLoader(resourceLoader);
}
 

registerDefaultFilters 源码

protected void registerDefaultFilters() {
    // 1.添加@Component注解Filter到includeFilters中
    this.includeFilters.add(new AnnotationTypeFilter(Component.class));
    ClassLoader cl = ClassPathScanningCandidateComponentProvider.class.getClassLoader();
    try {
        // 2.添加@ManagedBean注解Filter到includeFilters中
        this.includeFilters.add(new AnnotationTypeFilter(
                ((Class<? extends Annotation>) ClassUtils.forName("javax.annotation.ManagedBean", cl)), false));
        logger.debug("JSR-250 'javax.annotation.ManagedBean' found and supported for component scanning");
    }
    catch (ClassNotFoundException ex) {
        // JSR-250 1.1 API (as included in Java EE 6) not available - simply skip.
    }
    try {
        // 3.添加@Named注解Filter到includeFilters中,这边会抛ClassNotFoundException
        this.includeFilters.add(new AnnotationTypeFilter(
                ((Class<? extends Annotation>) ClassUtils.forName("javax.inject.Named", cl)), false));
        logger.debug("JSR-330 'javax.inject.Named' annotation found and supported for component scanning");
    }
    catch (ClassNotFoundException ex) {
        // JSR-330 API not available - simply skip.
    }
}

parseTypeFilters 源码

protected void parseTypeFilters(Element element, ClassPathBeanDefinitionScanner scanner, ParserContext parserContext) {
    // Parse exclude and include filter elements.
    ClassLoader classLoader = scanner.getResourceLoader().getClassLoader();
    NodeList nodeList = element.getChildNodes();
    // 1.遍历解析element下的所有子节点
    for (int i = 0; i < nodeList.getLength(); i++) {
        Node node = nodeList.item(i);
        if (node.getNodeType() == Node.ELEMENT_NODE) {
            // 拿到节点的localName
            // 例如节点:<context:exclude-filter type="" expression=""/>,localName为:exclude-filter
            String localName = parserContext.getDelegate().getLocalName(node);
            try {
                /**
                 * 例如
                 * <context:component-scan base-package="com.joonwhee.open">
                 *     <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
                 * </context:component-scan>
                 */
                // 2.解析include-filter子节点
                if (INCLUDE_FILTER_ELEMENT.equals(localName)) {
                    // 2.1 构建TypeFilter
                    TypeFilter typeFilter = createTypeFilter((Element) node, classLoader, parserContext);
                    // 2.2 添加到scanner的includeFilters属性
                    scanner.addIncludeFilter(typeFilter);
                }
                // 3.解析exclude-filter子节点
                else if (EXCLUDE_FILTER_ELEMENT.equals(localName)) {
                    // 3.1 构建TypeFilter
                    TypeFilter typeFilter = createTypeFilter((Element) node, classLoader, parserContext);
                    // 3.2 添加到scanner的excludeFilters属性
                    scanner.addExcludeFilter(typeFilter);
                }
            } catch (Exception ex) {
                parserContext.getReaderContext().error(
                        ex.getMessage(), parserContext.extractSource(element), ex.getCause());
            }
        }
    }
}
 
protected TypeFilter createTypeFilter(Element element, ClassLoader classLoader, ParserContext parserContext) {
    // 1.获取type、expression
    String filterType = element.getAttribute(FILTER_TYPE_ATTRIBUTE);
    String expression = element.getAttribute(FILTER_EXPRESSION_ATTRIBUTE);
    expression = parserContext.getReaderContext().getEnvironment().resolvePlaceholders(expression);
    try {
        // 2.根据filterType,返回对应的TypeFilter,例如annotation返回AnnotationTypeFilter
        if ("annotation".equals(filterType)) {
            // 2.1 指定过滤的注解, expression为注解的类全名称, 例如: org.springframework.stereotype.Controller
            return new AnnotationTypeFilter((Class<Annotation>) classLoader.loadClass(expression));
        }
        else if ("assignable".equals(filterType)) {
            // 2.2 指定过滤的类或接口, 包括子类和子接口, expression为类全名称
            return new AssignableTypeFilter(classLoader.loadClass(expression));
        }
        else if ("aspectj".equals(filterType)) {
            // 2.3 指定aspectj表达式来过滤类, expression为aspectj表达式字符串
            return new AspectJTypeFilter(expression, classLoader);
        }
        else if ("regex".equals(filterType)) {
            // 2.4 通过正则表达式来过滤类, expression为正则表达式字符串
            return new RegexPatternTypeFilter(Pattern.compile(expression));
        }
        else if ("custom".equals(filterType)) {
            // 2.5 用户自定义过滤器类型, expression为自定义过滤器的类全名称
            Class<?> filterClass = classLoader.loadClass(expression);
            // 自定义的过滤器必须实现TypeFilter接口, 否则抛异常
            if (!TypeFilter.class.isAssignableFrom(filterClass)) {
                throw new IllegalArgumentException(
                        "Class is not assignable to [" + TypeFilter.class.getName() + "]: " + expression);
            }
            return (TypeFilter) BeanUtils.instantiateClass(filterClass);
        }
        else {
            throw new IllegalArgumentException("Unsupported filter type: " + filterType);
        }
    }
    catch (ClassNotFoundException ex) {
        throw new FatalBeanException("Type filter class not found: " + expression, ex);
    }
}

doScan 扫描包下面的Definition

protected Set<BeanDefinitionHolder> doScan(String... basePackages) {
    Assert.notEmpty(basePackages, "At least one base package must be specified");
    Set<BeanDefinitionHolder> beanDefinitions = new LinkedHashSet<BeanDefinitionHolder>();
    // 1.遍历basePackages
    for (String basePackage : basePackages) {
        // 2.扫描basePackage,将符合要求的bean定义全部找出来(这边符合要求最常见的就是使用Component注解)
        Set<BeanDefinition> candidates = findCandidateComponents(basePackage);
        // 3.遍历所有候选的bean定义
        for (BeanDefinition candidate : candidates) {
            // 4.解析@Scope注解, 包括scopeName(默认为singleton,常见的还有prototype), 和proxyMode(默认不使用代理, 可选接口代理/类代理)
            ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate);
            candidate.setScope(scopeMetadata.getScopeName());
            // 5.使用beanName生成器来生成beanName
            String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry);
            if (candidate instanceof AbstractBeanDefinition) {
                // 6.进一步处理BeanDefinition对象,比如: 此bean是否可以自动装配到其他bean中
                postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName);
            }
            if (candidate instanceof AnnotatedBeanDefinition) {
                // 7.处理定义在目标类上的通用注解,包括@Lazy, @Primary, @DependsOn, @Role, @Description
                AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate);
            }
            // 8.检查beanName是否已经注册过,如果注册过,检查是否兼容
            if (checkCandidate(beanName, candidate)) {
                // 9.将当前遍历bean的 bean定义和beanName封装成BeanDefinitionHolder
                BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName);
                // 10.根据proxyMode的值(步骤4中解析), 选择是否创建作用域代理
                definitionHolder =
                        AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
                beanDefinitions.add(definitionHolder);
                // 11.注册BeanDefinition(注册到beanDefinitionMap、beanDefinitionNames、aliasMap缓存)
                registerBeanDefinition(definitionHolder, this.registry);
            }
        }
    }
    return beanDefinitions;
}

findCandidateComponents 源码

public Set<BeanDefinition> findCandidateComponents(String basePackage) {
    Set<BeanDefinition> candidates = new LinkedHashSet<BeanDefinition>();
    try {
        // 1.根据我们配置的包名,组装成要扫描的通配包路径,例如:com.joonwhee.open 会被组装成: classpath*:com/joonwhee/open/**/*.class
        String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX +
                resolveBasePackage(basePackage) + '/' + this.resourcePattern;
        // 2.根据通配包路径匹配拿到所有匹配的类资源(本项目依赖的jar,如果路径也符合,则会一起扫描进来)
        Resource[] resources = this.resourcePatternResolver.getResources(packageSearchPath);
        boolean traceEnabled = logger.isTraceEnabled();
        boolean debugEnabled = logger.isDebugEnabled();
        // 3.遍历所有匹配的类资源
        for (Resource resource : resources) {
            if (traceEnabled) {
                logger.trace("Scanning " + resource);
            }
            if (resource.isReadable()) {
                try {
                    // 4.使用metadataReader读取资源,MetadataReader是专门用来访问元数据的类(包括: 类元数据ClassMetadata、注解元数据AnnotationMetadata等)
                    MetadataReader metadataReader = this.metadataReaderFactory.getMetadataReader(resource);
                    // 5.使用过滤器检查给定的类是否为候选类(候选类: 与excludeFilters的所有Filter不匹配,并且与includeFilters的至少一个Filter匹配)
                    if (isCandidateComponent(metadataReader)) {
                        ScannedGenericBeanDefinition sbd = new ScannedGenericBeanDefinition(metadataReader);
                        sbd.setResource(resource);
                        sbd.setSource(resource);
                        // 6.判断sbd是否为候选类(独立的 && (具体的实现类 || (抽象类 && 类中有方法使用@Lookup注解)))
                        if (isCandidateComponent(sbd)) {
                            if (debugEnabled) {
                                logger.debug("Identified candidate component class: " + resource);
                            }
                            // 7.确定是候选类,则添加到candidates
                            candidates.add(sbd);
                        }
                        else {
                            if (debugEnabled) {
                                logger.debug("Ignored because not a concrete top-level class: " + resource);
                            }
                        }
                    }
                    else {
                        if (traceEnabled) {
                            logger.trace("Ignored because not matching any filter: " + resource);
                        }
                    }
                }
                catch (Throwable ex) {
                    throw new BeanDefinitionStoreException(
                            "Failed to read candidate component class: " + resource, ex);
                }
            }
            else {
                if (traceEnabled) {
                    logger.trace("Ignored because not readable: " + resource);
                }
            }
        }
    }
    catch (IOException ex) {
        throw new BeanDefinitionStoreException("I/O failure during classpath scanning", ex);
    }
    return candidates;
}

isCandidateComponent 里面的代码就是根据前面得到的TypeFilter的match方法过滤掉不符合的,留下符合的候选类。

回顾上面的代码,resolveScopeMetadata的源码如下:
scope-resolver 指定bean的作用范围溶解器 与scope-proxy分开使用
scope-proxy 与scope-resolver分开使用,targetClass:cglib代理、interfaces:JDK代理、no:不使用代理 ,默认使用cglib代理

@Override
public ScopeMetadata resolveScopeMetadata(BeanDefinition definition) {
    ScopeMetadata metadata = new ScopeMetadata();
    if (definition instanceof AnnotatedBeanDefinition) {
        AnnotatedBeanDefinition annDef = (AnnotatedBeanDefinition) definition;
        AnnotationAttributes attributes  = AnnotationConfigUtils.attributesFor(annDef.getMetadata(),this.scopeAnnotationType);
        // 如果使用了@Scope注解
        if (attributes != null) {
            // 解析scopeName属性
            metadata.setScopeName(attributes.getString("value"));
            // 解析proxyMode属性
            ScopedProxyMode proxyMode = attributes.getEnum("proxyMode");
            if (proxyMode == null || proxyMode == ScopedProxyMode.DEFAULT) {
                proxyMode = this.defaultProxyMode;
            }
            metadata.setScopedProxyMode(proxyMode);
        }
    }
    return metadata;
}

如果使用了@Scope注解,则解析注解的属性。这边的 defaultProxyMode 取决于代码块1中步骤5的 scope-resolver、scoped-proxy 属性,默认为 ScopedProxyMode.NO。可以通过 scoped-proxy 来设置,例如下面配置 defaultProxyMode 的值就为 ScopedProxyMode.TARGET_CLASS。

postProcessBeanDefinition源码

protected void postProcessBeanDefinition(AbstractBeanDefinition beanDefinition, String beanName) {
    // 给beanDefinition设置默认值
    beanDefinition.applyDefaults(this.beanDefinitionDefaults);
    if (this.autowireCandidatePatterns != null) {
        // 设置此bean是否可以自动装配到其他bean中, 默认为true
        beanDefinition.setAutowireCandidate(PatternMatchUtils.simpleMatch(this.autowireCandidatePatterns, beanName));
    }
}

//autowireCandidatePatterns值来源于:
//parserContext.getDelegate().getAutowireCandidatePatterns()

registerComponents源码,这个源码注册的后置处理器对后面注解使用有很大的理解帮助。

protected void registerComponents(
        XmlReaderContext readerContext, Set<BeanDefinitionHolder> beanDefinitions, Element element) {
 
    Object source = readerContext.extractSource(element);
    // 1.使用注解的tagName(例如: context:component-scan)和source 构建CompositeComponentDefinition
    CompositeComponentDefinition compositeDef = new CompositeComponentDefinition(element.getTagName(), source);
 
    // 2.将扫描到的所有BeanDefinition添加到compositeDef的nestedComponents属性中
    for (BeanDefinitionHolder beanDefHolder : beanDefinitions) {
        compositeDef.addNestedComponent(new BeanComponentDefinition(beanDefHolder));
    }
 
    // Register annotation config processors, if necessary.
    boolean annotationConfig = true;
    if (element.hasAttribute(ANNOTATION_CONFIG_ATTRIBUTE)) {
        // 3.获取component-scan标签的annotation-config属性值(默认为true)
        annotationConfig = Boolean.valueOf(element.getAttribute(ANNOTATION_CONFIG_ATTRIBUTE));
    }
    if (annotationConfig) {
        // 4.如果annotation-config属性值为true,在给定的注册表中注册所有用于注解的Bean后置处理器
        Set<BeanDefinitionHolder> processorDefinitions =
                AnnotationConfigUtils.registerAnnotationConfigProcessors(readerContext.getRegistry(), source);
        for (BeanDefinitionHolder processorDefinition : processorDefinitions) {
            // 5.将注册的注解后置处理器的BeanDefinition添加到compositeDef的nestedComponents属性中
            compositeDef.addNestedComponent(new BeanComponentDefinition(processorDefinition));
        }
    }
 
    // 6.触发组件注册事件,默认实现为EmptyReaderEventListener(空实现,没有具体操作)
    readerContext.fireComponentRegistered(compositeDef);
}

registerAnnotationConfigProcessors源码

public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
        BeanDefinitionRegistry registry, Object source) {
 
    DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
    if (beanFactory != null) {
        if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
            // 1.设置dependencyComparator属性
            beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
        }
        if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
            // 2.设置autowireCandidateResolver属性(设置自动注入候选对象的解析器,用于判断BeanDefinition是否为候选对象)
            beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
        }
    }
 
    Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<BeanDefinitionHolder>(4);
 
    // 3.注册内部管理的用于处理@Configuration注解的后置处理器的bean
    if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
        RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
        def.setSource(source);
        // 3.1 registerPostProcessor: 注册BeanDefinition到注册表中
        beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
    }
 
    // 4.注册内部管理的用于处理@Autowired、@Value、@Inject以及@Lookup注解的后置处理器的bean
    if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
        RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
        def.setSource(source);
        beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
    }
 
    // 5.注册内部管理的用于处理@Required注解的后置处理器的bean
    if (!registry.containsBeanDefinition(REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
        RootBeanDefinition def = new RootBeanDefinition(RequiredAnnotationBeanPostProcessor.class);
        def.setSource(source);
        beanDefs.add(registerPostProcessor(registry, def, REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
    }
 
    // 6.注册内部管理的用于处理JSR-250注解(例如@Resource, @PostConstruct, @PreDestroy)的后置处理器的bean
    // Check for JSR-250 support, and if present add the CommonAnnotationBeanPostProcessor.
    if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {
        RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);
        def.setSource(source);
        beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));
    }
 
    // 7.注册内部管理的用于处理JPA注解的后置处理器的bean
    // Check for JPA support, and if present add the PersistenceAnnotationBeanPostProcessor.
    if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) {
        RootBeanDefinition def = new RootBeanDefinition();
        try {
            def.setBeanClass(ClassUtils.forName(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME,
                    AnnotationConfigUtils.class.getClassLoader()));
        } catch (ClassNotFoundException ex) {
            throw new IllegalStateException(
                    "Cannot load optional framework class: " + PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, ex);
        }
        def.setSource(source);
        beanDefs.add(registerPostProcessor(registry, def, PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME));
    }
 
    // 8.注册内部管理的用于处理@EventListener注解的后置处理器的bean
    if (!registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME)) {
        RootBeanDefinition def = new RootBeanDefinition(EventListenerMethodProcessor.class);
        def.setSource(source);
        beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_PROCESSOR_BEAN_NAME));
    }
    // 9.注册内部管理用于生产ApplicationListener对象的EventListenerFactory对象
    if (!registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME)) {
        RootBeanDefinition def = new RootBeanDefinition(DefaultEventListenerFactory.class);
        def.setSource(source);
        beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_FACTORY_BEAN_NAME));
    }
 
    return beanDefs;
}

四.自定义注解跟ImportBeanDefinitionRegistrar实现注入Bean

1:根据上面代码显示:需要构建和配置ClassPathBeanDefinitionScannner 然后再里面添加自定义过滤器(TypeFilter)
1.1:自定义Scannner需要:readerContext.getRegistry(), useDefaultFilters,
readerContext.getEnvironment(), readerContext.getResourceLoader() 四个参数
2:然后使用ClassPathBeanDefinitionScannner 的doScan(basePackages)方法,把对象注入容器中
代码如下(示例):

public class CustomImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar, ResourceLoaderAware, EnvironmentAware {
	
	@Override
	public void registerBeanDefinitions(AnnotationMetadata annotationMetadata,BeanDefinitionRegistry registry){
	//这段代码看不懂的话 我将会写一遍解析CustomImportBeanDefinitionRegistrar 的初始化流程代码
	if(!annotationMetadata.hasAnnotation(EnableCustomImport.class.getName())){
			return;
		}
	Map<String, Object> annotationAttributesMap = annotationMetadata.getAnnotationAttributes(EnableCustomImport.class.getName());
        AnnotationAttributes annotationAttributes = Optional.ofNullable(AnnotationAttributes.fromMap(annotationAttributesMap)).orElseGet(AnnotationAttributes::new);
        // 获取需要扫描的包
        String[] packages = retrievePackagesName(annotationMetadata, annotationAttributes);
         // useDefaultFilters = false,即第二个参数 表示不扫描 @Component、@ManagedBean、@Named 注解标注的类
        ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(registry, false, environment, resourceLoader);
        // 添加我们自定义注解的扫描
        scanner.addIncludeFilter(new AnnotationTypeFilter(CustomImport.class));
        // 扫描包
        for (String needScanPackage : packages) {
            Set<BeanDefinition> candidateComponents = scanner.findCandidateComponents(needScanPackage);
            try {
                registerCandidateComponents(registry, candidateComponents);
            } catch (ClassNotFoundException e) {
                log.error(e.getMessage(), e);
            }
        }
	}
private String[] retrievePackagesName(AnnotationMetadata annotationMetadata, AnnotationAttributes annotationAttributes) {
		 String[] packages = annotationAttributes.getStringArray("packages");
		 if(packages>0){
		 return packages;
		 }
		  String className = annotationMetadata.getClassName();
        int lastDot = className.lastIndexOf('.');
        return new String[]{className.substring(0,lastDot )}
    }
   /**
     * 注册 BeanDefinition
     */
    private void registerCandidateComponents(BeanDefinitionRegistry registry, Set<BeanDefinition> candidateComponents) throws ClassNotFoundException {
        for (BeanDefinition candidateComponent : candidateComponents) {
            if (candidateComponent instanceof AnnotatedBeanDefinition) {
                AnnotatedBeanDefinition annotatedBeanDefinition = (AnnotatedBeanDefinition) candidateComponent;
                AnnotationMetadata annotationMetadata = annotatedBeanDefinition.getMetadata();
                Map<String, Object> customImportAnnotationAttributesMap = annotationMetadata.getAnnotationAttributes(CustomImport.class.getName());
                AnnotationAttributes customImportAnnotationAttributes = Optional.ofNullable(AnnotationAttributes.fromMap(customImportAnnotationAttributesMap)).orElseGet(AnnotationAttributes::new);
                String beanName = customImportAnnotationAttributes.getString("beanName");
                String className = annotationMetadata.getClassName();
                Class<?> clazzName = Class.forName(className);
                AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition(CustomImportFactoryBean.class)
                        .addPropertyValue("type", clazzName)
                        .addPropertyValue("beanName", beanName)
                        .setAutowireMode(AbstractBeanDefinition.AUTOWIRE_BY_TYPE)
                        .setRole(BeanDefinition.ROLE_INFRASTRUCTURE)
                        .getBeanDefinition();
                registry.registerBeanDefinition(beanName, beanDefinition);

            }
        }
    }
}

五、自定义EnableCustomImport 注解

@Tartget({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(CustomImportBeanDefinitionRegistrar.class)
public @interface EnableCustomImport{
	String[] packages() default {};
}

使用的话直接到Aplication中使用就好,就是

@SpringBootApplication
@EnableCustomImport
public class ImportBeanDefinitionApplication{
}

  • 25
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值