结论

答案是可以的。

Talk is cheap. Show me the code

第一步:定义一个类实现任意Spring中Bean生命周期相关方法。

package com.xxx.hyl.ignore.lifecycle;import org.springframework.beans.factory.InitializingBean;/**** 演示当前类跳过Spring IoC 容器Bean生命周期管理* @author 君战* */
public class IgnoreLifecycleBean implements InitializingBean {private String createdBy;// 这里只是为了演示,所以只选择实现InitializingBean接口,只要该接口可以跳过,其它的生命周期方法都是一样的。@Overridepublic void afterPropertiesSet() throws Exception {System.out.println(this.getClass().getSimpleName() + " -----> afterPropertiesSet 方法执行");}public String getCreatedBy() {return createdBy;}public void setCreatedBy(String createdBy) {this.createdBy = createdBy;}
}

第二步:编写一个类实现InstantiationAwareBeanPostProcessor接口,并重写其postProcessBeforeInstantiation方法。

package com.xxx.hyl.ignore.lifecycle;import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor;/*** 演示通过实现{@linkplain InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation(Class,* String)} 方法来让Bean跳过IoC容器生命周期管理** @author 君战 **/
public class CustomizedBeanPostProcessor implements InstantiationAwareBeanPostProcessor {@Overridepublic Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName)throws BeansException {if (IgnoreLifecycleBean.class.equals(beanClass)) {IgnoreLifecycleBean ignoreLifecycleBean = new IgnoreLifecycleBean();ignoreLifecycleBean.setCreatedBy("customize init");return ignoreLifecycleBean;}return null;}
}

第三步:编写一个类来测试

package com.xxx.hyl.ignore.lifecycle;import org.springframework.context.annotation.AnnotationConfigApplicationContext;/*** 演示Bean跳过IoC容器的生命周期管理* @author 君战* **/
public class IgnoreLifecycleBeanDemo {public static void main(String[] args) {AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();context.register(IgnoreLifecycleBean.class,CustomizedBeanPostProcessor.class);context.refresh();IgnoreLifecycleBean ignoreLifecycleBean = context.getBean(IgnoreLifecycleBean.class);System.out.println(ignoreLifecycleBean.getCreatedBy());}
}

第四步:查看控制台打印结果。

可以看到,IgnoreLifecycleBean 所实现的InitializingBean的afterPropertiesSet方法并未被调用,并且其getCreatedBy方法所返回的数据和我们在CustomizedBeanPostProcessor的postProcessBeforeInstantiation方法设置的一致。那么接下来就进入底层原理分析。

底层原理分析

在AbstractAutowireCapableBeanFactory的createBean方法中,首先通过resolveBeanClass方法来解析BeanDefinition,获取要实例化的BeanClass。然后调用RootBeanDefinition的prepareMethodOverrides方法,重点是接下来调用的resolveBeforeInstantiation方法,可以看到如果该方法的返回值不为空,则createBean方法结束,而不会再去调用IoC容器中真正实例化Bean的方法-doCreateBean。

// AbstractAutowireCapableBeanFactory#createBean(java.lang.String, org.springframework.beans.factory.support.RootBeanDefinition, java.lang.Object[])
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)throws BeanCreationException {if (logger.isTraceEnabled()) {logger.trace("Creating instance of bean '" + beanName + "'");}RootBeanDefinition mbdToUse = mbd;Class<?> resolvedClass = resolveBeanClass(mbd, beanName);if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {mbdToUse = new RootBeanDefinition(mbd);mbdToUse.setBeanClass(resolvedClass);}try {mbdToUse.prepareMethodOverrides();}catch (BeanDefinitionValidationException ex) {throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),beanName, "Validation of method overrides failed", ex);}try {// 调用所有实现了InstantiationAwareBeanPostProcessor接口的postProcessBeforeInstantiation方法// 任何一个InstantiationAwareBeanPostProcessor接口实现类的postProcessBeforeInstantiation方法返回值不为null,那么则结束当前beanName所对应Bean的创建和初始化。Object bean = resolveBeforeInstantiation(beanName, mbdToUse);if (bean != null) {return bean;}}catch (Throwable ex) {throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,"BeanPostProcessor before instantiation of bean failed", ex);}try {// 这是IoC容器真正实例化Bean的地方Object beanInstance = doCreateBean(beanName, mbdToUse, args);if (logger.isTraceEnabled()) {logger.trace("Finished creating instance of bean '" + beanName + "'");}return beanInstance;}catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {throw ex;}catch (Throwable ex) {throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);}
}

而讲到这个resolveBeforeInstantiation方法,就不得不提InstantiationAwareBeanPostProcessor接口,该接口继承自Spring IoC容器中大名鼎鼎的BeanPostProcessor接口,并定义了四个接口方法-postProcessBeforeInstantiation方法和postProcessAfterInstantiation方法以及postProcessProperties方法和postProcessPropertyValues方法(该方法已被标记为废弃)。

而前面的resolveBeforeInstantiation方法就是调用IoC容器中所有实现了该接口的实现类的postProce-ssBeforeInstantiation方法,入参为前面解析好的BeanClass和beanName,如果有某一个实现类实现的该方法返回了数据,则直接结束循环,当前Bean的整个实例化过程就结束了。Bean中所有的依赖项、生命周期相关的方法都不会再被处理,因此,很少会有处理器在该方法中返回数据。

// AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsBeforeInstantiation
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {Object bean = null;if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {// Make sure bean class is actually resolved at this point.if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {Class<?> targetType = determineTargetType(beanName, mbd);if (targetType != null) {bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);if (bean != null) {bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);}}}mbd.beforeInstantiationResolved = (bean != null);}return bean;
}protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {for (BeanPostProcessor bp : getBeanPostProcessors()) {if (bp instanceof InstantiationAwareBeanPostProcessor) {InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);if (result != null) {return result;}}}return null;
}

