• Spring框架(十一):手动实现一个@Component,讲一讲Spring的工厂后处理器


    手动实现一个@Component,讲一讲Spring的工厂后处理器

    引子

    痛定思痛,主要问题出现在自己雀氏不熟悉框架底层、一些面试题,以及sql的一些情况淡忘了。
    本章节的开始是对于过去的重新回顾,当然,我也会深入基础,阅读源码,仔细熟悉开发过程,对问题进行整体学习,
    后面会深入去做一些sql的题目来提升mysql能力
    相关代码代码和笔记已经放到了gitee中去,喜欢的读者记得点赞下载
    链接: MyComponentAnnotation

    需求

    1. 自定义一个注解,使用在类/方法上
    2. 可以通过包扫描工具(ComponetScan)完成对包扫描
    3. 通过工厂后处理器完成注解解析
    4. 通过BeanFactory可以获取到响应的Bean

    代码分析

    在这里插入图片描述

    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    public @interface MyComponent {
    
        String value() default "";
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    @Component
    public class MyComponentBeanFactory implements BeanDefinitionRegistryPostProcessor {
    
        public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
            Map<String, Class> stringClassMap = BaseClassScanUtils.scanMyComponentAnnotation("com.Iron");
    
            stringClassMap.forEach((a,b)->{
                System.out.println(b.getName());
                BeanDefinition beanDefinition = new RootBeanDefinition();
                beanDefinition.setBeanClassName(b.getName());
                registry.registerBeanDefinition(b.getName(), beanDefinition);
            });
        }
    
        public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
    
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    @MyComponent("myTestBean")
    public class TestBean1  {
    }
    
    
    • 1
    • 2
    • 3
    • 4
    
    public class BaseClassScanUtils {
    
        //设置资源规则
        private static final String RESOURCE_PATTERN = "/**/*.class";
    
        public static Map<String, Class> scanMyComponentAnnotation(String basePackage) {
    
            //创建容器存储使用了指定注解的Bean字节码对象
            Map<String, Class> annotationClassMap = new HashMap<String, Class>();
    
            //spring工具类,可以获取指定路径下的全部类
            ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver();
            try {
                String pattern = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX +
                        ClassUtils.convertClassNameToResourcePath(basePackage) + RESOURCE_PATTERN;
                Resource[] resources = resourcePatternResolver.getResources(pattern);
                //MetadataReader 的工厂类
                MetadataReaderFactory refractory = new CachingMetadataReaderFactory(resourcePatternResolver);
                for (Resource resource : resources) {
                    //用于读取类信息
                    MetadataReader reader = refractory.getMetadataReader(resource);
                    //扫描到的class
                    String classname = reader.getClassMetadata().getClassName();
                    Class<?> clazz = Class.forName(classname);
                    //判断是否属于指定的注解类型
                    if(clazz.isAnnotationPresent(MyComponent.class)){
                        //获得注解对象
                        MyComponent annotation = clazz.getAnnotation(MyComponent.class);
                        //获得属value属性值
                        String beanName = annotation.value();
                        //判断是否为""
                        if(beanName!=null&&!beanName.equals("")){
                            //存储到Map中去
                            annotationClassMap.put(beanName,clazz);
                            continue;
                        }
    
                        //如果没有为"",那就把当前类的类名作为beanName
                        annotationClassMap.put(clazz.getSimpleName(),clazz);
    
                    }
                }
            } catch (Exception exception) {
            }
    
            return annotationClassMap;
        }
    
        public static void main(String[] args) {
            Map<String, Class> stringClassMap = scanMyComponentAnnotation("com.Iron");
            System.out.println(stringClassMap);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    public class Spring {
    
        public static void main(String[] args) {
    
            AnnotationConfigApplicationContext cont = new AnnotationConfigApplicationContext(SpringConfig.class);
            Object myTestBean = cont.getBean("com.Iron.MyComponent.TestBean1");
            System.out.println(myTestBean);
    
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    在这里插入图片描述

    Spring工厂后处理器

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

  • 相关阅读:
    踩坑,发现一个ShardingJdbc读写分离的BUG
    linux为什么不是实时操作系统
    ChatGPT与码农的机会
    微擎模块 微乐居房产v3.0.9综合版小程序,美化小程序房源详情,增加底部菜单
    Java 框架、库和软件的精选列表(awesome java)
    机器学习jupyter 鸢尾花决策树
    【Linux】进程通信 | 管道
    在Go中过滤范型集合:性能回顾
    深入浅出讲解python闭包
    Moto edge s pro手机 WIFI和蓝牙连接不上 解决方法分享
  • 原文地址:https://blog.csdn.net/futurn_hero/article/details/128179846