手写spring核心原理-02

手写spring核心原理-02

文章重要是走通spring核心原理,代码化繁为简,很多方法细节考虑不周全不用纠结

目标

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

spring相关代码

AnnotationConfigApplicationContext

AnnotationConfigApplicationContext模仿spring源码中类AnnotationConfigApplicationContext

package com.spring;

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.LinkedList;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author yanbing
 * @version 1.0
 * @date 2021/9/4 21:12
 */
public class AnnotationConfigApplicationContext implements ApplicationContext {

    //存储bean定义信息,bean定义信息用途是生成bean对象
    private ConcurrentHashMap<String, BeanDefinition> beanDefinitionConcurrentHashMap = new ConcurrentHashMap<>();
    //已经初始化的单实例bean对象,全局唯一
    private ConcurrentHashMap<String, Object> singletonObjects = new ConcurrentHashMap<>();
    //所以的BeanPostProcessor的子类,在spring源码BeanPostProcessor是非常重要类,aop和类的扩展,@Value都是通过它类实现的
    private List<BeanPostProcessor> beanPostProcessorList = new LinkedList<>();


    /**
     * spring 启动流程
     *
     * @param componentClasses
     */
    public AnnotationConfigApplicationContext(Class<?> componentClasses) {

        //扫描整个包, 得到BeanDefinition
        scan(componentClasses);

        //实例话非懒加载单列bean
        //  1 实例化
        //  2 属性赋值
        //  3 Aare接口回调  @PostConstruct InitializingBean
        //  4 初始化
        //  5 添加到单实例缓存 singletonObjects
        finishSingletonBeanInitialization();

    }

    private void finishSingletonBeanInitialization() {
        for (String beanName : beanDefinitionConcurrentHashMap.keySet()) {
            BeanDefinition beanDefinition = beanDefinitionConcurrentHashMap.get(beanName);
            if (beanDefinition.getScope().equals(ScopeEnum.singleton)) {
                Object bean = doCreateBean(beanName, beanDefinition);
                singletonObjects.put(beanName, bean);
            }
        }
    }

