欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 房产 > 家装 > Spring bean的生命周期和扩展

Spring bean的生命周期和扩展

2025/1/18 23:29:27 来源:https://blog.csdn.net/qq_26437925/article/details/145044487  浏览:    关键词:Spring bean的生命周期和扩展

接AnnotationConfigApplicationContext流程看实例化的beanPostProcessor-CSDN博客,以具体实例看bean生命周期的一些执行阶段

bean生命周期流程

生命周期扩展处理说明
实例化:createBeanInstance

构造方法, 如@Autowired的构造方法注入依赖bean

如UserService构造方法注入AppDAO:

@Autowired
public UserService(AppDAO appDAO) {System.out.println("@Autowired appDAO:" + appDAO);this.appDAO = appDAO;
}
属性设置:populateBean

如setter方法注入的依赖

如@Autoware的filed注入

如UserService中注入UserDAO:

@Resource(name = "u")
public void setUserDAO(UserDAO userDAO) {System.out.println("setUserDAO:" + userDAO);this.userDAO = userDAO;
}
初始化:initializeBean

1. BeanPostProcessor#postProcessBeforeInitialization

2. @PostConstruct

3. InitializingBean#afterPropertiesSet

initMethod

4. BeanPostProcessor#postProcessAfterInitialization

上一步骤属性设置完后,初始化方法前后都可以扩展。

例如BeanPostProcessor#postProcessBeforeInitialization,直接改变了set注入的appDAO对象

