Spring源码系列(二十)Spring创建Bean的过程(八)

1.写在前面

笔者在前面的博客已经介绍了spring的属性注入的流程了,接下来继续走剩下的流程。今天笔者主要带大家看的就是initializeBean()方法。也就是初始化Bean的方法。

2.initializeBean()方法

废话不多说直接上代码,直接看initializeBean()的方法,具体的代码如下,主要是属性注入完成后调用的代码

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 {
		invokeAwareMethods(beanName, bean);
	}

	Object wrappedBean = bean;
	if (mbd == null || !mbd.isSynthetic()) {
		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()) {
		wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
	}

	return wrappedBean;
}

上面的代码,笔者还是分段的讲吧,具体的先看第一部分,具体的代码如下:

//安全策略是否为空,一般是空的
if (System.getSecurityManager() != null) {
	AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
		invokeAwareMethods(beanName, bean);
		return null;
	}, getAccessControlContext());
}
else {
	invokeAwareMethods(beanName, bean);
}

上面的代码主要就是调用invokeAwareMethods(beanName, bean);方法,笔者带着大家来看下这个方法是干嘛的,具体的代码如下:

private void invokeAwareMethods(String beanName, Object bean) {
    //判断这个bean是否实现了Aware的接口
	if (bean instanceof Aware) {
       	//判断是否实现了BeanNameAware接口
		if (bean instanceof BeanNameAware) {
			((BeanNameAware) bean).setBeanName(beanName);
		}
        //判断是否实现了BeanClassLoaderAware接口
		if (bean instanceof BeanClassLoaderAware) {
			ClassLoader bcl = getBeanClassLoader();
			if (bcl != null) {
				((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
			}
		}
        //判断是否实现了BeanFactoryAware接口
		if (bean instanceof BeanFactoryAware) {
			((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
		}
	}
}

判断是否实现了BeanNameAwareBeanClassLoaderAwareBeanFactoryAware接口,如果实现了就调用这个接口的实现的方法。继续看剩下的代码,具体的代码如下:

Object wrappedBean = bean;
//判断对应的BeanDefinition为空或者BeanDefinition不是合成的,一般都是成立的
if (mbd == null || !mbd.isSynthetic()) {
	wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}

上面的代码最终会调用 applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);方法,具体的代码如下:

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

这儿会调用所有的bean的后置处理器的postProcessBeforeInitialization(result, beanName);方法,笔者先带大家看看各种后置处理器的postProcessBeforeInitialization(result, beanName);方法,首先是ApplicationContextAwareProcessorpostProcessBeforeInitialization(result, beanName);的代码,具体的如下:

public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
    //判断是不是这6个接口的中的一个
	if (!(bean instanceof EnvironmentAware || bean instanceof EmbeddedValueResolverAware ||
			bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware ||
			bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware)){
		return bean;
	}

	AccessControlContext acc = null;

	if (System.getSecurityManager() != null) {
		acc = this.applicationContext.getBeanFactory().getAccessControlContext();
	}

	if (acc != null) {
		AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
			invokeAwareInterfaces(bean);
			return null;
		}, acc);
	}
	else {
		invokeAwareInterfaces(bean);
	}

	return bean;
}

如果是EnvironmentAwareEmbeddedValueResolverAwareResourceLoaderAwareApplicationEventPublisherAwareMessageSourceAwareApplicationContextAware接口的实现类,就会调用invokeAwareInterfaces(bean);方法,具体的代码如下:

