手写代码模拟Spring底层原理

  1. 通过手写模拟,了解Spring的底层源码启动过程
  2. 通过手写模拟,了解BeanDefinition、BeanPostProcessor的概念
  3. 通过手写模拟,了解Spring解析配置类等底层源码工作流程
  4. 通过手写模拟,了解依赖注入,Aware回调等底层源码工作流程
  5. 通过手写模拟,了解Spring AOP的底层源码工作流程

        1.测试类:

package laoyang;

import laoyang.Service.UserService;
import spring.LaoyangApplicationContext;

/**
 * @author:Kevin
 * @create: 2023-09-08 20:49
 * @Description: 老杨spring手写spring底层模拟
 */

public class Test {
    public static void main(String[] args) {


        /**
         * 创建核心配置类
         *主要核心:
         *  扫描 创建单例Bean BeanDefinition:一个spring核心的对象,主要存放了spring初始化后的bean
         *                  BeanPostPRocess: 主要实现aop,对bean初始化前和初始化后进行调用扩展
         */
        LaoyangApplicationContext laoyangApplicationContext = new LaoyangApplicationContext(AppConfig.class);

        //拿到我们自己的bean
        UserService bean = (UserService) laoyangApplicationContext.getBean("userService");

        //调用我们spring的自己的方法
        bean.test();




    }
}

        2.模拟核心配置类(详细看代码)

package spring;

import laoyang.AppConfig;

import java.beans.Introspector;
import java.io.File;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author:Kevin
 * @create: 2023-09-08 20:51
 * @Description: 老杨spring配置类
 */

public class LaoyangApplicationContext {

    private Class AppConfig;

    //bean扩展集合
    private List beanPostProcessorList = new ArrayList<>();
    //存放所有的bean信息
    private Map beanDefinitionMap = new HashMap<>();
    //存放所有的bean
    private Map singletonObjects = new HashMap<>();

    /**
     * spring核心类配置: 1.获取到配置文件路径
     *                  2.扫描路径下的文件
     *                  3.根据注解生成bean存入容器
     * @param appConfig
     */
    public LaoyangApplicationContext(Class appConfig) {
        this.AppConfig = appConfig;

        //开始扫描
        scan(appConfig);
    }

    /**
     * 扫描:
     *      1. 将配置文件目录的路径配置为绝对路径,遍历路径下的所有文件判断
     *      2. beanDefinitionMap: 所有的bean信息
     *      3. beanPostProcessorList:是否需要扩展的
     * @param appConfig
     */
    private void scan(Class appConfig) {

        //判断配置类是否有ComponentScan属性
        if (appConfig.isAnnotationPresent(ComponentScan.class)) {

            //获取路径
            ComponentScan annotation = appConfig.getAnnotation(ComponentScan.class);
            String path = annotation.value();
            path = path.replace(".", "/");  //     com/laoyang/Service

            //获取编译路径并封装成绝对路劲为了扫描我们自己的包下的bean
            ClassLoader classLoader = LaoyangApplicationContext.class.getClassLoader();
            URL resource = classLoader.getResource(path);
            File file = new File(resource.getFile());

            //判断是否目录
            if (file.isDirectory()) {
                for (File f : file.listFiles()) {
                    //获取绝对路径
                    String absolutePath = f.getAbsolutePath();

                    absolutePath = absolutePath.substring(absolutePath.indexOf("com"), absolutePath.indexOf(".class"));
                    absolutePath = absolutePath.replace("\\", ".");

                    try {

                        Class clazz = classLoader.loadClass(absolutePath);

                        if (clazz.isAnnotationPresent(Component.class)) {

                            //判断这个类是否实现BeanPostProcessor,是否需要实现自定义扩展,aop的实现
                            if (BeanPostProcessor.class.isAssignableFrom(clazz)) {
                                BeanPostProcessor instance = (BeanPostProcessor) clazz.getConstructor().newInstance();
                                beanPostProcessorList.add(instance);
                            }

                            Component componentAnnotation = clazz.getAnnotation(Component.class);
                            String beanName = componentAnnotation.value();
                            if ("".equals(beanName)) {
                                //这里采用jdk的方法将给定字符串的首字母小写的方法。
                                beanName = Introspector.decapitalize(clazz.getSimpleName());
                            }

                            BeanDefinition beanDefinition = new BeanDefinition();
                            beanDefinition.setType(clazz);

                            //判断是否加入scope注解 ,是单例bean还是原型bean,默认单例bean
                            if (clazz.isAnnotationPresent(Scope.class)) {
                                Scope scopeAnnotation = clazz.getAnnotation(Scope.class);
                                String value = scopeAnnotation.value();
                                beanDefinition.setScope(value);
                            } else {
                                beanDefinition.setScope("singleton");
                            }

                            beanDefinitionMap.put(beanName, beanDefinition);
                        }
                    } catch (ClassNotFoundException | NoSuchMethodException e) {
                        e.printStackTrace();
                    } catch (InvocationTargetException e) {
                        e.printStackTrace();
                    } catch (InstantiationException e) {
                        e.printStackTrace();
                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                    }
                }

            }


        }

    }