@Component
public class ServiceBeanPostProcessor implements BeanPostProcessor {@Overridepublic Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {// Bean 初始化前的逻辑if (beanName.equals("userService")) {UserService userService = (UserService)bean;AppDAO appDAO = new AppDAOImpl2();userService.setAppDAO(appDAO);System.out.println("postProcessBeforeInitialization:" + ":" + bean);}return bean;}
销毁

1. @PreDestroy

2. DisposableBean#destroy

destroyMethod

附org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean

/*** Actually create the specified bean. Pre-creation processing has already happened* at this point, e.g. checking {@code postProcessBeforeInstantiation} callbacks.* <p>Differentiates between default bean instantiation, use of a* factory method, and autowiring a constructor.* @param beanName the name of the bean* @param mbd the merged bean definition for the bean* @param args explicit arguments to use for constructor or factory method invocation* @return a new instance of the bean* @throws BeanCreationException if the bean could not be created* @see #instantiateBean* @see #instantiateUsingFactoryMethod* @see #autowireConstructor*/protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)throws BeanCreationException {// Instantiate the bean.BeanWrapper instanceWrapper = null;if (mbd.isSingleton()) {instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);}if (instanceWrapper == null) {instanceWrapper = createBeanInstance(beanName, mbd, args);}final Object bean = instanceWrapper.getWrappedInstance();Class<?> beanType = instanceWrapper.getWrappedClass();if (beanType != NullBean.class) {mbd.resolvedTargetType = beanType;}// Allow post-processors to modify the merged bean definition.synchronized (mbd.postProcessingLock) {if (!mbd.postProcessed) {try {applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);}catch (Throwable ex) {throw new BeanCreationException(mbd.getResourceDescription(), beanName,"Post-processing of merged bean definition failed", ex);}mbd.postProcessed = true;}}// Eagerly cache singletons to be able to resolve circular references// even when triggered by lifecycle interfaces like BeanFactoryAware.boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&isSingletonCurrentlyInCreation(beanName));if (earlySingletonExposure) {if (logger.isTraceEnabled()) {logger.trace("Eagerly caching bean '" + beanName +"' to allow for resolving potential circular references");}addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));}// Initialize the bean instance.Object exposedObject = bean;try {populateBean(beanName, mbd, instanceWrapper);exposedObject = initializeBean(beanName, exposedObject, mbd);}catch (Throwable ex) {if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {throw (BeanCreationException) ex;}else {throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);}}if (earlySingletonExposure) {Object earlySingletonReference = getSingleton(beanName, false);if (earlySingletonReference != null) {if (exposedObject == bean) {exposedObject = earlySingletonReference;}else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {String[] dependentBeans = getDependentBeans(beanName);Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);for (String dependentBean : dependentBeans) {if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {actualDependentBeans.add(dependentBean);}}if (!actualDependentBeans.isEmpty()) {throw new BeanCurrentlyInCreationException(beanName,"Bean with name '" + beanName + "' has been injected into other beans [" +StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +"] in its raw version as part of a circular reference, but has eventually been " +"wrapped. This means that said other beans do not use the final version of the " +"bean. This is often the result of over-eager type matching - consider using " +"'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");}}}}// Register bean as disposable.try {registerDisposableBeanIfNecessary(beanName, bean, mbd);}catch (BeanDefinitionValidationException ex) {throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);}return exposedObject;}

扩展执行

接上文:AnnotationConfigApplicationContext流程看实例化的beanPostProcessor-CSDN博客,来看这些BeanPostProcessor如何起作用

测试bean定义类如下

@Service("userService")
public class UserService implements InitializingBean, DisposableBean {private String userServiceName;private UserDAO userDAO;private AppDAO appDAO;/*** field 注入*/@Autowiredprivate CommonService commonService;public UserService() {System.out.println("constructor");}/*** 类似于 InitializingBean 的 afterPropertiesSet() 方法*/@PostConstructpublic void init() {System.out.println("PostConstruct userService");System.out.println("userDAO is not null:" + (userDAO != null));System.out.println("appDAO is not null:" + (appDAO != null));userServiceName = "selfUserService";}/*** setter注入* @param userDAO*/@Resource(name = "u")public void setUserDAO(UserDAO userDAO) {System.out.println("setUserDAO:" + userDAO);this.userDAO = userDAO;}/*** 构造器注入* @param appDAO*/@Autowiredpublic UserService(AppDAO appDAO) {System.out.println("@Autowired appDAO:" + appDAO);this.appDAO = appDAO;}public void add(User user) {userDAO.save(user);}public UserDAO getUserDAO() {return userDAO;}/*** 类似于 DisposableBean 的 destroy() 方法*/@PreDestroypublic void preDestroy() {System.out.println("preDestroy");}@Overridepublic void afterPropertiesSet() throws Exception {System.out.println("afterPropertiesSet userService");}@Overridepublic void destroy() throws Exception {System.out.println("destroy userService");}public void setUserServiceName(String userServiceName) {this.userServiceName = userServiceName;}public void setAppDAO(AppDAO appDAO) {this.appDAO = appDAO;}@Overridepublic String toString() {return "UserService{" +"userServiceName='" + userServiceName + '\'' +", userDAO=" + userDAO +", appDAO=" + appDAO +", commonService=" + commonService +'}';}
}

InstantiationAwareBeanPostProcessors:SmartInstantiationAwareBeanPostProcessor

推断构造函数,最后是AutowiredAnnotationBeanPostProcessor完成构造函数的推断

最后判断有@Autowired的构造函数 完成实例化过程

InstantiationAwareBeanPostProcessor:CommonAnnotationBeanPostProcessor

populate阶段CommonAnnotationBeanPostProcessor完成setter注入

/*** setter注入* @param userDAO*/
@Resource(name = "u")
public void setUserDAO(UserDAO userDAO) {System.out.println("setUserDAO:" + userDAO);this.userDAO = userDAO;
}

org.springframework.context.annotation.CommonAnnotationBeanPostProcessor#postProcessProperties

@Overridepublic PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {InjectionMetadata metadata = findResourceMetadata(beanName, bean.getClass(), pvs);try {metadata.inject(bean, beanName, pvs);}catch (Throwable ex) {throw new BeanCreationException(beanName, "Injection of resource dependencies failed", ex);}return pvs;}

InstantiationAwareBeanPostProcessor:AutowiredAnnotationBeanPostProcessor

populate阶段AutowiredAnnotationBeanPostProcessor完成@Autorwired的filed的注入,具体可以再次阅读:Spring5.1.3 @Autorwired注解原理重新回顾-CSDN博客

BeanPostProcessor#postProcessBeforeInitialization

initializeBean阶段会执行BeanPostProcessor的postProcessBeforeInitialization方法
执行自定义的BeanPostProcessor

执行CommonAnnotationBeanPostProcessor解析@PostConstruct注解

@PostConstruct
public void init() {System.out.println("PostConstruct userService");System.out.println("userDAO is not null:" + (userDAO != null));System.out.println("appDAO is not null:" + (appDAO != null));userServiceName = "selfUserService";
}

执行InitializingBean的afterPropertiesSet方法

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#invokeInitMethods

protected void invokeInitMethods(String beanName, final Object bean, @Nullable RootBeanDefinition mbd)throws Throwable {boolean isInitializingBean = (bean instanceof InitializingBean);if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {if (logger.isTraceEnabled()) {logger.trace("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");}if (System.getSecurityManager() != null) {try {AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {((InitializingBean) bean).afterPropertiesSet();return null;}, getAccessControlContext());}catch (PrivilegedActionException pae) {throw pae.getException();}}else {((InitializingBean) bean).afterPropertiesSet();}}if (mbd != null && bean.getClass() != NullBean.class) {String initMethodName = mbd.getInitMethodName();if (StringUtils.hasLength(initMethodName) &&!(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&!mbd.isExternallyManagedInitMethod(initMethodName)) {invokeCustomInitMethod(beanName, bean, mbd);}}}
BeanPostProcessor#postProcessAfterInitialization

InitializingBean最后阶段会执行BeanPostProcessor的postProcessAfterInitialization方法

本例

@Component
public class ServiceBeanPostProcessor implements BeanPostProcessor {@Overridepublic Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {// Bean 初始化前的逻辑if (beanName.equals("userService")) {UserService userService = (UserService)bean;AppDAO appDAO = new AppDAOImpl2();userService.setAppDAO(appDAO);System.out.println("postProcessBeforeInitialization:" + ":" + bean);}return bean;}@Overridepublic Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {// Bean 初始化后的逻辑if (beanName.equals("userService")) {System.out.println("postProcessAfterInitialization:" + ":" + bean);}return bean;}
}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com