总结

Spring中的Bean是可以绕过IoC容器的Bean生命周期管理的,只需要实现InstantiationAwareBeanPostProcessor接口并重写其postProcessBeforeInstantiation方法来对指定beanClass进行创建,从而绕过IoC容器的生命周期管理。

但请慎用该手段,因为通过这种方式返回的Bean不仅其生命周期不受IoC容器管理,并且其依赖也不会被IoC容器所处理。如果其处于切点表达式的指定范围内,那么也不会被进行增强(动态代理/字节码增强),其方法上@Transactional注解将失去作用等等。

慎用!慎用!慎用!

Spring中的Bean可以绕过生命周期管理吗?相关推荐

  1. 业务规则的生命周期管理

    业务规则将公司从传统的软件开发生命周期(SDLC)中解放了出来,但这并不意味着业务规则的开发和部署不需要任何的监督管理.反而以我的经验来看,业务规则通常是以更为精细的方式进行跟踪管理的.其中,决策逻辑 ...

  2. 把对象的创建交给spring来管理——  1.创建bean的三种方式     2.bean对象的作用范围     3.bean对象的生命周期

    把对象的创建交给spring来管理 spring对bean的管理细节     1.创建bean的三种方式     2.bean对象的作用范围     3.bean对象的生命周期 创建Bean的三种方式 ...

  3. Spring Bean作用域与生命周期

    目录 Bean的作用域: Bean有六大行为模式 1.singleton:单例模式(默认) 2.prototype: 原型模式(多例模式) 3.request: 请求作用域(Spring MVC) 4 ...

  4. Spring 了解Bean的一生(生命周期)

    该篇博客就来了解IoC容器下Bean的一生吧,也可以理解为bean的生命周期. 首先你需要知道的知识 在IoC容器启动之后,并不会马上就实例化相应的bean,此时容器仅仅拥有所有对象的BeanDefi ...

  5. 一张图搞懂Spring bean的完整生命周期

    转载自 一张图搞懂Spring bean的完整生命周期 一张图搞懂Spring bean的生命周期,从Spring容器启动到容器销毁bean的全过程,包括下面一系列的流程,了解这些流程对我们想在其中任 ...

  6. Spring 中的bean 是线程安全的吗?

    点击上方蓝色"方志朋",选择"设为星标" 回复"666"获取独家整理的学习资料! 作者:myseries cnblogs.com/myser ...

  7. Spring5参考指南:Bean的生命周期管理

    文章目录 Spring Bean 的生命周期回调 总结生命周期机制 startup和Shutdown回调 优雅的关闭Spring IoC容器 Spring Bean 的生命周期回调 Spring中的B ...

  8. Spring中的Bean配置、属性配置、装配内容详细叙述

    文章目录 1.Bean的配置 1.1.配置方式 2.Bean的实例化 2.1.构造器实例化 2.2.静态工厂方式实例化 2.3.实例工厂方式实例化 3.Bean的作用域 3.1.作用域的种类 4.Be ...

  9. java spring源码_spring源码分析-spring中的bean

    接触过spring的人都知道,在spring中我们称java对象为bean,我们在spring的debug日志或者报错日志也能看到各种bean的描述.其实,spring的bean和java的对象之间是 ...

  10. Spring中的Bean是如何被回收的?

    1.架构师系列内容:架构师学习笔记(持续更新) 答:这需要看Spring中的bean的生命周期 spring中的生命周期有比如:singleton,prototype,session,request- ...

最新文章

  1. Bzoj1123 Blockade
  2. 什么是Vue.js?||为什么要学习流行框架||框架和库的区别?||MVC和MVVM的关系图解
  3. 转载:如何快速转载CSDN及博客园中的博客
  4. qimage加载bmp图片_批量修改图片大小,我发现了最简单的方法!
  5. vc6开发一个抓包软件_开发一个软件多少钱?传统app开发与0代码app制作方法对比...
  6. 如何在word中像LaTeX一样键入公式
  7. SQLSERVER日期时间汇总
  8. protoc 命令 java_用proto命令生成java文件
  9. android拉勾轮播,拉勾网顶部轮播图的实现(一)以及简单闭包的应用
  10. SolidKit.ERPs ERP集成接口工具(for SOLIDWORKS PDM)
  11. 深度学习算法-YOLO
  12. 聊聊图标和MBE图标
  13. googlePlay订阅商品对接流程
  14. URL重写实现会话跟踪
  15. BoundsChecker简易使用教程
  16. 大学计算机基础清华大学出版社 山东省高等学校教学改革项目,清华大学出版社-图书详情-《大学计算机基础(第2版)》...
  17. lvds 屏点亮的过程记录
  18. 游戏制作入门小知识------3ds Max
  19. 数组转JSON json对象 json字符串
  20. Python自学要多久?

热门文章

  1. SwiftUI实战二:组合视图和地图视图
  2. java interface 传值_前后端分离传值方案-RestfulAPI
  3. java socket 出现丢包_Java知识——网络编程、三次握手四次挥手
  4. GBDT, Gradient Boost Decision Tree,梯度提升决策树
  5. 12满秩分解与奇异值分解(2)
  6. 用eclipse无法打开html里用绝对路径添加的图片但是在外面可以打开的解决方法
  7. php mysqli 字段缺失,mysqli 为什么不提示字段异常
  8. Lucene创建索引和搜索索引
  9. Bioconductor学习_基因组坐标体系-Granges和IRanges
  10. 【UVALive - 7344】Numbered Cards【数位DP+状压DP】