private void invokeAwareInterfaces(Object bean) {
	if (bean instanceof EnvironmentAware) {
		((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment());
	}
	if (bean instanceof EmbeddedValueResolverAware) {
		((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(this.embeddedValueResolver);
	}
	if (bean instanceof ResourceLoaderAware) {
		((ResourceLoaderAware) bean).setResourceLoader(this.applicationContext);
	}
	if (bean instanceof ApplicationEventPublisherAware) {
		((ApplicationEventPublisherAware) bean).setApplicationEventPublisher(this.applicationContext);
	}
	if (bean instanceof MessageSourceAware) {
		((MessageSourceAware) bean).setMessageSource(this.applicationContext);
	}
	if (bean instanceof ApplicationContextAware) {
		((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);
	}
}

可以发现如果是这些的接口的实现类,就会调用这些接口实现类的实现方法。至此第一个后置处理器ApplicationContextAwareProcessor就讲完了。继续看下一个后置处理器ImportAwareBeanPostProcessorpostProcessBeforeInitialization的方法,具体的代码如下:

public Object postProcessBeforeInitialization(Object bean, String beanName) {
	if (bean instanceof ImportAware) {
		ImportRegistry ir = this.beanFactory.getBean(IMPORT_REGISTRY_BEAN_NAME, ImportRegistry.class);
		AnnotationMetadata importingClass = ir.getImportingClassFor(ClassUtils.getUserClass(bean).getName());
		if (importingClass != null) {
			((ImportAware) bean).setImportMetadata(importingClass);
		}
	}
	return bean;
}

判断这个bean是不是ImportAware的实现类,如果是先获取ImportRegistry这个类的实现类,最后调用传进来的bean的是setImportMetadata方法,至此第二个后置处理器ImportAwareBeanPostProcessor就讲完了,继续看下一个后置处理器BeanPostProcessorCheckerpostProcessBeforeInitialization方法,具体的代码如下:

public Object postProcessBeforeInitialization(Object bean, String beanName) {
	return bean;
}

这儿就直接返回一个bean,没有经过任何处理,至此第三后置处理器BeanPostProcessorChecker就讲完了,继续看下一个后置处理器InitDestroyAnnotationBeanPostProcessorpostProcessBeforeInitialization方法,具体的代码如下:

public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
    //查找对应的生命周期的封装的元数据(@PostConstruct注解)
	LifecycleMetadata metadata = findLifecycleMetadata(bean.getClass());
	try {
        //调用@PostConstruct注解的方法
		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;
}

上面的方法主要是调用加了@PostConstruct注解的方法,主要调用的metadata.invokeInitMethods(bean, beanName);方法,具体的代码如下:

public void invokeInitMethods(Object target, String beanName) throws Throwable {
	Collection<LifecycleElement> checkedInitMethods = this.checkedInitMethods;
	Collection<LifecycleElement> initMethodsToIterate =
		(checkedInitMethods != null ? checkedInitMethods : this.initMethods);
	if (!initMethodsToIterate.isEmpty()) {
        //循环调用所有的加了@PostConstruct注解的方法
		for (LifecycleElement element : initMethodsToIterate) {
			if (logger.isTraceEnabled()) {
				logger.trace("Invoking init method on bean '" + beanName + "': " + element.getMethod());
			}
			element.invoke(target);
		}
	}
}

上面的代码主要是调用所有的加了@PostConstruct注解的方法,至此这个InitDestroyAnnotationBeanPostProcessor后置处理器就讲完了,继续看下一个后置处理器的InstantiationAwareBeanPostProcessorAdapterpostProcessBeforeInitialization的方法,具体的代码如下:

public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
	return bean;
}

这个后置处理器主要是返回一个bean,什么操作也没有做,至此InstantiationAwareBeanPostProcessorAdapter的后置处理器就讲完了,继续讲下一个后置处理器ApplicationListenerDetectorpostProcessBeforeInitialization方法,具体的代码如下:

public Object postProcessBeforeInitialization(Object bean, String beanName) {
	return bean;
}

至此六个后置处理器就讲完了。笔者带着大家继续看剩下的代码。具体的代码如下:

try {
	invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
	throw new BeanCreationException(
		(mbd != null ? mbd.getResourceDescription() : null),
		beanName, "Invocation of init method failed", ex);
}

上面的代码主要调用invokeInitMethods(beanName, wrappedBean, mbd);方法,具体的代码如下:

protected void invokeInitMethods(String beanName, 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 {
            //调用afterPropertiesSet方法
			((InitializingBean) bean).afterPropertiesSet();
		}
	}

	if (mbd != null && bean.getClass() != NullBean.class) {
        //这个是xml中配置的initMethod
		String initMethodName = mbd.getInitMethodName();
        //实现了InitializingBean接口,方法名afterPropertiesSet,不是外部提供的,只要这三个条件只要一个不成立,就会执行用户提供的方法
		if (StringUtils.hasLength(initMethodName) &&
				!(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
				!mbd.isExternallyManagedInitMethod(initMethodName)) {
            //反射调用
			invokeCustomInitMethod(beanName, bean, mbd);
		}
	}
}

上面的代码就是先调用实现InitializingBean接口的afterPropertiesSet方法,然后调用用户提供的InitMethod方法。继续看剩下的代码,具体的代码如下:

if (mbd == null || !mbd.isSynthetic()) {
	wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}

然后会调用applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);方法,具体的代码如下:

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

可以发现上面也是一样是调用对应的后置处理器的postProcessAfterInitialization(result, beanName);方法,首先我们看ApplicationContextAwareProcessorpostProcessAfterInitialization方法,具体的代码如下:

default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
	return bean;
}

发现这个后置处理器没有做什么操作,至此这个ApplicationContextAwareProcessor后置处理器就讲完了,继续看下一个后置处理器InstantiationAwareBeanPostProcessorAdapterpostProcessAfterInitialization方法,具体的代码如下:

public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
	return bean;
}

