Spring 高级 工厂后处理器模拟实现组件扫描(一)

一、代码

复制代码
package com.mangoubiubiu.show.a05;

import lombok.extern.slf4j.Slf4j;
import org.mybatis.spring.mapper.MapperScannerConfigurer;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.ConfigurationClassPostProcessor;
import org.springframework.context.support.GenericApplicationContext;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.core.io.Resource;
import org.springframework.core.type.classreading.CachingMetadataReaderFactory;
import org.springframework.core.type.classreading.MetadataReader;
import org.springframework.stereotype.Component;

import java.awt.*;
import java.io.IOException;

@Slf4j
public class A05Application {

    public static void main(String[] args) throws IOException {
        GenericApplicationContext context = new GenericApplicationContext();
        //将config注册到容器里面
        context.registerBean("config",Config.class);
//        context.registerBean(ConfigurationClassPostProcessor.class);
//        context.registerBean(MapperScannerConfigurer.class,beanDefinition -> {
//            beanDefinition.getPropertyValues().add("basePackage","com.mangoubiubiu.show.a05.mapper");
//        });
        //Spring工具类 读取类的源信息
        CachingMetadataReaderFactory factory = new CachingMetadataReaderFactory();
        //查找某个类上有没有加注解 第一个参数 某个类的类型  第二个参数 要找的注解
        ComponentScan componentScan = AnnotationUtils.findAnnotation(Config.class, ComponentScan.class);
        if(componentScan!=null){
            for (String p:componentScan.basePackages()) {
                System.out.println("包名:"+p);

                //com.mangoubiubiu.show.a05.component
                StringBuilder path = new StringBuilder();
                path.append("classpath*:").append(p.replace(".","/")).append("/**/*.class");
                System.out.println("拼接后的包名:"+path.toString());
                //读取路径下的文件
                Resource[] resources = context.getResources(path.toString());
                for (Resource res:resources) {
                    System.out.println("读取到的文件信息为:"+res);
                    MetadataReader reader = factory.getMetadataReader(res);
                    System.out.println("得到类信息:"+reader.getClassMetadata().getClassName());
                    System.out.println("是否加了Component注解"+reader.getAnnotationMetadata().hasAnnotation(Component.class.getName()));
                }

            }
        }


        //初始化容器

        context.refresh();

        for (String name: context.getBeanDefinitionNames()) {
            System.out.println(name);
        }

        context.close();
    }



}
复制代码

二、进阶

如果是Component的派生组件呢 那原来的方法是否还能扫描到,将Bean3的Component换成Controller 

复制代码
package com.mangoubiubiu.show.a05.component;

import com.mangoubiubiu.show.a05.Bean1;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;

@Controller
public class Bean3 {
    private static final Logger log = LoggerFactory.getLogger(Bean1.class);

    public Bean3() {
        log.debug("我被 Spring 管理啦");
    }
}
复制代码
复制代码
package com.mangoubiubiu.show.a05;

import lombok.extern.slf4j.Slf4j;
import org.mybatis.spring.mapper.MapperScannerConfigurer;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.ConfigurationClassPostProcessor;
import org.springframework.context.support.GenericApplicationContext;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.core.io.Resource;
import org.springframework.core.type.classreading.CachingMetadataReaderFactory;
import org.springframework.core.type.classreading.MetadataReader;
import org.springframework.stereotype.Component;

import java.awt.*;
import java.io.IOException;

@Slf4j
public class A05Application {

    public static void main(String[] args) throws IOException {
        GenericApplicationContext context = new GenericApplicationContext();
        //将config注册到容器里面
        context.registerBean("config",Config.class);
//        context.registerBean(ConfigurationClassPostProcessor.class);
//        context.registerBean(MapperScannerConfigurer.class,beanDefinition -> {
//            beanDefinition.getPropertyValues().add("basePackage","com.mangoubiubiu.show.a05.mapper");
//        });
        //Spring工具类 读取类的源信息
        CachingMetadataReaderFactory factory = new CachingMetadataReaderFactory();
        //查找某个类上有没有加注解 第一个参数 某个类的类型  第二个参数 要找的注解
        ComponentScan componentScan = AnnotationUtils.findAnnotation(Config.class, ComponentScan.class);
        if(componentScan!=null){
            for (String p:componentScan.basePackages()) {
                System.out.println("包名:"+p);

                //com.mangoubiubiu.show.a05.component
                StringBuilder path = new StringBuilder();
                path.append("classpath*:").append(p.replace(".","/")).append("/**/*.class");
                System.out.println("拼接后的包名:"+path.toString());
                //读取路径下的文件
                Resource[] resources = context.getResources(path.toString());
                for (Resource res:resources) {
                    System.out.println("读取到的文件信息为:"+res);
                    MetadataReader reader = factory.getMetadataReader(res);
                    System.out.println("得到类信息:"+reader.getClassMetadata().getClassName());
                    System.out.println("是否加了Component注解"+reader.getAnnotationMetadata().hasAnnotation(Component.class.getName()));
                    System.out.println("是否加了Component注解 派生"+reader.getAnnotationMetadata().hasMetaAnnotation(Component.class.getName()));

                }


            }
        }


        //初始化容器

        context.refresh();

        for (String name: context.getBeanDefinitionNames()) {
            System.out.println(name);
        }

        context.close();
    }



}
复制代码

发现成功检测到@Controller

 

 

 

本文作者:KwFruit

本文链接:https://www.cnblogs.com/mangoubiubiu/p/16593085.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   KwFruit  阅读(36)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起