Spring源码 20 手写模拟源码
阅读原文时间:2023年07月09日阅读:1

参考源

https://www.bilibili.com/video/BV1tR4y1F75R?spm_id_from=333.337.search-card.all.click

https://www.bilibili.com/video/BV12Z4y197MU?spm_id_from=333.999.0.0

《Spring源码深度解析(第2版)》

版本

本文章基于 Spring 5.3.15


项目地址

https://gitee.com/liao-hang/hand-write-spring.git

模拟 Spring

自动装配

Autowired

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Autowired {

}

组件

Component

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Component {

    String value() default "";

}

组件扫描

ComponentScan

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface ComponentScan {

    String value() default "";

}

范围

Scope

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Scope {

    String value() default "";

}

BeanDefinition

public class BeanDefinition {

    /**
     * 类型
     */
    private Class type;

    /**
     * 范围
     */
    private String scope;

    public Class getType() {
        return type;
    }

    public void setType(Class type) {
        this.type = type;
    }

    public String getScope() {
        return scope;
    }

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

BeanNameAware

public interface BeanNameAware {

    /**
     * 设置 Bean 名称
     * @param beanName Bean名称
     */
    void setBeanName(String beanName);

}

BeanPostProcessor

public interface BeanPostProcessor {

    /**
     * 初始化前
     * @param beanName Bean名称
     * @param bean Bean对象
     * @return
     */
    Object postProcessBeforeInitialization(String beanName, Object bean);

    /**
     * 初始化后
     * @param beanName Bean名称
     * @param bean Bean对象
     * @return
     */
    Object postProcessAfterInitialization(String beanName, Object bean);

}

InitializationBean

public interface InitializationBean {

    /**
     * 属性设置后
     */
    void afterPropertiesSet();

}

AnnotationConfigApplicationContext

public class AnnotationConfigApplicationContext {

    /**
     * 配置的类
     */
    private Class configClass;

    /**
     * Bean 后置处理器列表
     */
    private List<BeanPostProcessor> beanPostProcessorList = new ArrayList<>();

    /**
     * Bean 定义信息池
     */
    private ConcurrentHashMap<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>();

    /**
     * 单例池
     */
    private ConcurrentHashMap<String, Object> singletonObjects = new ConcurrentHashMap<>();