    private Object doCreateBean(String beanName, BeanDefinition beanDefinition) {
        Class beanClass = beanDefinition.getBeanClass();
        try {
            //构造函数实例化
            Object instance = beanClass.getDeclaredConstructor().newInstance();
            Field[] fields = beanClass.getDeclaredFields();
            for (Field field : fields) {
                //依赖注入
                if (field.isAnnotationPresent(Autowired.class)) {
                    //真实spring源码通过属性的类型获取对象的,属性的名称可以随意命名
                    String filedName = field.getName();
                    Object bean = getBean(filedName);
                    field.setAccessible(true);
                    field.set(instance, bean);
                }
            }

            //Aware回调
            if (instance instanceof BeanNameAware) {
                ((BeanNameAware) instance).setBeanName(beanName);
            }
            //afterPropertiesSet回调
            if (instance instanceof InitializingBean) {
                ((InitializingBean) instance).afterPropertiesSet();
            }

            //beanPostProcessor 初始化前处理
            for (BeanPostProcessor beanPostProcessor : beanPostProcessorList) {
                instance = beanPostProcessor.postProcessAfterInitialization(instance, beanName);
            }
            return instance;

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

    private void scan(Class<?> componentClasses) {
        //获得需要扫描路径
        ComponentScan componentClassesAnnotation = componentClasses.getAnnotation(ComponentScan.class);
        String packagePath = componentClassesAnnotation.value();
        if (packagePath.equals("")) {
            throw new SpringException("packagePath cannot null  ");
        }

        //获得AppClassLoader加载后的class(经过类的)
        List<Class> beanList = getBeanClasses(packagePath);
        //遍历beanClasses得到BeanDefinition
        for (Class clazz : beanList) {
            //只有类上加了注解Component才会生成BeanDefinition
            if (clazz.isAnnotationPresent(Component.class)) {
                BeanDefinition beanDefinition = new BeanDefinition();
                beanDefinition.setBeanClass(clazz);

                Component componentAnnotation = (Component) clazz.getAnnotation(Component.class);
                String beanName = componentAnnotation.value();
                if (beanName.equals("")) {
                    beanName = Introspector.decapitalize(clazz.getSimpleName());
                }

                //判断类是否为BeanPostProcessor父类,,然后添加到BeanPostProcessorList
                if (BeanPostProcessor.class.isAssignableFrom(clazz)) {
                    try {
                        BeanPostProcessor beanPostProcessor = (BeanPostProcessor) clazz.getDeclaredConstructor().newInstance();
                        beanPostProcessorList.add(beanPostProcessor);
                    } catch (InstantiationException e) {
                        e.printStackTrace();
                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                    } catch (InvocationTargetException e) {
                        e.printStackTrace();
                    } catch (NoSuchMethodException e) {
                        e.printStackTrace();
                    }
                }

                //解析scope
                if (clazz.isAnnotationPresent(Scope.class)) {
                    Scope scope = (Scope) clazz.getAnnotation(Scope.class);
                    String scopeValue = scope.value();
                    if (ScopeEnum.singleton.name().equals(scopeValue)) {
                        beanDefinition.setScope(ScopeEnum.singleton);
                    } else {
                        beanDefinition.setScope(ScopeEnum.prototype);
                    }
                } else {
                    beanDefinition.setScope(ScopeEnum.prototype);
                }
                System.out.println("beanDefinition :" + beanDefinition.toString());
                beanDefinitionConcurrentHashMap.put(beanName, beanDefinition);
            }
        }
    }

    private List<Class> getBeanClasses(String packagePath) {
        /**
         * 获得AppClassLoader加载器
         * 加载过程经过:加载、验证、准备、解析
         * 加载:在硬盘中查找并通过IO读入字节码文件至JVM虚拟机方法区,同时在堆中创建class对象
         * 验证:校验字节码文件的正确性
         * 准备:为类的静态变量分配内存,并将期初始化默认值。此阶段仅为静态变量(static修饰的字段变量)分配内存
         * (例如static int=5 ,这里初始化值为0,5的赋值是在初始化时赋值);对于final static在编译的时候就已经分配了,
         * 解析:把类中的符号引用转换为直接引用
         *
         */
        List<Class> beanClasses = new ArrayList<>();
        ClassLoader classLoader = AnnotationConfigApplicationContext.class.getClassLoader();
        packagePath = packagePath.replace(".", "/");
        URL resource = classLoader.getResource(packagePath);
        File file = new File(resource.getFile());
        if (file.isDirectory()) {
            File[] files = file.listFiles();
            for (File f : files) {
                String fileName = f.getAbsolutePath();
                if (fileName.endsWith(".class")) {
                    String className = fileName.substring(fileName.indexOf("com"), fileName.indexOf(".class"));
                    className = className.replace("\\", ".");
                    try {
                        Class<?> clazz = classLoader.loadClass(className);
                        beanClasses.add(clazz);
                    } catch (ClassNotFoundException e) {
                        e.printStackTrace();
                    }
                }
            }
            for (Class beanClass : beanClasses) {
                System.out.println("scan class :" + beanClass.toString());
            }
        } else {
            throw new SpringException("packagePath cannot directory ");
        }
        return beanClasses;
    }

    @Override
    public Object getBean(String beanName, Object... args) {
        if (singletonObjects.containsKey(beanName)) {
            return singletonObjects.get(beanName);
        } else {
            BeanDefinition beanDefinition = beanDefinitionConcurrentHashMap.get(beanName);
            return doCreateBean(beanName, beanDefinition);
        }
    }
}

BeanPostProcessor

/**
 * @author yanbing
 * @version 1.0
 * @date 2021/9/5 9:40
 */
public interface BeanPostProcessor {

    /**
     * 初始化前执行
     * @param bean
     * @param beanName
     * @return
     * @throws
     */
    @Nullable
    default Object postProcessBeforeInitialization(Object bean, String beanName)   {
        return bean;
    }

    /**
     * 初始化后执行
     * @param bean
     * @param beanName
     * @return
     * @throws
     */
    @Nullable
    default Object postProcessAfterInitialization(Object bean, String beanName)   {
        return bean;
    }
@Component
public class YanibngBeanPostProcessor implements BeanPostProcessor {

    public Object postProcessAfterInitialization(Object bean, String beanName) {
        if ("orderService".equals(beanName)) {
            System.out.println("postProcessAfterInitialization  action ..............");
            //使用jdk动态代理生成代理类,
            Object proxy = Proxy.newProxyInstance(YanibngBeanPostProcessor.class.getClassLoader(), bean.getClass().getInterfaces(), new InvocationHandler() {
                @Override
                public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                    System.out.println("aop 切面核心逻辑");
                    //此方法才是真实方法的执行
                    return method.invoke(bean, args);
                }
            });
            return proxy;
        }
        return bean;
    }

}

BeanDefinition

public class BeanDefinition {


    private Class beanClass;
    ScopeEnum scope;

    public Class getBeanClass() {
        return beanClass;
    }

    public void setBeanClass(Class beanClass) {
        this.beanClass = beanClass;
    }

    public ScopeEnum getScope() {
        return scope;
    }

    public void setScope(ScopeEnum scope) {
        this.scope = scope;
    }

    @Override
    public String toString() {
        return "BeanDefinition{" +
                "beanClass=" + beanClass +
                ", scope=" + scope +
                '}';
    }
}

业务代码

启动入口

   public static void main(String[] args) {
        ApplicationContext context=new AnnotationConfigApplicationContext(AppConfig.class);
        OrderService bean = (OrderService) context.getBean("orderService");
        bean.order();

    }

AppConfig

@ComponentScan("com.yanbing.service")
public class AppConfig {
}

@Component("orderService")
public class OrderServiceimpl implements OrderService {
    @Autowired
    private UserServiceImpl userServiceImpl;

    @Override
    public void order() {
        System.out.println("OrderServiceimpl  order println  .....................");
        userServiceImpl.test();
    }
}
@Component
@Scope()
public class UserServiceImpl  implements BeanNameAware {

    static int i=0;
    
    static{
        System.out.println("静态代码块...............");
    }
    {
        System.out.println("代码块..............");
    }

    public void test() {
        System.out.println("UserServiceImpl  test println  .....................");
    }

    @Override
    public void setBeanName(String name) {
        System.out.println("实现了BeanNameAware 接口 beanName:"+name);
    }
}

执行效果

scan class :interface com.yanbing.service.OrderService
scan class :class com.yanbing.service.OrderServiceimpl
scan class :class com.yanbing.service.UserServiceImpl
scan class :class com.yanbing.service.YanibngBeanPostProcessor$1
scan class :class com.yanbing.service.YanibngBeanPostProcessor
beanDefinition :BeanDefinition{beanClass=class com.yanbing.service.OrderServiceimpl, scope=prototype}
beanDefinition :BeanDefinition{beanClass=class com.yanbing.service.UserServiceImpl, scope=singleton}
beanDefinition :BeanDefinition{beanClass=class com.yanbing.service.YanibngBeanPostProcessor, scope=prototype}
静态代码块...............
代码块..............
实现了BeanNameAware 接口 beanName:userServiceImpl
postProcessAfterInitialization  action ..............
aop 切面核心逻辑
OrderServiceimpl  order println  .....................
UserServiceImpl  test println  .....................

核心原理伪代码

Spring解析配置类底层

        //获得需要扫描路径
        ComponentScan componentClassesAnnotation = componentClasses.getAnnotation(ComponentScan.class);
        String packagePath = componentClassesAnnotation.value();
        if (packagePath.equals("")) {
            throw new SpringException("packagePath cannot null  ");
        }

   //中间略...............
   
          //只有类上加了注解Component才会生成BeanDefinition
            if (clazz.isAnnotationPresent(Component.class)) {
                BeanDefinition beanDefinition = new BeanDefinition();
                beanDefinition.setBeanClass(clazz);

                Component componentAnnotation = (Component) clazz.getAnnotation(Component.class);
                String beanName = componentAnnotation.value();
                if (beanName.equals("")) {
                    beanName = Introspector.decapitalize(clazz.getSimpleName());
                }

                //判断类是否为BeanPostProcessor父类,,然后添加到BeanPostProcessorList
                if (BeanPostProcessor.class.isAssignableFrom(clazz)) {
                    try {
                        BeanPostProcessor beanPostProcessor = (BeanPostProcessor) clazz.getDeclaredConstructor().newInstance();
                        beanPostProcessorList.add(beanPostProcessor);
                    }  catch (Exception e) {
                        e.printStackTrace();
                    }
                }

Spring依赖注入

    Field[] fields = beanClass.getDeclaredFields();
            for (Field field : fields) {
                //依赖注入
                if (field.isAnnotationPresent(Autowired.class)) {
                    //真实spring源码通过属性的类型获取对象的,属性的名称可以随意命名
                    String filedName = field.getName();
                    Object bean = getBean(filedName);
                    field.setAccessible(true);
                    field.set(instance, bean);
                }
            }

Aware和InitializingBean回调等底层

   //Aware回调
            if (instance instanceof BeanNameAware) {
                ((BeanNameAware) instance).setBeanName(beanName);
            }
            //afterPropertiesSet回调
            if (instance instanceof InitializingBean) {
                ((InitializingBean) instance).afterPropertiesSet();
            }

spring AOP的底层

    public Object postProcessAfterInitialization(Object bean, String beanName) {
        //我们这里简单化了,AOP源码做了大量工作识别类的方法是否需要切面
        if ("orderService".equals(beanName)) {
            System.out.println("postProcessAfterInitialization  action ..............");
            //使用jdk动态代理生成代理类,AOP中大部分对象都是通过cglib生成代理对象
            Object proxy = Proxy.newProxyInstance(YanibngBeanPostProcessor.class.getClassLoader(), bean.getClass().getInterfaces(), new InvocationHandler() {
                @Override
                public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                    System.out.println("aop 切面核心逻辑");
                    //此方法才是真实方法的执行
                    return method.invoke(bean, args);
                }
            });
            return proxy;
        }
        return bean;
    }

其他

  • 整个手写项目只依赖jdk1.8, 没有引入spring任何相关包
  • 需要了解更多细节,可以去下载我手写代码 :https://gitee.com/yanbing123456/spring-demo.git

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