Spring-扫描注解原理,注解自动扫描原理分析

注解自动扫描原理分析

在spring的配置文件中加入如下代码,spring便开启了自动扫描,那么它的底层到底是如何实现的呢?
<context:component-scan base-package="com.wisely.highlight_spring4.ch1"/>

  1. 首先找到解析这个标签的地方,spring 中解析具体的标签都有相应的解析器,且都继承了NamespaceHandlerSupport
    在这里插入图片描述
    在这里插入图片描述

  2. 查看 ComponentScanBeanDefinitionParserparse方法
    在这里插入图片描述

  3. 真正的逻辑其实是在ClassPathBeanDefinitionScannerdoScan方法中
    在这里插入图片描述

  4. 测试一下扫描过程

package com.wisely.highlight_spring4.ch1.di;

import java.io.IOException;
import java.util.LinkedHashSet;
import java.util.Set;

import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.ScannedGenericBeanDefinition;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.core.type.classreading.MetadataReader;
import org.springframework.core.type.classreading.MetadataReaderFactory;
import org.springframework.core.type.classreading.SimpleMetadataReaderFactory;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;
import org.springframework.stereotype.Service;

public class BeanFactoryTest
{
	public static void main(String[] args) throws IOException, ClassNotFoundException {
        Set<BeanDefinition> candidates = new LinkedHashSet<>();

        ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver();  
        //这里特别注意一下类路径必须这样写
        //获取指定包下的所有类
        Resource[] resources = resourcePatternResolver.getResources("classpath*:com\\wisely\\highlight_spring4\\ch1\\di\\*");  
         
        MetadataReaderFactory metadata=new SimpleMetadataReaderFactory();
        for(Resource resource:resources) {
        	System.out.println(resource);
            MetadataReader metadataReader=metadata.getMetadataReader(resource);
            ScannedGenericBeanDefinition sbd = new ScannedGenericBeanDefinition(metadataReader);
            sbd.setResource(resource);
            sbd.setSource(resource);
            candidates.add(sbd);
        }
        for(BeanDefinition beanDefinition : candidates) {  
            String classname=beanDefinition.getBeanClassName();
            //扫描controller注解
            Controller c=Class.forName(classname).getAnnotation(Controller.class);
            //扫描Service注解
            Service s=Class.forName(classname).getAnnotation(Service.class);
            //扫描Component注解
            Component component=Class.forName(classname).getAnnotation(Component.class);
            if(c!=null ||s!=null ||component!=null){       
            	System.out.println(classname);
            }
        } 
    }
}

  1. 我的项目包结构
    在这里插入图片描述

  2. 控制台输出结果
    在这里插入图片描述

  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值