    public AnnotationConfigApplicationContext(Class configClass) {
        this.configClass = configClass;

        /*
        扫描 -> BeanDefinition -> beanDefinitionMap
         */
        // 是否有 @ComponentScan 注解
        if (configClass.isAnnotationPresent(ComponentScan.class)) {
            ComponentScan componentScan = (ComponentScan) configClass.getAnnotation(ComponentScan.class);
            // 注解中的路径
            String path = componentScan.value();
            // 处理路径
            path = path.replace(".", "/");
            // 类加载器
            ClassLoader classLoader = AnnotationConfigApplicationContext.class.getClassLoader();
            // 资源
            URL resource = classLoader.getResource(path);
            // 文件
            File file = new File(resource.getFile());
            // 如果为目录
            if (file.isDirectory()) {
                // 文件列表
                File[] files = file.listFiles();
                for (File f : files) {
                    // 绝对路径
                    String fileName = f.getAbsolutePath();
                    // 是否为 class 文件
                    if (fileName.endsWith(".class")) {
                        // 类名 cn\sail\test\文件名
                        String className = fileName.substring(fileName.indexOf("cn"), fileName.indexOf(".class"));
                        // 处理路径
                        className = className.replace("\\", ".");
                        try {
                            Class<?> clazz = classLoader.loadClass(className);
                            // 是否有 @Component 注解
                            if (clazz.isAnnotationPresent(Component.class)) {
                                // 接口和类是否相同或者是否为其超类或超接口
                                if (BeanPostProcessor.class.isAssignableFrom(clazz)) {
                                    BeanPostProcessor instance = (BeanPostProcessor) clazz.newInstance();
                                    beanPostProcessorList.add(instance);
                                }
                                Component component = clazz.getAnnotation(Component.class);
                                String beanName = component.value();
                                if ("".equals(beanName)) {
                                    beanName = Introspector.decapitalize(clazz.getSimpleName());
                                }
                                BeanDefinition beanDefinition = new BeanDefinition();
                                beanDefinition.setType(clazz);
                                // 是否有 @Scope 注解
                                if (clazz.isAnnotationPresent(Scope.class)) {
                                    // 如果有,以传入的模式为准
                                    Scope scope = clazz.getAnnotation(Scope.class);
                                    beanDefinition.setScope(scope.value());
                                } else {
                                    // 如果没有,默认为单例模式
                                    beanDefinition.setScope("singleton");
                                }
                                beanDefinitionMap.put(beanName, beanDefinition);
                            }
                        } catch (ClassNotFoundException e) {
                            e.printStackTrace();
                        } catch (InstantiationException e) {
                            e.printStackTrace();
                        } catch (IllegalAccessException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }

        // 实例化单例 Bean
        for (String beanName : beanDefinitionMap.keySet()) {
            BeanDefinition beanDefinition = beanDefinitionMap.get(beanName);
            // 如果为单例模式,将 BeanDefinition 放入单例池中,下次直接从池中取,以保证单例
            if ("singleton".equals(beanDefinition.getScope())) {
                Object bean = createBean(beanName, beanDefinition);
                singletonObjects.put(beanName, bean);
            }
        }
    }

    /**
     * 创建 Bean
     * @param beanName Bean 名称
     * @param beanDefinition Bean 定义信息
     * @return Bean 对象
     */
    private Object createBean(String beanName, BeanDefinition beanDefinition) {
        Class clazz = beanDefinition.getType();
        try {
            Object instance = clazz.getConstructor().newInstance();
            // 依赖注入
            for (Field f : clazz.getDeclaredFields()) {
                // 是否有 @Autowired 注解
                if (f.isAnnotationPresent(Autowired.class)) {
                    // 忽略访问修饰符限制
                    f.setAccessible(true);
                    // 注入
                    f.set(instance, getBean(f.getName()));
                }
            }
            // Aware
            if (instance instanceof BeanNameAware) {
                ((BeanNameAware) instance).setBeanName(beanName);
            }
            // 初始化前
            for (BeanPostProcessor beanPostProcessor : beanPostProcessorList) {
                instance = beanPostProcessor.postProcessBeforeInitialization(beanName, instance);
            }
            // 初始化
            if (instance instanceof InitializationBean) {
                ((InitializationBean) instance).afterPropertiesSet();
            }
            // 初始化后
            for (BeanPostProcessor beanPostProcessor : beanPostProcessorList) {
                instance = beanPostProcessor.postProcessAfterInitialization(beanName, instance);
            }
            return instance;
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
        return null;
    }

    public Object getBean(String beanName) {
        BeanDefinition beanDefinition = beanDefinitionMap.get(beanName);
        if (beanDefinition == null) {
            throw new NullPointerException();
        } else {
            String scope = beanDefinition.getScope();
            if ("singleton".equals(scope)) {
                Object bean = singletonObjects.get(beanName);
                // 如果单例池中没有对应 Bean,创建 Bean 后再放入池中
                if (bean == null) {
                    bean = createBean(beanName, beanDefinition);
                    singletonObjects.put(beanName, bean);
                }
                return bean;
            } else {
                // 如果不是单例模式,直接创建 Bean
                return createBean(beanName, beanDefinition);
            }
        }
    }

}

使用 Spring

AppConfig

@ComponentScan("cn.sail.test")
public class AppConfig {

}

UserInterface

public interface UserInterface {

    /**
     * 测试
     */
    void test();

}

UserService

@Component
public class UserService implements UserInterface{

    @Autowired
    private OrderService orderService;

    @Override
    public void test() {
        System.out.println(orderService);
    }

}

OrderService

@Component
public class OrderService {

}

MyBeanPostProcessor

@Component
public class MyBeanPostProcessor implements BeanPostProcessor {

    /**
     * 初始化前
     *
     * @param beanName
     * @param bean
     * @return
     */
    @Override
    public Object postProcessBeforeInitialization(String beanName, Object bean) {
        if ("userService".equals(beanName)) {
            System.out.println("1111");
        }
        return bean;
    }

    /**
     * 初始化后
     *
     * @param beanName
     * @param bean
     * @return
     */
    @Override
    public Object postProcessAfterInitialization(String beanName, Object bean) {
        if ("userService".equals(beanName)) {
            Object proxyInstance = Proxy.newProxyInstance(MyBeanPostProcessor.class.getClassLoader(), bean.getClass().getInterfaces(), new InvocationHandler() {
                @Override
                public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                    System.out.println("切面逻辑");
                    return method.invoke(bean, args);
                }
            });
            return proxyInstance;
        }
        return bean;
    }
}

Test

public class Test {

    public static void main(String[] args) {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);
        UserInterface userService = (UserInterface) applicationContext.getBean("userService");
        userService.test();
    }

}