同时这个后置处理器也没有做什么操作,至此这个InstantiationAwareBeanPostProcessorAdapter后置处理器就讲完了,继续看下一个后置处理器BeanPostProcessorCheckerpostProcessAfterInitialization方法,具体的代码如下:

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

同样也是什么操作也没有做,至此BeanPostProcessorChecker后置处理器就讲完了,继续下一个后置处理器InitDestroyAnnotationBeanPostProcessorpostProcessAfterInitialization方法,具体的代码如下:

public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
	return bean;
}

同样也是什么操作也没有做,至此InitDestroyAnnotationBeanPostProcessor后置处理器就讲完了,继续下一个后置处理器InstantiationAwareBeanPostProcessorAdapterpostProcessAfterInitialization方法,具体的代码如下:

public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
	return bean;
}

同样也是什么操作也没有做,至此InstantiationAwareBeanPostProcessorAdapter后置处理器就讲完了,继续下一个后置处理器ApplicationListenerDetectorpostProcessAfterInitialization方法,具体的代码如下:

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

上面的代码是判断这个bean是不是实现了ApplicationListener接口,如果实现了,就从容器中获取这个bean,如果存在的话,就给这个bean添加监听器,如果没有,就移除这个beanName。至此整个initializeBean方法就讲完了。

3.registerDisposableBeanIfNecessary()方法

至此整个初始化和各种赋值的操作就已经讲完了,这个时候还剩最后一个方法registerDisposableBeanIfNecessary()具体的代码如下:

protected void registerDisposableBeanIfNecessary(String beanName, Object bean, RootBeanDefinition mbd) {
	AccessControlContext acc = (System.getSecurityManager() != null ? getAccessControlContext() : null);
    //不是多例,判断是否需要注册销毁的方法,主要看看有没有实现销毁的方法
	if (!mbd.isPrototype() && requiresDestruction(bean, mbd)) {
        //判断是否是单例的
		if (mbd.isSingleton()) {
			// Register a DisposableBean implementation that performs all destruction
			// work for the given bean: DestructionAwareBeanPostProcessors,
			// DisposableBean interface, custom destroy method.
			registerDisposableBean(beanName,
					new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
		}
		else {
			// A bean with a custom scope...
			Scope scope = this.scopes.get(mbd.getScope());
			if (scope == null) {
				throw new IllegalStateException("No Scope registered for scope name '" + mbd.getScope() + "'");
			}
			scope.registerDestructionCallback(beanName,
					new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
		}
	}
}

上面的代码走来看是不是多例的,然后如果有实现销毁的方法,这个时候需要看下这个类是单例的,就会调用registerDisposableBean(beanName,
new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));这个时候看看new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc)具体的代码如下:

