spring bean初始化扩展之Aware源码解析

18 篇文章 0 订阅
17 篇文章 0 订阅

认识Aware接口

package org.springframework.beans.factory;

/**
 * A marker superinterface indicating that a bean is eligible to be notified by the
 * Spring container of a particular framework object through a callback-style method.
 * The actual method signature is determined by individual subinterfaces but should
 * typically consist of just one void-returning method that accepts a single argument.
 *
 * <p>Note that merely implementing {@link Aware} provides no default functionality.
 * Rather, processing must be done explicitly, for example in a
 * {@link org.springframework.beans.factory.config.BeanPostProcessor}.
 * Refer to {@link org.springframework.context.support.ApplicationContextAwareProcessor}
 * for an example of processing specific {@code *Aware} interface callbacks.
 *
 * @author Chris Beams
 * @author Juergen Hoeller
 * @since 3.1
 */
public interface Aware {

}

可以看到Aware是一个空接口,没有任何方法,它类似于java.io.Serializable接口,作用是标识某一类接口。Aware是Spring容器中非常重要的一个接口。有很多接口继承了Aware接口,如BeanFactoryAware。而实现了这些接口的bean将会被Spring容器回调通知(即调用接口中得set方法)。一般继承Aware接口的接口,会定义相应setXxx接口方法,如BeanFactoryAware定义了setBeanFactory方法,spring容器会在初始化bean时,会调用bean实现的Aware接口的setXxx方法,这个调用过程在上一篇博客有介绍。

举例BeanFactoryAware

package org.springframework.beans.factory;

import org.springframework.beans.BeansException;

/**
 * Interface to be implemented by beans that wish to be aware of their
 * owning {@link BeanFactory}.
 *
 * <p>For example, beans can look up collaborating beans via the factory
 * (Dependency Lookup). Note that most beans will choose to receive references
 * to collaborating beans via corresponding bean properties or constructor
 * arguments (Dependency Injection).
 *
 * <p>For a list of all bean lifecycle methods, see the
 * {@link BeanFactory BeanFactory javadocs}.
 *
 * @author Rod Johnson
 * @author Chris Beams
 * @since 11.03.2003
 * @see BeanNameAware
 * @see BeanClassLoaderAware
 * @see InitializingBean
 * @see org.springframework.context.ApplicationContextAware
 */
public interface BeanFactoryAware extends Aware {

	/**
	 * Callback that supplies the owning factory to a bean instance.
	 * <p>Invoked after the population of normal bean properties
	 * but before an initialization callback such as
	 * {@link InitializingBean#afterPropertiesSet()} or a custom init-method.
	 * @param beanFactory owning BeanFactory (never {@code null}).
	 * The bean can immediately call methods on the factory.
	 * @throws BeansException in case of initialization errors
	 * @see BeanInitializationException
	 */
	void setBeanFactory(BeanFactory beanFactory) throws BeansException;

}

spring调用Aware的setXxx进行回调通知

AbstractAutowireCapableBeanFactory中初始化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;
	}

可以看到是初始化bean的几个步骤里面,在第一步进行了激活Aware接口的方法,invokeAwareMethods,其实现如下:

private void invokeAwareMethods(final String beanName, final Object bean) {
		//这里主要处理 BeanNameAware  BeanClassLoaderAware  BeanFactoryAware这三个接口,可以看到主要是调用bean实现的Aware中的setXxx方法
		if (bean instanceof Aware) {
			if (bean instanceof BeanNameAware) {
				((BeanNameAware) bean).setBeanName(beanName);
			}
			if (bean instanceof BeanClassLoaderAware) {
				ClassLoader bcl = getBeanClassLoader();
				if (bcl != null) {
					((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
				}
			}
			if (bean instanceof BeanFactoryAware) {
				((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
			}
		}
	}

可以看到这里主要处理了BeanNameAware BeanClassLoaderAware BeanFactoryAware这三个接口,通过调用setXxx方法,将属性设置给bean。

示例代码

工程结构

这里用ApplicationContextAware作为示例代码的接口。以下是工程结构
在这里插入图片描述

MyAware

package spring.aware;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

public class MyAware implements ApplicationContextAware {

    private ApplicationContext myapplicationContext;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        myapplicationContext = applicationContext;
        System.out.println("spring容器已调用setApplicationContext进行回调通知,myapplicationContext=" + myapplicationContext);
    }

    public ApplicationContext getMyapplicationContext() {
        return myapplicationContext;
    }
}

AwareConfig

package spring.aware;

import org.springframework.context.annotation.*;

@Configuration
public class AwareConfig {

    @Bean(value = "myAware")
    public MyAware myAware() {
        return new MyAware();
    }
}

AwareTest

package spring.aware.test;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import spring.aware.AwareConfig;
import spring.aware.MyAware;


public class AwareTest {

    @Test
    public void testAware() {
        ApplicationContext applicationContext = new AnnotationConfigApplicationContext(AwareConfig.class);
        MyAware myAware = (MyAware) applicationContext.getBean("myAware");
        System.out.println("从容器中获取的myAware="+myAware + ",其applicationContext属性=" + myAware.getMyapplicationContext());
    }
}

运行结果

在这里插入图片描述

方法调用栈分析

在这里插入图片描述
前面我们分析了BeanNameAware BeanClassLoaderAware BeanFactoryAware这三个接口是在初始化bean的第一步就做了处理。通过上图这个调用栈可以看到,其它实现的Aware的接口,则通过相应的后置处理器(如这里的ApplicationContextAwareProcessor)进行间接处理,最终调用了相应的setXxx方法。
ApplicationContextAwareProcessor

@Override
	@Nullable
	public Object postProcessBeforeInitialization(final Object bean, String beanName) throws BeansException {
		AccessControlContext acc = null;

		if (System.getSecurityManager() != null &&
				(bean instanceof EnvironmentAware || bean instanceof EmbeddedValueResolverAware ||
						bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware ||
						bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware)) {
			acc = this.applicationContext.getBeanFactory().getAccessControlContext();
		}

		if (acc != null) {
			AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
				invokeAwareInterfaces(bean);
				return null;
			}, acc);
		}
		else {
			//调用激活Aware接口
			invokeAwareInterfaces(bean);
		}

		return bean;
	}

	private void invokeAwareInterfaces(Object bean) {
		//根据不同接口调用相应的setXxx方法
		if (bean instanceof Aware) {
			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);
			}
		}
	}

可以猜想,其他Aware的调用时机,也应该是通过相应的后置处理器进行处理,间接调用相应的setXxx方法。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值