您现在的位置是:首页 > 文章详情

一个 Bean 就这样走完了它的一生之 Bean 的出生

日期:2025-05-18点击:13

生命周期流程

Spring 中的一个 Bean 从被创建到被销毁,需要经历很多个阶段的生命周期,下图是一个 Bean 从创建到销毁的生命周期流程: image.png

在 Bean 的各个生命周期流程点,Spring 都提供了对应的接口或者注解,以便开发者在各个生命周期的流程点能够做一些自己的操作。

案例解析

定义 Spring 上下文工具类

Spring 中生命周期最常见的应用可能是定义一个 Spring 上下文的工具类。这个工具类也使用 @Component 注解修饰,表明它也是一个 Bean ,其次它实现了 ApplicationContextAware 接口,则说明它作为一个 Bean 被创建以及初始化的过程中需要调用 setApplicationContext() 方法,设置它所在的 Spring 上下文。代码如下:

@Component public class SpringContextUtils implements ApplicationContextAware { private static ApplicationContext applicationContext; /** * Spring会自动调用这个方法,注入ApplicationContext */ @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { SpringContextUtils.applicationContext = applicationContext; } /** * 获取ApplicationContext * @return ApplicationContext */ public static ApplicationContext getApplicationContext() { if (applicationContext == null) { throw new IllegalStateException("ApplicationContext is not set. Make sure SpringContextUtils is properly initialized."); } return applicationContext; } /** * 通过名称获取Bean * @param name Bean的名称 * @return Bean实例 */ public static Object getBean(String name) { return getApplicationContext().getBean(name); } /** * 通过名称和类型获取Bean * @param name Bean的名称 * @param requiredType Bean的类型 * @param <T> Bean的类型 * @return Bean实例 */ public static <T> T getBean(String name, Class<T> requiredType) { return getApplicationContext().getBean(name, requiredType); } /** * 通过类型获取Bean * @param requiredType Bean的类型 * @param <T> Bean的类型 * @return Bean实例 */ public static <T> T getBean(Class<T> requiredType) { return getApplicationContext().getBean(requiredType); } } 

在 Bean 的依赖注入之后执行初始化操作

比如下面的案例中,MyService 这个 Bean 需要在它的依赖 MyRepository 这个 Bean 注入完成之后,调用依赖的 loadInitialData() 方法加载初始数据。代码如下:

