时隔一年多,在掌握了spring、springboot、springcloud之后
我再次回头,重新学习spring框架
bean的生命周期学习:
在传统的xml配置中,可以这样自定义初始化和销毁方法:
init-method="" destroy-method=""
注解方式的简单使用:
@configuration public class lifecircleconfig { @bean(initmethod = "init",destroymethod = "destroy") public car car(){ return new car(); } }
public class car { public car(){ system.out.println("construct car!"); } public void init(){ system.out.println("car init!"); } public void destroy(){ system.out.println("car destroy!"); } }
public class lifecircletest { private static annotationconfigapplicationcontext applicationcontext = new annotationconfigapplicationcontext(lifecircleconfig.class); @test public void test(){ applicationcontext.close(); } }
注意:要有close方法,否则不会打印car销毁方法
打印如下:
construct car! car init! car destroy!
这里默认的是单实例bean
如果是多实例的话,按照以上的测试代码是不会打印的,因为多实例情况下,在获取bean的情况下才会创建对象
而且在多例情况下,只会调用初始化和构造方法,不会调用销毁方法
以上测试代码只完成了初始化ioc容器,所以什么都不打印
实现spring中接口方式:这时候不需要在@bean中进行配置
public class car implements initializingbean, disposablebean { public car() { system.out.println("construct car!"); } public void afterpropertiesset() throws exception { system.out.println("car init!"); } public void destroy() { system.out.println("car destroy!"); } }
使用java原生注解:
public class car { public car() { system.out.println("construct car!"); } @postconstruct public void init() { system.out.println("car init!"); } @predestroy public void destroy() { system.out.println("car destroy!"); } }
使用spring中bean的后置处理器:
@component public class mybeanpostprocessor implements beanpostprocessor { /** * 初始化前调用 */ public object postprocessbeforeinitialization(object bean, string beanname) throws beansexception { system.out.println("postprocessbeforeinitialization " + bean + " " + beanname); return bean; } /** * 初始化后调用 */ public object postprocessafterinitialization(object bean, string beanname) throws beansexception { system.out.println("postprocessafterinitialization " + bean + " " + beanname); return bean; } }
@configuration @componentscan("org.dreamtech.bean") public class lifecircleconfig { @bean public car car(){ return new car(); } }
测试后部分打印如下:
construct car! postprocessbeforeinitialization org.dreamtech.bean.car@2d9d4f9d car postprocessafterinitialization org.dreamtech.bean.car@2d9d4f9d car
beanpostprocessor原理:
查看这一段源码:
initializebean(beanname, exposedobject, mbd)方法中:
object wrappedbean = bean; if (mbd == null || !mbd.issynthetic()) { wrappedbean = applybeanpostprocessorsbeforeinitialization(wrappedbean, beanname); } try { invokeinitmethods(beanname, wrappedbean, mbd); } catch (throwable ex) { throw new beancreationexception( (mbd != null ? mbd.getresourcedescription() : null), beanname, "invocation of init method failed", ex); } if (mbd == null || !mbd.issynthetic()) { wrappedbean = applybeanpostprocessorsafterinitialization(wrappedbean, beanname); }
在invokeinitmethods初始化方法之前
调用了applybeanpostprocessorsbeforeinitialization,也就是调用了所有postprocessor的before方法
在invokeinitmethods初始化方法之后
调用了applybeanpostprocessorsafterinitialization,也就是调用了所有postprocessor的after方法
进入applybeanpostprocessorsbeforeinitialization方法查看源码:
遍历所有的processor,一旦返回null,就会跳出循环
@override public object applybeanpostprocessorsbeforeinitialization(object existingbean, string beanname) throws beansexception { object result = existingbean; for (beanpostprocessor beanprocessor : getbeanpostprocessors()) { result = beanprocessor.postprocessbeforeinitialization(result, beanname); if (result == null) { return result; } } return result; }
在initializebean方法之前,调用的是populatebean方法
作用:给属性赋值
// initialize the bean instance. object exposedobject = bean; try { populatebean(beanname, mbd, instancewrapper); if (exposedobject != null) { exposedobject = initializebean(beanname, exposedobject, mbd); } }
所以:beanpostprocessor是在bean赋值之后,初始化的过程前后执行的
beanpostprocessor在spring底层的使用:
获取ioc容器的接口:
public interface applicationcontextaware extends aware { void setapplicationcontext(applicationcontext var1) throws beansexception; }
而它就是基于beanpostprocessor的,代码过长就不截取了
class applicationcontextawareprocessor implements beanpostprocessor
或者是参数校验:也使用到了beanpostprocessor
public class beanvalidationpostprocessor implements beanpostprocessor, initializingbean
部分代码如下:
public object postprocessbeforeinitialization(object bean, string beanname) throws beansexception { if (!this.afterinitialization) { this.dovalidate(bean); } return bean; } public object postprocessafterinitialization(object bean, string beanname) throws beansexception { if (this.afterinitialization) { this.dovalidate(bean); } return bean; }
如对本文有疑问, 点击进行留言回复!!
unity的错误解决办法:NullReferenceException: Object reference not set to an instance of an object;tiny proje
Hadoop 之 HDFS (HDFS 数据流的 读写 流程)
听说你一读Spring源码就懵逼?我帮你把架子搭好了,你填就行!
首席架构师推荐:金融保险领域数字化转型实践--如何优雅地修改业务中台中分层应用Maven多模块的版本号?(命令导入式)
[JVM学习之路]一、初识JVM,了解其结构、模型及生命周期
网友评论