天天看点

Spring框架(十一):手动实现一个@Component,讲一讲Spring的工厂后处理器引子需求代码分析Spring工厂后处理器

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

  • 引子
  • 需求
  • 代码分析
  • Spring工厂后处理器

引子

痛定思痛,主要问题出现在自己雀氏不熟悉框架底层、一些面试题,以及sql的一些情况淡忘了。

本章节的开始是对于过去的重新回顾,当然,我也会深入基础,阅读源码,仔细熟悉开发过程,对问题进行整体学习,

后面会深入去做一些sql的题目来提升mysql能力

相关代码代码和笔记已经放到了gitee中去,喜欢的读者记得点赞下载

链接: MyComponentAnnotation

需求

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

代码分析

Spring框架(十一):手动实现一个@Component,讲一讲Spring的工厂后处理器引子需求代码分析Spring工厂后处理器
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyComponent {

    String value() default "";

}

           
@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 {

    }
}

           
@MyComponent("myTestBean")
public class TestBean1  {
}

           
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);
    }
}
           
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);

    }
}
           
Spring框架(十一):手动实现一个@Component,讲一讲Spring的工厂后处理器引子需求代码分析Spring工厂后处理器

Spring工厂后处理器

Spring框架(十一):手动实现一个@Component,讲一讲Spring的工厂后处理器引子需求代码分析Spring工厂后处理器
Spring框架(十一):手动实现一个@Component,讲一讲Spring的工厂后处理器引子需求代码分析Spring工厂后处理器
Spring框架(十一):手动实现一个@Component,讲一讲Spring的工厂后处理器引子需求代码分析Spring工厂后处理器
Spring框架(十一):手动实现一个@Component,讲一讲Spring的工厂后处理器引子需求代码分析Spring工厂后处理器
Spring框架(十一):手动实现一个@Component,讲一讲Spring的工厂后处理器引子需求代码分析Spring工厂后处理器
Spring框架(十一):手动实现一个@Component,讲一讲Spring的工厂后处理器引子需求代码分析Spring工厂后处理器