2、Spring源码-代码模拟Spring底层原理

烟雨 4年前 (2021-07-11) 阅读数 328 #Spring源码
文章标签 Spring
Bean创建的生命周期,大致过程如下:
UserService.class >> 构造方法 >> UserService对象 >> 依赖注入(属性赋值) >> Aware接口回调  >> 初始化前(@PostConstruct) >> 初始化(实现InitializingBean) >> 初始化后(AOP)  >> Bean
  1. 利用该类的构造方法来实例化得到一个对象(如何一个类中有多个构造方法,则会进行选择,这个叫:推断构造方法)

  2. 得到一个对象后,Spring会判断该对象中是否被@Autowired注解了,把这些属性找出来并由Spring进行赋值(

  3. 依赖注入后,Spring会判断该对象是否实现了

  4. Aware回调后,Spring会判断该对象中是否存在某个方法被@PostConstruct注解了,如果存在,Spring会调用当前对象的此方法(

  5. 紧接着,Spring会判断该对象是否实现了InitializingBean接口,如果实现了,就表示当前对象必须实现该接口中的afterPropertiesSet()方法,那Spring就会调用当前对象中的afterPropertiesSet()方法(初始化)

  6. 最后,Spring会判断当前对象需不需要进行AOP,如果不需要那么Bean就创建完了,如果需要进行AOP,则会进行动态代理并生成一个代理对象做为Bean(初始化后)

项目结构如下:

image.png

一、注解

Spring4个注解:Autowired、Component、ComponentScan、PostConstruct、Scope

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.METHOD})
public @interface Autowired {
}
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Component {
    String value() default "";
}
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface ComponentScan {
    String value() default "";
}
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface PostConstruct {
}
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Scope {
    String value() default "singleton";
}

二、Aware接口

BeanNameAware接口:
public interface BeanNameAware {
    public void setBeanName(String name);
}

四、单例/实例枚举

public enum ScopeEnum {
    /**
     * 单例
     */
    singleton,
    prototype
}

五、BeanDefinition:Bean的定义类

public class BeanDefinition {
    //具体class
    private Class beanClass;
    //是否单例
    private 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;
    }
}

六、BeanPostProcessor接口

初始化前后处理接口
public interface BeanPostProcessor {
    /**
     * 初始化前处理
     */
    default Object postProcessBeforeInitialization(String beanName, Object bean){
        return bean;
    }
    /**
     * 初始化后处理
     */
    default Object postProcessAfterInitialization(String beanName, Object bean){
        return bean;
    }
}

接口对应的实现类

@Component
public class ZenderBeanPostProcessor implements BeanPostProcessor {
    /**
     * 初始化前处理
     *
     * @param beanName
     * @param bean
     */
    @Override
    public Object postProcessBeforeInitialization(String beanName, Object bean) {
        // 解析@PostConstruct注解
        Method[] methods = bean.getClass().getDeclaredMethods();
        for (Method method : methods) {
            if (method.isAnnotationPresent(PostConstruct.class)) {
                try {
                    //调用方法
                    method.invoke(bean);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }

        System.out.println("初始化前处理:" + beanName);
        return bean;
    }

    /**
     * 初始化后处理
     *
     * @param beanName
     * @param bean
     */
    @Override
    public Object postProcessAfterInitialization(String beanName, Object bean) {
        System.out.println("初始化后处理:" + beanName);
        //简单模拟AOP
        if("orderService".equals(beanName)){
            Object proxy = Proxy.newProxyInstance(ZenderBeanPostProcessor.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 proxy;
        }
        return bean;
    }
}

七、InitializingBean接口

如果bean实现了这个接口,初始化Bean时,会调用afterPropertiesSet()方法。

public interface InitializingBean {
    public void afterPropertiesSet();
}

接口对应的实现类

@Component("userService")
public class UserService implements InitializingBean {
    public void testUser(){
        System.out.println("testUser");
    }

    @Override
    public void afterPropertiesSet() {
        System.out.println("UserService Bean初始化的时候调用afterPropertiesSet方法!");
    }
}

八、Spring核心ApplicationContext类

public class ApplicationContext {
    //bean描述池
    private ConcurrentHashMap<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>();
    //单例池
    private ConcurrentHashMap<String, Object> singletonObjects = new ConcurrentHashMap<>();

    private List<BeanPostProcessor> beanPostProcessorList = new ArrayList<>();

    public ApplicationContext(Class configClass) {
        scan(configClass);
    }

    /**
     * 扫描class转换为BeanDefinition
     * @param configClass 扫描路径
     */
    private void scan(Class configClass){
        // 1、先得到包路径
        ComponentScan componentScanAnnotation = (ComponentScan) configClass.getAnnotation(ComponentScan.class);
        String packagePath = componentScanAnnotation.value();

        // 2、扫描包路径得到所有包下面的class
        List<Class> classList = genBeanClasses(packagePath);

        // 3、遍历class创建BeanDefinition
        for (Class clazz : classList) {
            if (clazz.isAnnotationPresent(Component.class)) {
                BeanDefinition beanDefinition = new BeanDefinition();
                beanDefinition.setBeanClass(clazz);

                // bean的名字要么Spring自动生成,要么从Component注解上获取bean名称
                Component component = (Component) clazz.getAnnotation(Component.class);
                String beanName = component.value();

                if (BeanPostProcessor.class.isAssignableFrom(clazz)) {
                    try {
                        BeanPostProcessor instance = (BeanPostProcessor) clazz.getDeclaredConstructor().newInstance();
                        beanPostProcessorList.add(instance);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                } else {
                    // 解析scope注解
                    if (clazz.isAnnotationPresent(Scope.class)) {
                        Scope scope = (Scope) clazz.getAnnotation(Scope.class);
                        String scopeValue = scope.value();
                        if (ScopeEnum.singleton.name().equals(scopeValue)) {
                            //单例Bean
                            beanDefinition.setScope(ScopeEnum.singleton);
                        } else {
                            beanDefinition.setScope(ScopeEnum.prototype);
                        }
                    } else {
                        //如果没配置scope注解,默认单例bean
                        beanDefinition.setScope(ScopeEnum.singleton);
                    }
                }

                beanDefinitionMap.put(beanName, beanDefinition);
            }
        }
    }

    /**
     * 获取指定路径下Class列表
     * @param packagePath 包路径
     * @return Class列表
     */
    private List<Class> genBeanClasses(String packagePath) {
        List<Class> beanClasses = new ArrayList<>();

        ClassLoader classLoader = ApplicationContext.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();
                    }
                }
            }
        }

        return beanClasses;
    }

