Spring思考

Scroll Down

Spring的本质是将对象之间的关系通过可描述的形式进行配置,而不再由人为组装对象之间的依赖关系。

1、它会帮我们自动的创建对象然后保存起来
2、它会帮我们完成属性的填充
3、如果我们设置了Aop的功能,它会帮我们自动的代理,实现切面功能

Spring的生命周期流程
Spring作者希望,Spring在着手管理一个Bean的时候,它希望能够让Spring的使用者能够插手,Spring把一个类对象变成一个Java Object的每一步,怎么理解呢?

比如我们买了一栋新房子,这个房子需要去装修,你自己去装修诚然不够专业,不能够面面俱到,所以是我们就找了一个装修公司帮助我们装修新房,于是装修公司就开始预先画好的图纸进行装修,但是在装修的过程中,你为了让自己的新家更加温馨,你想挂一些壁画在墙上,但是图纸上却没有!于是你就找装修公司,要求装修公司在新家的墙上挂上一些壁画!装修公司在接受到你的请求之后,就吩咐装修的工人在图纸之外去给你在墙上挂上壁画之后,然后再接着装修!

上面这个小故事有 这样几个角色,我们把它和Spring对照起来!

你:代表框架的使用者!
新房:代表一个Class文件,你自己也能够装修,但是不够专业,所以交给装修公司! 那么你自己创建对象可能某些使用用起来很麻烦,所以我们交给了Spring容器!
装修公司:代表着Spring容器!
图纸:代表预设步骤,Spring原本就存在的步骤!
工人:Spring提供的各种接口!我们可以通过Spring工厂提供的接口做各种自定义的配置!
上面的小故事,大致可以描述Spring生命周期的核心思想!Spring再对一个Class文件实例化成具体的Spring Bean的时候,它提供了各种接口,由我们自己实现!然后再实例化过程中,不同的时机,去调用不同的接口!从而完成Spring的整个生命周期的创建!

Spring的生命周期大致分为以下部分!

扫描项目,将项目指定目录下的Class文件转换为Class对象!
读取Class对象属性包装为BeanDefinition,然后保存在一个Map中!(不难理解,他是为了后续创建或者读取这个类的信息更加方便取而创立的)
将全部的类转化为 BeanDefinition 并保存之后,开始调用第一个回调接口BeanFactoryPostProcessor#postProcessBeanFactory()!
「它的调用时机是将扫描到的Class文件转换为 BeanDefinition 之后调用的,我们可以通过回调的方法获取所有的BeanDefinition ,而后续的所有对Class的操作都是基于BeanDefinition 操作的,所以,我们可以通过修改它,来改变后续的流程!」
先从当前的容器对象取当前要创建的对象,当取出来的对象为null时开始着手创建对象!
做一系列的验证,比如验证这个类是否被排除、是否正在创建中、是否有依赖Bean【@DependsOn】注解、是否是单例等等!
验证通过之后,开始通过反射创建这个对象!
合并BeanDefinition ,这里涉及到Spring之前版本使用的父子容器的概念,属于另外一个知识点不做讲解!
判断当前对象是不是单例、是不是支持循环引用、是不是正在创建等!
执行第二个接口回调InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation()方法!
「它的执行时机是实例化完成之后,属性填充之前,它的返回值是一个布尔值,当返回false时,不做自动属性填充!」
执行第三个接口回调InstantiationAwareBeanPostProcessor#postProcessProperties()方法!
「他的执行时机是,实例化之后,属性填充检查之后,属性填充之前!它会返回一个属性,后续的属性填充会使用这个方法返回的值!我们可以在这个方法里面修改对应Bean的注入的值!」
填充属性到对象!
调用第四个回调接口BeanNameAware#setBeanName()方法!
「调用时机:属性填充给完毕后,调用初始化方法之前;它的功能是能获取bean的Name!」
调用第五个回调接口BeanClassLoaderAware#setBeanClassLoader()
「调用时机:BeanNameAware之后,他的功能是传入bean的类加载器;」
调用第六个回调接口BeanFactoryAware#setBeanFactory()!
「调用时机:BeanClassLoaderAware之后,用于设置beanFactory!」
调用第七个回调接口BeanPostProcessor#postProcessBeforeInitialization()方法
「调用时机是部分Aware之后,初始化方法之前!传入当前实例化好的对象和beanName,再初始化前做修改!」
回调第八个比较重要的生命周期的初始化方法,它可以是一个InitializingBean接口的bean,也可以是xml中配置的类,也可以是被加了@PostConstruct注解的方法!
「该方法内部逻辑可以用户自己编写,调用时机为:实例化完成之后调用!」
回调第九个回调接口 BeanPostProcessor#postProcessAfterInitialization()方法!
「该方法的调用时机为初始化方法执行之后,这里也是Bean实例化后的最后一步,也是SpringAop实现的重要的一步!」
注册销毁方法,以便Spring容器销毁的时候进行方法的销毁!