阅读之前要注意的东西:本文就是主打流水账式的源码阅读,主导的是一个参考,主要内容需要看官自己去源码中验证。全系列文章基于 spring 源码 5.x 版本。
写在开始前的话:
阅读spring 源码实在是一件庞大的工作,不说全部内容,单就最基本核心部分包含的东西就需要很长时间去消化了:
实际上我在博客里贴出来的还只是一部分内容,更多的内容,我放在了个人,fork自 spring 官方源码仓了; 而且对源码的学习,必须是要跟着实际代码层层递进的,不然只是干巴巴的文字味同嚼蜡。
这个仓设置的公共仓,可以直接拉取。
/** * Initialize the given bean instance, applying factory callbacks * as well as init methods and bean post processors. * <p>Called from {@link #createBean} for traditionally defined beans, * and from {@link #initializeBean} for existing bean instances. * * @param beanName the bean name in the factory (for debugging purposes) * @param bean the new bean instance we may need to initialize * @param mbd the bean definition that the bean was created with * (can also be {@code null}, if given an existing bean instance) * @return the initialized bean instance (potentially wrapped) * @see BeanNameAware * @see BeanClassLoaderAware * @see BeanFactoryAware * @see #applyBeanPostProcessorsBeforeInitialization * @see #invokeInitMethods * @see #applyBeanPostProcessorsAfterInitialization */ protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) { if (System.getSecurityManager() != null) { AccessController.doPrivileged((PrivilegedAction<Object>) () -> { invokeAwareMethods(beanName, bean); return null; }, getAccessControlContext()); } else { // 特殊 bean 处理 Aware BeanClassLoaderAware BeanFactoryAware invokeAwareMethods(beanName, bean); } Object wrappedBean = bean; if (mbd == null || !mbd.isSynthetic()) { // init-method 执行前 后处理器 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()) { // init-method 执行后 后处理器 wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); } return wrappedBean; }
复制
这里的操作其实相当简单
"后置处理器" 是老朋友了
实际上它是个接口,我们可以把它叫做自动装配。
若我们想要实现某个自动装配操作,那么就可以实现 Aware 接口并定义自定义的装配行为。
详情可以参考下边的博客:
执行-bean初始化前-后置处理器: 简单的说,就是要在初始化方法(init-method) 执行前,才能进行的一些操作。
[遗憾的是,目前spring.beans 包下,除了测试包之外,spring框架中,并没有这方面的实际应用。
也就是说你可以忽略它,这个后置处理器,目前还不会对 bean 做出任何的改动。]
@Override public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName) throws BeansException { Object result = existingBean; for (BeanPostProcessor processor : getBeanPostProcessors()) {// 初始化 init-method 前 Object current = processor.postProcessBeforeInitialization(result, beanName); if (current == null) { return result; } result = current; } return result; }
复制
如果元数据中定义了init-method:结合包装器 bw,以及 BeanDefinition 中记录的元数据;
应用反射的原理,执行该 init-method.
/** * Give a bean a chance to react now all its properties are set, * and a chance to know about its owning bean factory (this object). * This means checking whether the bean implements InitializingBean or defines * a custom init method, and invoking the necessary callback(s) if it does. * * @param beanName the bean name in the factory (for debugging purposes) * @param bean the new bean instance we may need to initialize * @param mbd the merged bean definition that the bean was created with * (can also be {@code null}, if given an existing bean instance) * @throws Throwable if thrown by init methods or by the invocation process * @see #invokeCustomInitMethod */ protected void invokeInitMethods(String beanName, Object bean, @Nullable RootBeanDefinition mbd) throws Throwable { // 首先判断是否实现了 InitializingBean 接口,如果实现了,直接调用接口方法: afterPropertiesSet 即可完成初始化操作 boolean isInitializingBean = (bean instanceof InitializingBean); if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) { if (logger.isDebugEnabled()) { logger.debug("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 { // 直接回调完成操作,适用于较高版本的 spring ((InitializingBean) bean).afterPropertiesSet(); } } // 低版本中,通过在xml中配置 init-method 方式实现初始化方法 // 此种情形下,需要通过 反射调用bean上定义的 init-method 方法.(发射存在性能损耗,不如上述的直接回调。) if (mbd != null && bean.getClass() != NullBean.class) { String initMethodName = mbd.getInitMethodName(); if (StringUtils.hasLength(initMethodName) && !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) && !mbd.isExternallyManagedInitMethod(initMethodName)) { // 利用反射执行 init-method invokeCustomInitMethod(beanName, bean, mbd); } } }
复制
执行-bean初始化后-后置处理器: 简单的说,就是要在初始化方法(init-method) 执行后,才能进行的一些操作。
[遗憾的是,目前spring.beans 包下,除了测试包之外,spring框架中,并没有这方面的实际应用。
也就是说你可以忽略它,这个后置处理器,目前还不会对 bean 做出任何的改动。]
@Override public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) throws BeansException { Object result = existingBean; for (BeanPostProcessor processor : getBeanPostProcessors()) { // afterInitialization: 初始化之后 - 后置处理 Object current = processor.postProcessAfterInitialization(result, beanName); // 初始化 init-method 之后 if (current == null) { return result; } result = current; } return result; }
复制
本文为系列文章-Grafana 统一展示,通过 Grafana Explore 功能探索 Jaeger 数据源中的 trace 信息。