public DisposableBeanAdapter(Object bean, String beanName, RootBeanDefinition beanDefinition,
			List<BeanPostProcessor> postProcessors, @Nullable AccessControlContext acc) {

	Assert.notNull(bean, "Disposable bean must not be null");
	this.bean = bean;
	this.beanName = beanName;
	this.invokeDisposableBean =
			(this.bean instanceof DisposableBean && !beanDefinition.isExternallyManagedDestroyMethod("destroy"));
	this.nonPublicAccessAllowed = beanDefinition.isNonPublicAccessAllowed();
	this.acc = acc;
	String destroyMethodName = inferDestroyMethodIfNecessary(bean, beanDefinition);
	if (destroyMethodName != null && !(this.invokeDisposableBean && "destroy".equals(destroyMethodName)) &&
			!beanDefinition.isExternallyManagedDestroyMethod(destroyMethodName)) {
		this.destroyMethodName = destroyMethodName;
		Method destroyMethod = determineDestroyMethod(destroyMethodName);
		if (destroyMethod == null) {
			if (beanDefinition.isEnforceDestroyMethod()) {
				throw new BeanDefinitionValidationException("Could not find a destroy method named '" +
						destroyMethodName + "' on bean with name '" + beanName + "'");
			}
		}
		else {
			Class<?>[] paramTypes = destroyMethod.getParameterTypes();
			if (paramTypes.length > 1) {
				throw new BeanDefinitionValidationException("Method '" + destroyMethodName + "' of bean '" +
						beanName + "' has more than one parameter - not supported as destroy method");
			}
			else if (paramTypes.length == 1 && boolean.class != paramTypes[0]) {
				throw new BeanDefinitionValidationException("Method '" + destroyMethodName + "' of bean '" +
						beanName + "' has a non-boolean parameter - not supported as destroy method");
			}
			destroyMethod = ClassUtils.getInterfaceMethodIfPossible(destroyMethod);
		}
		this.destroyMethod = destroyMethod;
	}
    //上面就是进行一些属性赋值
	this.beanPostProcessors = filterPostProcessors(postProcessors, bean);
}

上面的就是进行一些赋值,最重要的就是filterPostProcessors(postProcessors, bean);方法,主要是对后置处理器进行一些过滤具体的代码如下:

private List<DestructionAwareBeanPostProcessor> filterPostProcessors(List<BeanPostProcessor> processors, Object bean) {
	List<DestructionAwareBeanPostProcessor> filteredPostProcessors = null;
	if (!CollectionUtils.isEmpty(processors)) {
		filteredPostProcessors = new ArrayList<>(processors.size());
		for (BeanPostProcessor processor : processors) {
			if (processor instanceof DestructionAwareBeanPostProcessor) {
				DestructionAwareBeanPostProcessor dabpp = (DestructionAwareBeanPostProcessor) processor;
				if (dabpp.requiresDestruction(bean)) {
					filteredPostProcessors.add(dabpp);
				}
			}
		}
	}
	return filteredPostProcessors;
}

过滤的规则主要是这个后置处理器是DestructionAwareBeanPostProcessor类型的,同时requiresDestruction方法的返回值是true。最后就是执行registerDisposableBean方法,具体的代码如下:

public void registerDisposableBean(String beanName, DisposableBean bean) {
	synchronized (this.disposableBeans) {
		this.disposableBeans.put(beanName, bean);
	}
}

主要是将刚才的那个创建好的对象添加到disposableBeans集合中去。至此spring创建Bean的流程就讲完了。

4.写在最后

笔者已经讲整个spring创建bean的流程已经讲完了,还有一些其他的例如AOP,事务,类型转换器,Resource等等,spring的体系太过于庞大,后面笔者如果有时间会继续更新。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值