Spring源码分析(二)bean实例化到初始化过程源码主流程分析
getBean的大致总流程如下:
下面只记录bean实例化到初始化的过程以及期间spring提供可以扩展的点。从下面getBean开始
public static void main(String []args){
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(BeanConfig.class);
System.out.println("======================");
System.out.println(applicationContext.getBean("people"));
System.out.println("======================");
}
@ImportResource("spring-ioctest.xml")
@Configuration
@ComponentScan(value = "com.my.ioc.pojo.beanpostprocessor")
//@Import({ Myregister.class,MyImport.class})
public class BeanConfig {
@Bean
@Scope("prototype")
// @Conditional(MyConditional.class)
public People people(){
return new People();
}
@Bean
public Bird bird(){
Bird bird = new Bird();
bird.setName("bad bird");
return bird;
}
}
People里自动注入了Brid为了验证后面的问题:
一直往后跟,会走到AbstractBeanFactory.doGetBean, 直接从 // Create bean instance开始看,前面都是从单例对象池中获取(如果获取到了就返回),从父工厂获取,从factorybean中获取,检查是否存在循环依赖,这种循环依赖是通过DependsOn相互依赖的,无法解决则抛出异常,判断是否为抽象的。抽象的类不会创建。
从创建单例的这个分支进去查看:
首先调用getSingleton方法,第二个参数为lambda表达式,里面会被调用。
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) { Assert.notNull(beanName, "Bean name must not be null"); synchronized (this.singletonObjects) {// 加锁防止并发创建 Object singletonObject = this.singletonObjects.get(beanName);//再次从单例对象池中获取,看是否走到加锁之前别的线程已经创建了 if (singletonObject == null) {// 还是为空,进行创建 if (this.singletonsCurrentlyInDestruction) { throw new BeanCreationNotAllowedException(beanName, "Singleton bean creation not allowed while singletons of this factory are in destruction " + "(Do not request a bean from a BeanFactory in a destroy method implementation!)"); } if (logger.isDebugEnabled()) { logger.debug("Creating shared instance of singleton bean '" + beanName + "'"); } beforeSingletonCreation(beanName);//单例创建之前进行的操作,检查这个bean是否正在被创建,如果不是就把它加到正在被创建的inCreationCheckExclusions中 boolean newSingleton = false; boolean recordSuppressedExceptions = (this.suppressedExceptions == null); if (recordSuppressedExceptions) { this.suppressedExceptions = new LinkedHashSet<>(); } try { singletonObject = singletonFactory.getObject(); //执行第二个参数的lambda表达式 newSingleton = true;// 创建完成,设置为新的单例 } catch (IllegalStateException ex) { // Has the singleton object implicitly appeared in the meantime -> // if yes, proceed with it since the exception indicates that state. singletonObject = this.singletonObjects.get(beanName); if (singletonObject == null) { throw ex; } } catch (BeanCreationException ex) { if (recordSuppressedExceptions) { for (Exception suppressedException : this.suppressedExceptions) { ex.addRelatedCause(suppressedException); } } throw ex; } finally { if (recordSuppressedExceptions) { this.suppressedExceptions = null; } afterSingletonCreation(beanName); } if (newSingleton) { //如果单例创建成功就放到单例对象池中 addSingleton(beanName, singletonObject); } } return singletonObject; } }
lambda表达式中会调用createBean方法:AbstractAutowireCapableBeanFactory.createBean(beanName, mbd, args);
@Override 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; // Make sure bean class is actually resolved at this point, and // clone the bean definition in case of a dynamically resolved Class // which cannot be stored in the shared merged bean definition. Class<?> resolvedClass = resolveBeanClass(mbd, beanName);//创建bean首先加载到对应的class,因为mbd.getBeanClassName大部分时候都是类的全限定名 if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) { mbdToUse = new RootBeanDefinition(mbd); mbdToUse.setBeanClass(resolvedClass); } // Prepare method overrides. try { mbdToUse.prepareMethodOverrides(); } catch (BeanDefinitionValidationException ex) { throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(), beanName, "Validation of method overrides failed", ex); } try { // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance. // 给自己实现的BeanPostProcessors一次机会,可以返回一个对象,如果能返回,就不走spring自己 doCreateBean来创建了,这个地方我们进行扩展。 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 { Object beanInstance = doCreateBean(beanName, mbdToUse, args); //spring内部创建bean的实例 if (logger.isTraceEnabled()) { logger.trace("Finished creating instance of bean '" + beanName + "'"); } return beanInstance; } catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) { // A previously detected exception with proper bean creation context already, // or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry. throw ex; } catch (Throwable ex) { throw new BeanCreationException( mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex); } }
resolveBeforeInstantiation(beanName, mbdToUse);我们进去看:
@Nullable 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()) { //判断是用户自己创建的bean而不是spring内部的bean,而且要看有没有实现InstantiationAwareBeanPostProcessor接口 Class<?> targetType = determineTargetType(beanName, mbd); //获取要创建的bean的class,有可能beanName对应的是个factoryBean,需要获取factoryBean中的类型 if (targetType != null) { // 调用InstantiationAwareBeanPostProcessor实现类中的postProcessBeforeInstantiation方法这是实例化之前的方法 bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName); if (bean != null) { //前置方法调用完,调用所有BeanPostProcessors的 postProcessAfterInitialization,bean初始之后的方法,因为上一步bean返回不为空,说明我们自定义的类已经实例化并初始化好了 bean = applyBeanPostProcessorsAfterInitialization(bean, beanName); } } } mbd.beforeInstantiationResolved = (bean != null); } return bean; }
applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
@Nullable protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) { for (BeanPostProcessor bp : getBeanPostProcessors()) { if (bp instanceof InstantiationAwareBeanPostProcessor) { //会判断只走 InstantiationAwareBeanPostProcessor的实现类 InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp; Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName); if (result != null) { return result; } } } return null; }
applyBeanPostProcessorsAfterInitialization(bean, beanName);
@Override public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) throws BeansException { Object result = existingBean; for (BeanPostProcessor processor : getBeanPostProcessors()) { //没有加判断,都会走到 Object current = processor.postProcessAfterInitialization(result, beanName); if (current == null) { return result; } result = current; } return result; }
我们实现 InstantiationAwareBeanPostProcessor ,来看下效果。
接口说明:
public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor { /** * Apply this BeanPostProcessor <i>before the target bean gets instantiated</i>. * The returned bean object may be a proxy to use instead of the target bean, * effectively suppressing default instantiation of the target bean. * <p>If a non-null object is returned by this method, the bean creation process * will be short-circuited. The only further processing applied is the * {@link #postProcessAfterInitialization} callback from the configured * {@link BeanPostProcessor BeanPostProcessors}. * <p>This callback will be applied to bean definitions with their bean class, * as well as to factory-method definitions in which case the returned bean type * will be passed in here. * <p>Post-processors may implement the extended * {@link SmartInstantiationAwareBeanPostProcessor} interface in order * to predict the type of the bean object that they are going to return here. * <p>The default implementation returns {@code null}. * @param beanClass the class of the bean to be instantiated * @param beanName the name of the bean * @return the bean object to expose instead of a default instance of the target bean, * or {@code null} to proceed with default instantiation * @throws org.springframework.beans.BeansException in case of errors * @see #postProcessAfterInstantiation * @see org.springframework.beans.factory.support.AbstractBeanDefinition#getBeanClass() * @see org.springframework.beans.factory.support.AbstractBeanDefinition#getFactoryMethodName() */ @Nullable default Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException { return null; } /** * Perform operations after the bean has been instantiated, via a constructor or factory method, * but before Spring property population (from explicit properties or autowiring) occurs. * <p>This is the ideal callback for performing custom field injection on the given bean * instance, right before Spring's autowiring kicks in. * <p>The default implementation returns {@code true}. * @param bean the bean instance created, with properties not having been set yet * @param beanName the name of the bean * @return {@code true} if properties should be set on the bean; {@code false} * if property population should be skipped. Normal implementations should return {@code true}. * Returning {@code false} will also prevent any subsequent InstantiationAwareBeanPostProcessor * instances being invoked on this bean instance. * @throws org.springframework.beans.BeansException in case of errors * @see #postProcessBeforeInstantiation */ // 这个时候得到的Object bean已经是实例化的了,可以根据beanName进行强转,然后进行想要的操作,这个方法在填充属性之前调用的,自己实现方法要默认返回true不然,不会走spring自己的
// 属性注入的逻辑了
default boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException { return true; } /**调用到这里,属性值还没有赋值到bean对象里面,只是获取到了属性值到pvs中了。所以这里可以对bean的属性值进行操作。 * spring中解析@Autowired @Value就是在这里。pvs中存的是spring将要赋值给bean的属性值。这个方法的返回值默认为空,表示要自己实现赋值 * 逻辑,这时候就要实现postProcessPropertyValues方法,spring在填充属性逻辑里如果postProcessProperties返回为null,就会调用 * postProcessPropertyValues方法,但是spring不建议使用这个方法了,已经设置为过期了. * 所以spring建议如果要实现这个类,这个方法如果不做特殊处理就这直接返回pvs。 * Post-process the given property values before the factory applies them * to the given bean, without any need for property descriptors. * <p>Implementations should return {@code null} (the default) if they provide a custom * {@link #postProcessPropertyValues} implementation, and {@code pvs} otherwise. * In a future version of this interface (with {@link #postProcessPropertyValues} removed), * the default implementation will return the given {@code pvs} as-is directly. * @param pvs the property values that the factory is about to apply (never {@code null}) * @param bean the bean instance created, but whose properties have not yet been set * @param beanName the name of the bean * @return the actual property values to apply to the given bean (can be the passed-in * PropertyValues instance), or {@code null} which proceeds with the existing properties * but specifically continues with a call to {@link #postProcessPropertyValues} * (requiring initialized {@code PropertyDescriptor}s for the current bean class) * @throws org.springframework.beans.BeansException in case of errors * @since 5.1 * @see #postProcessPropertyValues */ @Nullable default PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException { return null; } /** * Post-process the given property values before the factory applies them * to the given bean. Allows for checking whether all dependencies have been * satisfied, for example based on a "Required" annotation on bean property setters. * <p>Also allows for replacing the property values to apply, typically through * creating a new MutablePropertyValues instance based on the original PropertyValues, * adding or removing specific values. * <p>The default implementation returns the given {@code pvs} as-is. * @param pvs the property values that the factory is about to apply (never {@code null}) * @param pds the relevant property descriptors for the target bean (with ignored * dependency types - which the factory handles specifically - already filtered out) * @param bean the bean instance created, but whose properties have not yet been set * @param beanName the name of the bean * @return the actual property values to apply to the given bean (can be the passed-in * PropertyValues instance), or {@code null} to skip property population * @throws org.springframework.beans.BeansException in case of errors * @see #postProcessProperties * @see org.springframework.beans.MutablePropertyValues * @deprecated as of 5.1, in favor of {@link #postProcessProperties(PropertyValues, Object, String)} */ @Deprecated @Nullable default PropertyValues postProcessPropertyValues( PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException { return pvs; } }
//@Component public class InstantiationAwareTest implements InstantiationAwareBeanPostProcessor { //实例化之前调用的方法,如果返回了非空对象,就不再走spring自己创建逻辑。 @Override public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException { if(beanName.equals("people")){ return "InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation invokeed"; } return null; } //实例化之后执行,但是执行的地方是在populateBean的地方 @Override public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException { return false; } @Override public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException { return null; } }
首先不把它交给Spring管理,运行main方法:可以正常得到People对象。
如果把 InstantiationAwareTest上面的注解去掉再执行:直接返回 postProcessBeforeInstantiation的结果。
这是实例化之前可以进行操作的地方。
如果没有实现InstantiationAwareBeanPostProcessor接口,走spring自己实例化的逻辑
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException { // Instantiate the bean. BeanWrapper instanceWrapper = null; if (mbd.isSingleton()) { instanceWrapper = this.factoryBeanInstanceCache.remove(beanName); } if (instanceWrapper == null) { /**第二次调用后置处理器 * 创建bean实例,并将实例放在包装类BeanWrapper中返回 * 暂时先不看,设计到构造器选择,过程够讲的了 */ instanceWrapper = createBeanInstance(beanName, mbd, args); } Object bean = instanceWrapper.getWrappedInstance(); Class<?> beanType = instanceWrapper.getWrappedClass(); if (beanType != NullBean.class) { mbd.resolvedTargetType = beanType; } // Allow post-processors to modify the merged bean definition. // 允许后置处理器修改合并后的BeanDefinition synchronized (mbd.postProcessingLock) { //BeanDefinition中专门用于后置处理器处理时候用的锁 if (!mbd.postProcessed) {//MergedBeanDefinitionPostProcessor 被设置了 try { // 在实例化之后,初始化之前,设置属性之前,可以通过后置处理器直接对bean的的BeanDefinition进行修改 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 { // 在这里调用 InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation了 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 " + "'getBeanNamesForType' 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; }
上面的applyMergedBeanDefinitionPostProcessors方法:
protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class<?> beanType, String beanName) { for (BeanPostProcessor bp : getBeanPostProcessors()) { if (bp instanceof MergedBeanDefinitionPostProcessor) { //只要实现MergedBeanDefinitionPostProcessor,重写postProcessMergedBeanDefinition方法即可。 MergedBeanDefinitionPostProcessor bdp = (MergedBeanDefinitionPostProcessor) bp; bdp.postProcessMergedBeanDefinition(mbd, beanType, beanName); } } }
这里又有一个后置处理器MergedBeanDefinitionPostProcessor可以使用:第一个方法可以获取beanDefinition,对其进行修改,但是这里要注意,它调用的时候bean已经实例化了,所以对beanclass的修改已经没有用了。可以修改属性,初始化方法等。第二个方法是默认的,一般很少用,但是Spring里也用到了做一些重置清理的动作。
实现下看下效果:
//@Component public class MergedBeanDefinitionPostProcessorTest implements MergedBeanDefinitionPostProcessor { @Override public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) { //可以改变BeanDefinition if (beanName.equals("people")){ //可以进行属性赋值 beanDefinition.getPropertyValues().add("userName","postProcessMergedBeanDefinition"); //还可以设置初始化方法 beanDefinition.setInitMethodName("initPeople"); } } }
先不把它交给Spring管理,People类中有个普通的initPeople方法,和两个属性:
如果直接getPeople结果是:
放开 @Component注解运行结果:初始化方法和属性都设置成功
手动设置的初始化方法是在下面的方法中进行的。
实例化完了之后,就是填充属性,初始化,填充属性populateBean方法里面执行了,但是里面又调用了上面的提到的InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation 方法。
这个方法是为了让用户在Spring 的属性填充之前可以通过构造器或工厂方法进行一些操作,这是典型的一种回调方式可以自定义字段注入到当前bean中。默认返回的结果是true,表示这个接口的下一个实现类的此方法可以继续执行,如果返回为false,此接口的实现类调用链结束。
下面就是填充属性了。从BeanDefinition中得到属性之后,又调用了一次InstantiationAwareBeanPostProcessor但是调用的是postProcessProperties。这个方法上面也有说明。具体的解析@Autowired的属性等,这里不再深入,后面单独记录。
// 是否在BeanDefinition中设置了属性值, PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null); int resolvedAutowireMode = mbd.getResolvedAutowireMode(); //下面的逻辑一般很少走到 if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) { // by_name 是根据属性名字找bean // by_type 是根据属性所对应的set方法的参数类型找bean // 找到bean之后都要调用set方法进行注入 MutablePropertyValues newPvs = new MutablePropertyValues(pvs); // Add property values based on autowire by name if applicable. if (resolvedAutowireMode == AUTOWIRE_BY_NAME) { autowireByName(beanName, mbd, bw, newPvs); } // Add property values based on autowire by type if applicable. if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) { autowireByType(beanName, mbd, bw, newPvs); } pvs = newPvs; }// 注意执行到这里,只是把属性以及找到的值存在了 pvs中,并没有完成反射赋值 // 执行完了Spring的自动注入之后,就开始解析@Autowired,这里叫做实例化回调 boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors(); boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE); PropertyDescriptor[] filteredPds = null; if (hasInstAwareBpps) { if (pvs == null) { pvs = mbd.getPropertyValues(); } for (BeanPostProcessor bp : getBeanPostProcessors()) { if (bp instanceof InstantiationAwareBeanPostProcessor) { InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp; // 调用BeanPostProcessor 分别解析@Autowired @Value,得到属性值 这里才是调用最多属性填充的地方 PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName); if (pvsToUse == null) { if (filteredPds == null) { filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching); } pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName); if (pvsToUse == null) { return; } } pvs = pvsToUse; } } }
populateBean(beanName, mbd, instanceWrapper);填充属性执行完,开始执行初始化方法。initializeBean(beanName, exposedObject, mbd);
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,可以让当前bean获取spring内部的一些数据 invokeAwareMethods(beanName, bean); } Object wrappedBean = bean; if (mbd == null || !mbd.isSynthetic()) { // 调用BeanPostProcessor.postProcessBeforeInitialization wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName); } try { // InitializingBean afterPropertiesSet 可以让bean结合其它aware接口,在属性填充之后再次进行一些操作 // //BeanDefinition.setInitMethodName 设置的方法,在这个地方就会进行调用 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()) { // 调用BeanPostProcessor.postProcessAfterInitialization wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); } return wrappedBean; }
初始化结束。