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 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步