    /**
     * 基于BeanDefinition来创建bean
     * @param beanName bean名称
     * @param beanDefinition
     */
    private Object doCreateBean(String beanName, BeanDefinition beanDefinition) {
        Class beanClass = beanDefinition.getBeanClass();

        try {
            // 实例化
            Constructor declaredConstructor = beanClass.getDeclaredConstructor();
            Object instance = declaredConstructor.newInstance();

            // 解析Autowired注解,依赖注入,填充属性
            Field[] fields = beanClass.getDeclaredFields();
            for (Field field : fields) {
                if (field.isAnnotationPresent(Autowired.class)) {
                    //在Spring中,会先根据类型查找,查找不到再通过名称去找
                    String fieldName = field.getName();
                    Object bean = getBean(fieldName);

                    field.setAccessible(true);
                    field.set(instance, bean);
                }
            }

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

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

            // 如果实现了InitializingBean,则调用afterPropertiesSet方法
            if (instance instanceof InitializingBean) {
                ((InitializingBean)instance).afterPropertiesSet();
            }

            //AOP
            for (BeanPostProcessor beanPostProcessor: beanPostProcessorList) {
                instance = beanPostProcessor.postProcessAfterInitialization(beanName, instance);
            }

            return instance;
        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }

    /**
     * 获取bean
     * @param beanName bean名称
     * @return
     */
    public Object getBean(String beanName) {
        BeanDefinition beanDefinition = beanDefinitionMap.get(beanName);

        //获取单例Bean
        if (singletonObjects.containsKey(beanName)) {
            Object singletonObject = singletonObjects.get(beanName);
            if (singletonObject == null){
                singletonObjects.put(beanName, doCreateBean(beanName, beanDefinition));
            }
            return singletonObjects.get(beanName);
        } else {
            return doCreateBean(beanName, beanDefinition);
        }
    }
}

九、测试相关类

9.1、配置类

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

9.2、service

public interface OrderService {
    public void testOrder();
}
@Component("orderService")
public class OrderServiceImpl implements OrderService, BeanNameAware {
    @Autowired
    private UserService userService;

    private String beanName;

    public void testOrder() {
        System.out.println("testOrder");
        userService.testUser();
    }

    @Override
    public void setBeanName(String beanName) {
        System.out.println("beanName:" + beanName);
        this.beanName = beanName;
    }

    @PostConstruct
    public void testPostConstruct() {
        System.out.println("test_PostConstruct");
    }
}
@Component("userService")
public class UserService implements InitializingBean {
    public void testUser(){
        System.out.println("testUser");
    }

    @Override
    public void afterPropertiesSet() {
        System.out.println("UserService Bean初始化的时候调用afterPropertiesSet方法!");
    }
}
public class Test {
    public static void main(String[] args) {
        ApplicationContext applicationContext = new ApplicationContext(AppConfig.class);
        OrderService orderService = (OrderService) applicationContext.getBean("orderService");
        orderService.testOrder();
    }
}

运行结果:

image.png

版权声明

非特殊说明,本文由Zender原创或收集发布,欢迎转载。

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

作者文章
热门