    /**
     * 通过bean名称返回bean
     * @param beanName
     * @return
     */
    public Object getBean(String beanName) {

        if (!beanDefinitionMap.containsKey(beanName)) {
            throw new NullPointerException();

        }
        BeanDefinition beanDefinition = beanDefinitionMap.get(beanName);

        if (beanDefinition.getScope().equals("singleton")) {
            Object singletonBean = singletonObjects.get(beanName);
            if (singletonBean == null) {
                singletonBean = createBean(beanName, beanDefinition);
                singletonObjects.put(beanName, singletonBean);
            }
            return singletonBean;
        } else {
            // 原型
            Object prototypeBean = createBean(beanName, beanDefinition);
            return prototypeBean;
        }

    }

    /**
     * 创建bean的方法:
     *            1. 依赖注入
     *            2. 判断是否实现BeanNameAware:就是初始化bean名称
     *            3. bean初始化前的操作
     *            4,初始化bean
     *            5. bean的初始化后的方法调用
     *            6. 返回bean
     * @param beanName
     * @param beanDefinition
     * @return
     */
    private Object createBean(String beanName, BeanDefinition beanDefinition) {
        Class clazz = beanDefinition.getType();

        Object instance = null;
        try {

            instance = clazz.getConstructor().newInstance();

            //依赖注入
            for (Field field : clazz.getDeclaredFields()) {
                if (field.isAnnotationPresent(Autowired.class)) {

                    //跳过访问权限直接修改
                    field.setAccessible(true);

                    field.set(instance, getBean(field.getName()));
                }
            }

            //判断是否实现BeanNameAware:就是初始化bean名称
            if (instance instanceof BeanNameAware) {
                ((BeanNameAware)instance).setBeanName(beanName);
            }

            //bean初始化前的操作,调用postProcessBeforeInitialization方法实现
            for (BeanPostProcessor beanPostProcessor : beanPostProcessorList) {
                instance = beanPostProcessor.postProcessBeforeInitialization(instance, beanName);
            }

            //初始化bean
            if (instance instanceof InitializingBean) {
                ((InitializingBean)instance).afterPropertiesSet();
            }

            //bean的初始化后的方法调用
            for (BeanPostProcessor beanPostProcessor : beanPostProcessorList) {
                instance = beanPostProcessor.postProcessAfterInitialization(instance, beanName);
            }


        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }

        return instance;
    }
}

        3. 核心配置类

package laoyang;

import spring.ComponentScan;

/**
 * @author:Kevin
 * @create: 2023-09-08 20:49
 * @Description: 配置类
 */
@ComponentScan("com.laoyang.Service")
public class AppConfig {
}

        4. 

你可能感兴趣的:(spring,java,后端)