@Service public class MyService { private MyRepository myRepository; private List<String> initialData; @Autowired public void setMyRepository(MyRepository myRepository) { this.myRepository = myRepository; } // 依赖注入完成后执行的初始化方法 @PostConstruct public void init() { this.initialData = myRepository.loadInitialData(); } public void doBusinessLogic() { } } @Service class MyRepository { public List<String> loadInitialData() { } } 

@PostConstruct 注解是 JSR-250 标准定义的注解,它与 Spring 框架的耦合度比较低。除此之外还可以实现 InitializingBean 接口,在它的 afterPropertiesSet() 方法中来完成初始化;通过 XML 配置 init-method 或者 @Bean 注解的 initMethod 属性来指定任意的方法作为初始化方法来完成初始化。

Bean 创建源码解析

在 Spring 源码实现中实际上分为了三个大的步骤:实例化 -> 填充属性 -> 初始化 。填充属性可以看前面的文章[Spring 中@Autowired,@Resource@Inject 注解实现原理](https://mp.weixin.qq.com/s/WVpWDU2JXFbpl-hgsywUXQ)。在上面生命周期图片中的从 XXXAwaresetXXXAware() 方法到 postProcessAfterInitialization() 都属于初始化的这个步骤中。

AbstractAutowireCapableBeanFactory 中提供的 doCreateBean() 方法中提现了这三个大的步骤,其中的 createBeanInstance() 方法完成 Bean 的实例化;populateBean() 方法完成 Bean的属性填充;initializeBean() 方法完成 Bean 的初始化。代码如下:

protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException { // Instantiate the bean. BeanWrapper instanceWrapper = null; if (instanceWrapper == null) { //实例化Bean instanceWrapper = createBeanInstance(beanName, mbd, args); } Object bean = instanceWrapper.getWrappedInstance(); // 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) { addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean)); } // Initialize the bean instance. Object exposedObject = bean; try { //填充Bean的属性,比如处理@Autowired,@Resource,@Inject注解 populateBean(beanName, mbd, instanceWrapper); //初始化Bean exposedObject = initializeBean(beanName, exposedObject, mbd); } catch { } } 

initializeBean()方法流程

initializeBean() 方法中又分为:调用 invokeAwareMethods() 方法 -> 调用 applyBeanPostProcessorsBeforeInitialization() 方法 -> 调用 invokeInitMethods() 方法 -> 调用 applyBeanPostProcessorsAfterInitialization() 方法,代码如下:

protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) { //调用Aware()方法 invokeAwareMethods(beanName, bean); Object wrappedBean = bean; if (mbd == null || !mbd.isSynthetic()) { //调用BeanPostProcessor的postProcessBeforeInitialization()方法 wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName); } try { //调用初始化方法 invokeInitMethods(beanName, wrappedBean, mbd); } catch (Throwable ex) { throw new BeanCreationException( (mbd != null ? mbd.getResourceDescription() : null), beanName, ex.getMessage(), ex); } if (mbd == null || !mbd.isSynthetic()) { //调用BeanPostProcessor的postProcessAfterInitialization()方法 wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); } return wrappedBean; } 

invokeAwareMethods()方法流程

需要注意的是 invokeAwareMethods() 方法中仅仅只调用实现了 BeanNameAwareBeanClassLoaderAwareBeanFactoryAware 接口的方法。而常见的 ApplicationContextAware 接口的 setApplicationContext() 方法则是在 ApplicationContextAwareProcessorpostProcessBeforeInitialization() 方法中调用的。代码如下:

public abstract class AbstractAutowireCapableBeanFactory { private void invokeAwareMethods(String beanName, Object bean) { if (bean instanceof Aware) { if (bean instanceof BeanNameAware beanNameAware) { //调用setBeanName()方法 beanNameAware.setBeanName(beanName); } if (bean instanceof BeanClassLoaderAware beanClassLoaderAware) { ClassLoader bcl = getBeanClassLoader(); if (bcl != null) { //调用setBeanClassLoader()方法 beanClassLoaderAware.setBeanClassLoader(bcl); } } if (bean instanceof BeanFactoryAware beanFactoryAware) { //调用setBeanFactory()方法 beanFactoryAware.setBeanFactory(AbstractAutowireCapableBeanFactory.this); } } } } class ApplicationContextAwareProcessor { public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { if (bean instanceof Aware) { this.invokeAwareInterfaces(bean); } return bean; } private void invokeAwareInterfaces(Object bean) { if (bean instanceof EnvironmentAware environmentAware) { environmentAware.setEnvironment(this.applicationContext.getEnvironment()); } if (bean instanceof EmbeddedValueResolverAware embeddedValueResolverAware) { embeddedValueResolverAware.setEmbeddedValueResolver(this.embeddedValueResolver); } if (bean instanceof ResourceLoaderAware resourceLoaderAware) { resourceLoaderAware.setResourceLoader(this.applicationContext); } if (bean instanceof ApplicationEventPublisherAware applicationEventPublisherAware) { applicationEventPublisherAware.setApplicationEventPublisher(this.applicationContext); } if (bean instanceof MessageSourceAware messageSourceAware) { messageSourceAware.setMessageSource(this.applicationContext); } if (bean instanceof ApplicationStartupAware applicationStartupAware) { applicationStartupAware.setApplicationStartup(this.applicationContext.getApplicationStartup()); } if (bean instanceof ApplicationContextAware applicationContextAware) { //这里调用的setApplicationContext()方法 applicationContextAware.setApplicationContext(this.applicationContext); } } } 

applyBeanPostProcessorsBeforeInitialization() 方法流程

在该方法中主要就是查找所有实现了 BeanPostProcessor 接口的对象,然后循环调用其 postProcessBeforeInitialization() 方法。代码如下:

public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName) throws BeansException { Object result = existingBean; for (BeanPostProcessor processor : getBeanPostProcessors()) { Object current = processor.postProcessBeforeInitialization(result, beanName); if (current == null) { return result; } result = current; } return result; } 

在 Spring 中提供了 CommonAnnotationBeanPostProcessor@Resource 注解也是它处理的) 实现了 BeanPostProcessor 接口,在它的构造函数里面初始化了要处理 @PostConstruct 注解。代码如下:

public CommonAnnotationBeanPostProcessor() { setOrder(Ordered.LOWEST_PRECEDENCE - 3); // Jakarta EE 9 set of annotations in jakarta.annotation package addInitAnnotationType(loadAnnotationType("jakarta.annotation.PostConstruct")); addDestroyAnnotationType(loadAnnotationType("jakarta.annotation.PreDestroy")); // Tolerate legacy JSR-250 annotations in javax.annotation package addInitAnnotationType(loadAnnotationType("javax.annotation.PostConstruct")); addDestroyAnnotationType(loadAnnotationType("javax.annotation.PreDestroy")); } 

然后在它的子类 InitDestroyAnnotationBeanPostProcessorpostProcessBeforeInitialization() 实现了查找 @PostConstruct 注解修饰的方法,然后调用的逻辑。代码如下:

public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { LifecycleMetadata metadata = findLifecycleMetadata(bean.getClass()); try { metadata.invokeInitMethods(bean, beanName); } catch (InvocationTargetException ex) { throw new BeanCreationException(beanName, "Invocation of init method failed", ex.getTargetException()); } catch (Throwable ex) { throw new BeanCreationException(beanName, "Failed to invoke init method", ex); } return bean; } 

invokeInitMethods() 方法流程

在该方法中会先判断 Bean 是否实现了 InitializingBean 接口,如果实现了则调用其 afterPropertiesSet() 方法,然后查看 Bean 定义中是否有自定义的初始化方法,如果有的话,则调用自定义的初始化方法。代码如下:

protected void invokeInitMethods(String beanName, Object bean, @Nullable RootBeanDefinition mbd) throws Throwable { boolean isInitializingBean = (bean instanceof InitializingBean); if (isInitializingBean && (mbd == null || !mbd.hasAnyExternallyManagedInitMethod("afterPropertiesSet"))) { if (logger.isTraceEnabled()) { logger.trace("Invoking afterPropertiesSet() on bean with name '" + beanName + "'"); } //调用afterPropertiesSet()方法 ((InitializingBean) bean).afterPropertiesSet(); } if (mbd != null && bean.getClass() != NullBean.class) { String[] initMethodNames = mbd.getInitMethodNames(); if (initMethodNames != null) { for (String initMethodName : initMethodNames) { if (StringUtils.hasLength(initMethodName) && !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) && !mbd.hasAnyExternallyManagedInitMethod(initMethodName)) { //调用自定义初始化方法 invokeCustomInitMethod(beanName, bean, mbd, initMethodName); } } } } } protected void invokeCustomInitMethod(String beanName, Object bean, RootBeanDefinition mbd, String initMethodName) throws Throwable { Class<?> beanClass = bean.getClass(); MethodDescriptor descriptor = MethodDescriptor.create(beanName, beanClass, initMethodName); String methodName = descriptor.methodName(); Method initMethod = (mbd.isNonPublicAccessAllowed() ? BeanUtils.findMethod(descriptor.declaringClass(), methodName) : ClassUtils.getMethodIfAvailable(beanClass, methodName)); //省略代码 Method methodToInvoke = ClassUtils.getPubliclyAccessibleMethodIfPossible(initMethod, beanClass); try { ReflectionUtils.makeAccessible(methodToInvoke); //这里通过反射的方式调用初始化方法 methodToInvoke.invoke(bean); } catch (InvocationTargetException ex) { throw ex.getTargetException(); } } 

applyBeanPostProcessorsBeforeInitialization() 方法流程

在该方法中主要就是查找所有实现了 BeanPostProcessor 接口的对象,然后循环调用其 postProcessAfterInitialization() 方法。代码如下:

public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { LifecycleMetadata metadata = findLifecycleMetadata(bean.getClass()); try { metadata.invokeInitMethods(bean, beanName); } catch (InvocationTargetException ex) { throw new BeanCreationException(beanName, "Invocation of init method failed", ex.getTargetException()); } catch (Throwable ex) { throw new BeanCreationException(beanName, "Failed to invoke init method", ex); } return bean; } 
原文链接:https://my.oschina.net/u/4009705/blog/18421923
关注公众号

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。

持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。

转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。

文章评论

共有0条评论来说两句吧...

文章二维码

扫描即可查看该文章

点击排行

推荐阅读

最新文章