重庆造价工程建设信息网站,杭州哪里找网站建设的兼职,5g天天奭5g天天运动网站代码,织梦软件展示网站源码个人背景
如标题所示#xff0c;我的个人背景非常简单#xff0c;Java开发经验1年半#xff0c;学历普通#xff0c;2本本科毕业#xff0c;毕业后出来就一直在Crud#xff0c;在公司每天重复的工作对我的技术提升并没有什么帮助#xff0c;但小镇出来的我也深知自我努…个人背景
如标题所示我的个人背景非常简单Java开发经验1年半学历普通2本本科毕业毕业后出来就一直在Crud在公司每天重复的工作对我的技术提升并没有什么帮助但小镇出来的我也深知自我努力的重要性想要改变“命运”没有背景没有资本的人只能通过勤奋获得。
幸运女神往往会眷顾努力的人所以当好运降临到我头上我并不诧异目前拿到了美团30K的offer下文也不说废话主要分享我这次“美团面试经历”和“个人学习方法”希望能帮助到你们。 二、Spring生命周期的大胆猜测
这里分享一个阅读源码的小技巧捉大放小连蒙带猜8字真言我们在阅读源码过程中因为你要知道每一个被开源出来的优秀框架其源码的体系都是极其庞大复杂的我们不能面面俱到所以在看源码过程中一定不能被细枝末节缠住一定要先理清楚整个框架的一个大致思想和大致的框架体系再去搞那些细枝末节其效率会好很多其次在看源码过程中我们一定要大胆的去想去猜测如果这个功能让你自己去写你会怎么实现
我们今天学习SpringBean的生命周期也是按照这个8字真言去学习通过我们之前所学Spring大致有以下的功能
他会帮我们自动的创建对象然后保存起来他会帮我们完成属性的填充如果我们设置了Aop的功能他会帮我们自动的代理实现切面功能
我们从平常的使用中至少可以得知以上的三点如果让你自己去实现必会如何实现呢
首先他既然能够帮我们自己创建对象那么他肯定是通过反射来创建的通过反射来创建就必定绕不过去要使用Class对象创建那么我们如何获取Class对象呢 去扫描项目将指定的包下的加了注解的类文件切割获取Class名称通过反射加载Class名称反射创建java对象我们要完成属性的填充为了方便和性能方面我肯定会把这些创建好的对象保存起来无疑Map容器是最合适的我们在创建一个对象完成之后反射拿到里面的属性如果需要填充我们先去我们之前保存的容器里面去取取不出来在反射吧这个依赖的属性创建出来然后填充进对象再保存在容器里面从而完成了属性的注入填充完成属性之后我们那当前对象取与Aop逻辑进行对比判断是否需要代理不需要则创建完成保存进Map容器需要代理则对当前这个类进行jdk或者cglib的代理然后再保存进容器里面
于是乎我们自己实现了一个Spring管理一个Bean的所有过程画个图他大概长这样 自己实现看起来整个流程就很清晰扫描、创建、注入、代理、保存一应俱全但是Spring的实现方式远比我们自己实现的要复杂的多得多
三、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容器销毁的时候进行方法的销毁
整体的方法流程示例图如下 四、对应源码结构图 最后
送大家一个小福利点击领取Java全套进阶资料 m/doc/DSmxTbFJ1cmN1R2dB)**
[外链图片转存中…(img-rZNaTsWe-1624684547280)]
[外链图片转存中…(img-4XB840rx-1624684547282)]