refresh()中的finishBeanFactoryInitialization()函数,Spring Boot利用反射机制实例化新的Bean。新Bean创建后,Spring Boot还会继续对Bean进行操作,如填充变量和初始化等。在初始化过程中如果需要对Bean进行切面处理,那么将会利用JDK动态代理或CGLiB动态代理生成Bean的代理对象。
JDK动态代理和CGLIB动态代理
在Spring Boot中根据被代理对象类是否是接口的实现,如果是一个接口的实现类使用JDK动态代理生成代理对象,如果类没有实现接口就用CGLiB动态代理生成代理对象。
JDK动态代理
核心是InvocationHandler接口和Proxy类,目标类必须是一个接口的实现,采用动态代理机制为其生成代理对象实例。
CGLiB动态代理
如果目标类没有实现任何接口,使用开源的动态字节码生成类库CGLIB(Code Generation Library)为目标对象生成代理对象实例。
AnnotationAwareAspectJAutoProxyCreator对象创建
Spring Boot引入包spring-boot-starter-aop默认自动开启装配。
在registerBeanPostProcessors()函数中先创建AnnotationAwareAspectJAutoProxyCreator对象,在finishBeanFactoryInitialization()函数中通过AnnotationAwareAspectJAutoProxyCreator对象完成代理对象生成逻辑。
registerBeanPostProcessors()函数中调用类PostProcessorRegistrationDelegate中static方法registerBeanPostProcessors()。
下面代码片段中beanFactory.getBean()会实例化AnnotationAwareAspectJAutoProxyCreator对象,注册到BeanFactory中。
Spring中的BeanFactoryPostProcessor是在BeanFactory创建之后,Bean创建之前执行;而BeanPostProcessor在Bean创建之后执行,是对Bean的后续操作。因此BeanPostProcessor的执行顺序是在BeanFactoryPostProcessor之后。先有了Bean,然后执行BeanPostProcessor处理Bean。
类AnnotationAwareAspectJAutoProxyCreator实现了接口BeanPostProcessor。
public static void registerBeanPostProcessors(
ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
//...略去部分代码...
// Next, register the BeanPostProcessors that implement Ordered.
List orderedPostProcessors = new ArrayList();
for (String ppName : orderedPostProcessorNames) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
orderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
//...略去部分代码...
}
填充对象和生成代理对象
从finishBeanFactoryInitialization()函数进入,依次进入Bean实例化逻辑,执行过程顺序在或公众号文章《Spring refresh函数(3)——Spring Boot finishBeanFactoryInitialization》(以后简称“refresh函数(3)”)中讲述。
到类AbstractAutowireCapableBeanFactory中的doCreateBean()方法。“refresh函数(3)”中我们描述方法createBeanInstance()最终利用Java反射机制创建Bean的过程,将方法createBeanInstance()后面的逻辑暂时忽略掉。现在我们继续看之前被忽略的代码逻辑。
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)
throws BeanCreationException {
//这里实例化Bean
// Instantiate the bean.
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);
Class beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null);
mbd.resolvedTargetType = beanType;
//...略去部分代码...
//对实例化的Bean进行填充和初始化
// Initialize the bean instance.
Object exposedObject = bean;
try {
populateBean(beanName, mbd, instanceWrapper);
if (exposedObject != null) {
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);
}
}
//...略去部分代码...
return exposedObject;
}
populateBean()填充Bean
注册的多个BeanPostProcessor依次顺序执行postProcessPropertyValues()方法对Bean进行填充,例如AutowiredAnnotationBeanPostProcessor对象对@Autowired注解描述的Field进行填充。
protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) {
//...略去部分代码...
boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE);
if (hasInstAwareBpps || needsDepCheck) {
PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
if (hasInstAwareBpps) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
//注册的多个BeanPostProcessor依次对Bean进行填充
pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvs == null) {
return;
}
}
}
}
if (needsDepCheck) {
checkDependencies(beanName, mbd, filteredPds, pvs);
}
}
applyPropertyValues(beanName, mbd, bw, pvs);
}
以AutowiredAnnotationBeanPostProcessor对象为例进入到postProcessPropertyValues()方法中。
@Override
public PropertyValues postProcessPropertyValues(
PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeanCreationException {
InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
try {
metadata.inject(bean, beanName, pvs);
}
catch (BeanCreationException ex) {
throw ex;
}
catch (Throwable ex) {
throw new BeanCreationException(beanName, "Injection of autowired dependencies failed", ex);
}
return pvs;
}
直接看代码metadata.inject(bean, beanName, pvs)。类InjectionMetadata中inject()方法。
public void inject(Object target, String beanName, PropertyValues pvs) throws Throwable {
Collection elementsToIterate =
(this.checkedElements != null ? this.checkedElements : this.injectedElements);
if (!elementsToIterate.isEmpty()) {
boolean debug = logger.isDebugEnabled();
for (InjectedElement element : elementsToIterate) {
if (debug) {
logger.debug("Processing injected element of bean '" + beanName + "': " + element);
}
element.inject(target, beanName, pvs);
}
}
}
继续element.inject(target, beanName, pvs)。类InjectionMetadata中的内部类InjectedElement的子类AutowiredFieldElement的inject()方法。BeanFactory的resolveDependency()尝试去处理依赖,如果field是一个Bean,需要对依赖的Bean进行提前的创建和初始化。Java反射机制对Bean进行填充。这里可能涉及到的单例Bean的循环依赖问题,在或公众号其他文章中会详细介绍。
@Override
protected void inject(Object bean, String beanName, PropertyValues pvs) throws Throwable {
Field field = (Field) this.member;
Object value;
if (this.cached) {
value = resolvedCachedArgument(beanName, this.cachedFieldValue);
}
else {
DependencyDescriptor desc = new DependencyDescriptor(field, this.required);
desc.setContainingClass(bean.getClass());
Set autowiredBeanNames = new LinkedHashSet(1);
TypeConverter typeConverter = beanFactory.getTypeConverter();
try {
//尝试去处理依赖
value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
}
catch (BeansException ex) {
throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(field), ex);
}
synchronized (this) {
if (!this.cached) {
if (value != null || this.required) {
this.cachedFieldValue = desc;
registerDependentBeans(beanName, autowiredBeanNames);
if (autowiredBeanNames.size() == 1) {
String autowiredBeanName = autowiredBeanNames.iterator().next();
if (beanFactory.containsBean(autowiredBeanName)) {
if (beanFactory.isTypeMatch(autowiredBeanName, field.getType())) {
this.cachedFieldValue = new ShortcutDependencyDescriptor(
desc, autowiredBeanName, field.getType());
}
}
}
}
else {
this.cachedFieldValue = null;
}
this.cached = true;
}
}
}
//填充field
if (value != null) {
ReflectionUtils.makeAccessible(field);
field.set(bean, value);
}
}
}
initializeBean()方法中的AOP
initializeBean()方法英文注释翻译为“初始化给定的Bean实例,应用工厂的回调方法、初始方法和BeanPostProcessor”。在中文理解初始化是一个Bean完整的生产过程或者是对一些属性进行默认设置,而实际上initializeBean()方法在这里是对已经实例化并且填充了field的Bean进行收尾工作,我们讨论的AOP切片就在这里完成的。
/**
* Initialize the given bean instance, applying factory callbacks
* as well as init methods and bean post processors.
*/
protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged(new PrivilegedAction
进入类AbstractAutowireCapableBeanFactory中的applyBeanPostProcessorsAfterInitialization()方法。
依次遍历所有的BeanPostProcessor对Bean进行后初始化操作。为专注讨论AOP,这里忽略掉其他无关的BeanPostProcessor,直接看对象AnnotationAwareAspectJAutoProxyCreator(在上文介绍过,在registerBeanPostProcessors()方法中实例化的)。
@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
result = beanProcessor.postProcessAfterInitialization(result, beanName);
if (result == null) {
return result;
}
}
return result;
}
AnnotationAwareAspectJAutoProxyCreator的父类AbstractAutoProxyCreator中具体实现postProcessAfterInitialization()方法。
postProcessAfterInitialization()方法中,如果代理对象已经存在于第二级缓存中(this.earlyProxyReferences.contains(cacheKey)代码逻辑,Spring在创建Bean时使用了三级缓存结构),证明已经生成过代理对象,则不再重新生成。
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (bean != null) {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
if (!this.earlyProxyReferences.contains(cacheKey)) {
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
AbstractAutoProxyCreator wrapIfNecessary()方法。getAdvicesAndAdvisorsForBean()方法确定Bean是否需要被代理,如果需要的话,返回创建的切面接口PointcutAdvisor对象。createProxy()方法进行代理的创建。
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
if (beanName != null && this.targetSourcedBeans.contains(beanName)) {
return bean;
}
if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
return bean;
}
if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
// Create proxy if we have advice.
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
if (specificInterceptors != DO_NOT_PROXY) {
this.advisedBeans.put(cacheKey, Boolean.TRUE);
Object proxy = createProxy(
bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
}
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
类InstantiationModelAwarePointcutAdvisorImpl是接口PointcutAdvisor的具体实现类。InstantiationModelAwarePointcutAdvisorImpl对象是被代理Bean的切面的描述。
接下来继续进入类AbstractAutoProxyCreator中createProxy()方法。创建ProxyFactory对象,getProxy()生成代理。
protected Object createProxy(
Class beanClass, String beanName, Object[] specificInterceptors, TargetSource targetSource) {
if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
}
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.copyFrom(this);
if (!proxyFactory.isProxyTargetClass()) {
if (shouldProxyTargetClass(beanClass, beanName)) {
proxyFactory.setProxyTargetClass(true);
}
else {
evaluateProxyInterfaces(beanClass, proxyFactory);
}
}
Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
for (Advisor advisor : advisors) {
proxyFactory.addAdvisor(advisor);
}
proxyFactory.setTargetSource(targetSource);
customizeProxyFactory(proxyFactory);
proxyFactory.setFrozen(this.freezeProxy);
if (advisorsPreFiltered()) {
proxyFactory.setPreFiltered(true);
}
return proxyFactory.getProxy(getProxyClassLoader());
}
类ProxyFactory中getProxy()。
public Object getProxy(ClassLoader classLoader) {
return createAopProxy().getProxy(classLoader);
}
先进入createAopProxy()方法,依次调用类ProxyCreatorSupport中的createAopProxy()方法和类DefaultAopProxyFactory的createAopProxy()方法。
//类ProxyCreatorSupport
protected final synchronized AopProxy createAopProxy() {
if (!this.active) {
activate();
}
return getAopProxyFactory().createAopProxy(this);
}
类DefaultAopProxyFactory的createAopProxy()方法会根据将被代理的类是否是接口的实现,确定使用JDK动态代理还是CGLIB动态代理。如果实现了具体的接口,使用JDK动态代理,否则使用CGLIB动态代理。
所以,Spring AOP利用的是动态代理机制,即使用JDK动态代理,也使用CGLIB动态代理。
//类DefaultAopProxyFactory
@Override
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
Class targetClass = config.getTargetClass();
if (targetClass == null) {
throw new AopConfigException("TargetSource cannot determine target class: " +
"Either an interface or a target is required for proxy creation.");
}
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
return new JdkDynamicAopProxy(config);
}
return new ObjenesisCglibAopProxy(config);
}
else {
return new JdkDynamicAopProxy(config);
}
}
回到类ProxyFactory中getProxy()。假设我们的类没有实现接口,进入到类CglibAopProxy中getProxy()方法,接下来的操作就是利用CGLIB生成代理对象。
@Override
public Object getProxy(ClassLoader classLoader) {
if (logger.isDebugEnabled()) {
logger.debug("Creating CGLIB proxy: target source is " + this.advised.getTargetSource());
}
try {
Class rootClass = this.advised.getTargetClass();
Assert.state(rootClass != null, "Target class must be available for creating a CGLIB proxy");
Class proxySuperClass = rootClass;
if (ClassUtils.isCglibProxyClass(rootClass)) {
proxySuperClass = rootClass.getSuperclass();
Class[] additionalInterfaces = rootClass.getInterfaces();
for (Class additionalInterface : additionalInterfaces){
this.advised.addInterface(additionalInterface);
}
}
// Validate the class, writing log messages as necessary.
validateClassIfNecessary(proxySuperClass, classLoader);
// Configure CGLIB Enhancer...
Enhancer enhancer = createEnhancer();
if (classLoader != null) {
enhancer.setClassLoader(classLoader);
if (classLoader instanceof SmartClassLoader &&
((SmartClassLoader) classLoader).isClassReloadable(proxySuperClass)) {
enhancer.setUseCache(false);
}
}
enhancer.setSuperclass(proxySuperClass);
enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised));
enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
enhancer.setStrategy(new ClassLoaderAwareUndeclaredThrowableStrategy(classLoader));
Callback[] callbacks = getCallbacks(rootClass);
Class[] types = new Class[callbacks.length];
for (int x = 0; x < types.length; x++) {
types[x] = callbacks[x].getClass();
}
// fixedInterceptorMap only populated at this point, after getCallbacks call above
enhancer.setCallbackFilter(new ProxyCallbackFilter(
this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset));
enhancer.setCallbackTypes(types);
// Generate the proxy class and create a proxy instance.
return createProxyClassAndInstance(enhancer, callbacks);
}
catch (CodeGenerationException ex) {
throw new AopConfigException("Could not generate CGLIB subclass of class [" +
this.advised.getTargetClass() + "]: " +
"Common causes of this problem include using a final class or a non-visible class",
ex);
}
catch (IllegalArgumentException ex) {
throw new AopConfigException("Could not generate CGLIB subclass of class [" +
this.advised.getTargetClass() + "]: " +
"Common causes of this problem include using a final class or a non-visible class",
ex);
}
catch (Throwable ex) {
// TargetSource.getTarget() failed
throw new AopConfigException("Unexpected AOP exception", ex);
}
}
自此完整的Spring Boot AOP生成了代理对象。在我们的代码示例中定义一个UserController类,如下图生成其代理对象,最终Spring Boot容器使用的就是这个代理对象。
DEBUG源码执行的顺序表
为了方便debug时快速找到具体的实现方法,把Spring Boot(版本1.5.7.RELEASE) AOP的调用顺序统计在下表中,方法中省略参数列表。