31、Spring5.x源码之旅三十一getBean详解十六initializeBean二

  • invokeInitMethods
    • invokeCustomInitMethod自定义的初始方法
    • getInterfaceMethodIfPossible尝试获取接口方法
  • applyBeanPostProcessorsAfterInitialization初始化之后处理
    • PostProcessorRegistrationDelegate内部类BeanPostProcessorChecker的postProcessAfterInitialization
  • ApplicationListenerDetector的postProcessAfterInitialization

invokeInitMethods

前面讲一初始化前做的处理,今天继续。
这个方法就是我们如果实现了InitializingBean接口的话,就可能要调用afterPropertiesSet方法,其实就是个回调,告诉你属性设置好了。当然后面也有自定义的初始化方法invokeCustomInitMethod

protected void invokeInitMethods(String beanName, final Object bean, @Nullable RootBeanDefinition mbd)
			throws Throwable {
   
     
		//实现InitializingBean接口的
		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();
			}
		}
		//初始化方法,比如xml配置的
		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);
			}
		}
	}

invokeCustomInitMethod自定义的初始方法

获取bean的自定义初始化方法,如果自身或者父类是接口类型的话,就反射出接口方法来,最后调用。

protected void invokeCustomInitMethod(String beanName, final Object bean, RootBeanDefinition mbd)
			throws Throwable {
   
     

		String initMethodName = mbd.getInitMethodName();
		Assert.state(initMethodName != null, "No init method set");
		Method initMethod = (mbd.isNonPublicAccessAllowed() ?
				BeanUtils.findMethod(bean.getClass(), initMethodName) :
				ClassUtils.getMethodIfAvailable(bean.getClass(), initMethodName));

		if (initMethod == null) {
   
     
			if (mbd.isEnforceInitMethod()) {
   
     
				throw new BeanDefinitionValidationException("Could not find an init method named '" +
						initMethodName + "' on bean with name '" + beanName + "'");
			}
			else {
   
     
				if (logger.isTraceEnabled()) {
   
     
					logger.trace("No default init method named '" + initMethodName +
							"' found on bean with name '" + beanName + "'");
				}
				// Ignore non-existent default lifecycle methods.
				return;
			}
		}

		if (logger.isTraceEnabled()) {
   
     
			logger.trace("Invoking init method  '" + initMethodName + "' on bean with name '" + beanName + "'");
		}
		Method methodToInvoke = ClassUtils.getInterfaceMethodIfPossible(initMethod);

		if (System.getSecurityManager() != null) {
   
     
			AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
				ReflectionUtils.makeAccessible(methodToInvoke);
				return null;
			});
			try {
				AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () ->
						methodToInvoke.invoke(bean), getAccessControlContext());
			}
			catch (PrivilegedActionException pae) {
   
     
				InvocationTargetException ex = (InvocationTargetException) pae.getException();
				throw ex.getTargetException();
			}
		}
		else {
   
     
			try {
   
     
				ReflectionUtils.makeAccessible(methodToInvoke);
				methodToInvoke.invoke(bean);
			}
			catch (InvocationTargetException ex) {
   
     
				throw ex.getTargetException();
			}
		}
	}

getInterfaceMethodIfPossible尝试获取接口方法

尝试从自身或者父类获取接口方法。

public static Method getInterfaceMethodIfPossible(Method method) {
   
     
		if (Modifier.isPublic(method.getModifiers()) && !method.getDeclaringClass().isInterface()) {
   
     
			Class<?> current = method.getDeclaringClass();
			while (current != null && current != Object.class) {
   
     
				Class<?>[] ifcs = current.getInterfaces();
				for (Class<?> ifc : ifcs) {
   
     
					try {
   
     
						return ifc.getMethod(method.getName(), method.getParameterTypes());
					}
					catch (NoSuchMethodException ex) {
   
     
						// ignore
					}
				}
				current = current.getSuperclass();
			}
		}
		return method;
	}

applyBeanPostProcessorsAfterInitialization初始化之后处理

跟初始化之前处理差不多。

	@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;
	}

PostProcessorRegistrationDelegate内部类BeanPostProcessorChecker的postProcessAfterInitialization

没干瘪的,就是打印信息。

		@Override
		public Object postProcessAfterInitialization(Object bean, String beanName) {
   
     
			if (!(bean instanceof BeanPostProcessor) && !isInfrastructureBean(beanName) &&
					this.beanFactory.getBeanPostProcessorCount() < this.beanPostProcessorTargetCount) {
   
     
				if (logger.isInfoEnabled()) {
   
     
					logger.info("Bean '" + beanName + "' of type [" + bean.getClass().getName() +
							"] is not eligible for getting processed by all BeanPostProcessors " +
							"(for example: not eligible for auto-proxying)");
				}
			}
			return bean;
		}

ApplicationListenerDetector的postProcessAfterInitialization

将我们自定义的单例类作为监听器添加到applicationEventMulticaster里。

@Override
	public Object postProcessAfterInitialization(Object bean, String beanName) {
   
     
		if (bean instanceof ApplicationListener) {
   
     
			// potentially not detected as a listener by getBeanNamesForType retrieval
			Boolean flag = this.singletonNames.get(beanName);
			if (Boolean.TRUE.equals(flag)) {
   
     
				// singleton bean (top-level or inner): register on the fly
				this.applicationContext.addApplicationListener((ApplicationListener<?>) bean);
			}
			else if (Boolean.FALSE.equals(flag)) {
   
     
				if (logger.isWarnEnabled() && !this.applicationContext.containsBean(beanName)) {
   
     
					// inner bean with other scope - can't reliably process events
					logger.warn("Inner bean '" + beanName + "' implements ApplicationListener interface " +
							"but is not reachable for event multicasting by its containing ApplicationContext " +
							"because it does not have singleton scope. Only top-level listener beans are allowed " +
							"to be of non-singleton scope.");
				}
				this.singletonNames.remove(beanName);
			}
		}
		return bean;
	}

至此初始化基本完成了。

好了,今天就到这里了,希望对学习理解有帮助,大神看见勿喷,仅为自己的学习理解,能力有限,请多包涵。