2023-09-16  阅读(2)
原文作者:王伟王胖胖 原文地址: https://blog.csdn.net/wangwei19871103/article/details/105149605

initializeBean

前面讲了populateBean,给属性和方法注入bean,完成后,就要进行初始化调用了,其实就是各种处理器接口的处理。

    	protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
    		if (System.getSecurityManager() != null) {
    			AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
    				invokeAwareMethods(beanName, bean);
    				return null;
    			}, getAccessControlContext());
    		}
    		else {//Aware接口处理器
    			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;
    	}

invokeAwareMethods触发提示方法

处理BeanNameAwareBeanClassLoaderAwareBeanFactoryAware接口方法,这里BeanFactoryAware的接口要注意,如果前面配置类有CGLIB动态代理的话,这里这个方法就重复了,也就是setBeanFactory被重复调用了两次,前面一次是在EnhancedConfiguration接口的方法。

    private void invokeAwareMethods(final String beanName, final Object bean) {
    		if (bean instanceof Aware) {
    			if (bean instanceof BeanNameAware) {//设置bean名字
    				((BeanNameAware) bean).setBeanName(beanName);
    			}
    			if (bean instanceof BeanClassLoaderAware) {
    				ClassLoader bcl = getBeanClassLoader();
    				if (bcl != null) {//设置类加载器
    					((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
    				}
    			}
    			if (bean instanceof BeanFactoryAware) {//设置BeanFactory
    				((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
    			}
    		}
    	}

applyBeanPostProcessorsBeforeInitialization初始化之前处理

所有BeanPostProcessor 处理,如果有返回null了就直接返回,否则就把处理后的对象替换原来的,返回最新对象。

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

ApplicationContextAwareProcessor的postProcessBeforeInitialization

如果发现bean有实现那一堆接口任意一个的话,就会执行invokeAwareInterfaces方法。

    @Override
    	@Nullable
    	public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
    		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;
    	}

invokeAwareInterfaces

其实就是设置一些值,方便外部获取,做一些扩展。

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

ConfigurationClassPostProcessor内部类ImportAwareBeanPostProcessor的postProcessBeforeInitialization

如果是ImportAware类型的,就会设置bean的注解信息。

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

InitDestroyAnnotationBeanPostProcessor的postProcessBeforeInitialization

这里就是我们前面注册的生命周期元数据,这个时候要进行调用了。

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

LifecycleMetadata 的invokeInitMethods

调用前面注册的初始化方法集合checkedInitMethods的每一个方法。

    	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()) {
    				for (LifecycleElement element : initMethodsToIterate) {
    					if (logger.isTraceEnabled()) {
    						logger.trace("Invoking init method on bean '" + beanName + "': " + element.getMethod());
    					}
    					element.invoke(target);
    				}
    			}
    		}
LifecycleElement的invoke

就是方法的反射调用,参数是null

    		public void invoke(Object target) throws Throwable {
    			ReflectionUtils.makeAccessible(this.method);
    			this.method.invoke(target, (Object[]) null);
    		}

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


Java 面试宝典是大明哥全力打造的 Java 精品面试题,它是一份靠谱、强大、详细、经典的 Java 后端面试宝典。它不仅仅只是一道道面试题,而是一套完整的 Java 知识体系,一套你 Java 知识点的扫盲贴。

它的内容包括:

  • 大厂真题:Java 面试宝典里面的题目都是最近几年的高频的大厂面试真题。
  • 原创内容:Java 面试宝典内容全部都是大明哥原创,内容全面且通俗易懂,回答部分可以直接作为面试回答内容。
  • 持续更新:一次购买,永久有效。大明哥会持续更新 3+ 年,累计更新 1000+,宝典会不断迭代更新,保证最新、最全面。
  • 覆盖全面:本宝典累计更新 1000+,从 Java 入门到 Java 架构的高频面试题,实现 360° 全覆盖。
  • 不止面试:内容包含面试题解析、内容详解、知识扩展,它不仅仅只是一份面试题,更是一套完整的 Java 知识体系。
  • 宝典详情:https://www.yuque.com/chenssy/sike-java/xvlo920axlp7sf4k
  • 宝典总览:https://www.yuque.com/chenssy/sike-java/yogsehzntzgp4ly1
  • 宝典进展:https://www.yuque.com/chenssy/sike-java/en9ned7loo47z5aw

目前 Java 面试宝典累计更新 400+ 道,总字数 42w+。大明哥还在持续更新中,下图是大明哥在 2024-12 月份的更新情况:

想了解详情的小伙伴,扫描下面二维码加大明哥微信【daming091】咨询

同时,大明哥也整理一套目前市面最常见的热点面试题。微信搜[大明哥聊 Java]或扫描下方二维码关注大明哥的原创公众号[大明哥聊 Java] ,回复【面试题】 即可免费领取。

阅读全文