上一篇,我们最后通过一个例子讲解了resolveBeforeInstantiation()中,通过InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation返回一个代理对象,下面,我们继续分析这个方法返回的是null的情况,那么它就会往下执行doCreateBean()。
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
// 省略部分代码...
// 1、代理对象的创建
// 一般是实现了InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation()
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
// 如果bean不为null ,则直接返回,这种情况通常创建了代理对象。后面的doCreateBean不再执行
return bean;
}
// 2、普通bean创建
// 包括检查是否进行了类加载(没有则进行类加载),bean对象实例创建,bean对象实例的属性赋值,init-method的调用,BeanPostProcessor的调用
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
}
假如,我们有一个A bean需要创建,并且设置了一个AOP切面:
@Component
public class A {
public void test(){
System.out.println("----a---");
}
}
@Aspect
@Component
public class Aop {
@Pointcut("execution(* com.example.demo.aop2..*.*(..))")
private void pointcut(){}
@After("pointcut()")
public void advice(){
System.out.println("-----------后置增强---------");
}
}
@Configuration
@ComponentScan("com.example.demo.aop2")
@EnableAspectJAutoProxy
public class AppConfig {
}
public class Test {
public static void main(String[] args) {
AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);
A a = ac.getBean(A.class);
a.f();
}
}
通过打断点调试,我们发现在创建beanName=a的时候,执行到:Object bean = resolveBeforeInstantiation(beanName, mbdToUse) 时,返回的bean=null,所以会往下执行:
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
这个方法是重点,它主要作用是检查是否进行了类加载(没有则进行类加载)、bean对象的创建、bean对象的属性赋值,init-method方法的调用,BeanPostProcessor的调用等,大致:
实例化(前后)-->属性填充-->初始化(前后) (这里暂且不讨论循环依赖的情况)。
【重点】
AbstractAutowireCapableBeanFactory#doCreateBean()
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException {
// Instantiate the bean.
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
// 1、推断构造方法并且实例化bean对象
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
// 获取原始对象
final Object bean = instanceWrapper.getWrappedInstance();
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}
// Allow post-processors to modify the merged bean definition.
// 2、做一些合并bean定义的逻辑
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
} catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Post-processing of merged bean definition failed", ex);
}
mbd.postProcessed = true;
}
}
// Eagerly cache singletons to be able to resolve circular references
// even when triggered by lifecycle interfaces like BeanFactoryAware.
// 判断属于单例、并且允许循环依赖、在当前正在创建的beanName集合中
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
if (logger.isDebugEnabled()) {
logger.debug("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
// 重点:3、将当前正在创建的bean的单例工厂放入到SingletonFactories集合中(三级缓存)
// 第二个参数,ObjectFactory属于函数式接口,只有getObject()一个方法,所以支持lambda表达式
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
// Initialize the bean instance.
Object exposedObject = bean;
try {
// 4、填充属性--->循环依赖
// populateBean中 会执行InstantiationAwareBeanPostProcessor中的postProcessAfterInstantiation,
// 这是在对象实例化后,还没有进行属性填充的时候会调用的方法。如果此时该方法返回false,
// 并且mbd.getDependencyCheck() 不需要check,则不会进行属性填充,否则继续走下面的逻辑
// 【注意】提前动态代理(循环依赖),其实是在依赖注入的时候,也就是在populateBean属性填充方法内完成的
populateBean(beanName, mbd, instanceWrapper);
// 5、执行initializeBean,初始化Bean
// 【注意】非提前生成代理对象(非循环依赖)是在属性填充populateBean完成之后,执行了initializeBean方法的里面进行的动态代理
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
。。。。
}
上面注释可以清楚知道,实例化-->属性填充-->初始化,下面我们重点关注初始化方法initializeBean()
// 初始化(前后),AOP代理对象
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
// 执行invokeAwareMethods 处理部分Aware接口的方法
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()) {
//初始化之前的回调:对该bean调用所有后置处理器的postProcessBeforeInitialization方法
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()) {
//【aop重点】初始化后:代理对象的生成就在这个方法中生成
// 非提前生成代理对象(非循环依赖)是在属性填充populateBean完成之后,执行了initializeBean方法的时候进行的动态代理
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
看注释基本都清楚,这个方法就是:
- 初始化前:对该bean调用所有后置处理器的postProcessBeforeInitialization方法
- 初始化
- 初始化后:代理对象的生成就在这个方法中生成
这里我们重点关注初始化后,调用applyBeanPostProcessorsAfterInitialization()方法,主要是遍历所有的bean后置处理器,然后分别执行相应的后置处理方法postProcessAfterInitialization()
@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
// 遍历所有的bean后置处理器
for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
// 其中有一个子类AbstractAutoProxyCreator,调用它的postProcessAfterInitialization就会产生aop代理对象
// 所以非提前生成的代理对象 是在属性填充populateBean完成之后,执行了initializeBean方法的时候进行的动态代理
Object current = beanProcessor.postProcessAfterInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}
我们上面有分析,其中,有一个AbstractAutoProxyCreator,就属于BeanPostProcessor接口的子类,调用它的postProcessAfterInitialization就会产生aop代理对象。
下面,我们跟进断点调试验证:
原始对象A@2508并非代理对象
当执行完applyBeanPostProcessorsAfterInitialization()方法后,发现返回了一个代理对象,并且该代理对象是通过cglib生成的(因为我们的A类没有实现任何接口,在Spring中默认为基于JDK的动态代理,但在SpringBoot2.x中默认是Cglib)
因此,我们知道代理对象就是在bean初始化后进行创建的,具体AbstractAutoProxyCreator#postProcessAfterInitialization() 如下:
@Override
public Object postProcessAfterInitialization(@Nullable 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;
}
上述方法:根据bean类型和名字创建缓存key,判断earlyProxyReferences提前动态代理的集合当中存不存在这个缓存key,若存在则说明已经进行过动态代理了,则不再进行动态代理,而本例子中,很明显是没有执行提前动态代理的,所以会执行wrapIfNecessary方法进行构建动态代理对象
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
if (StringUtils.hasLength(beanName) && 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;
}
创建代理对象:createProxy
createProxy的源码如下:代理对象可以基于JDK的动态代理或者基于Cglib来创建,在Spring中默认为基于JDK的动态代理(在SpringBoot2.x中默认是Cglib,具体可看《SpringBoot2.x中为何默认使用Cglib》),如果ProxyConfig配置类的proxy-target-class属性为true或者目标类没有实现接口,则使用Cglib来创建代理对象。
protected Object createProxy(Class<?> beanClass, @Nullable String beanName,
@Nullable Object[] specificInterceptors, TargetSource targetSource) {
if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
}
// 每个bean对象都new一个单例的ProxyFactory来创建代理对象,因为每个bean需要的辅助方法不一样,
// 然后将该ProxyFactory对象引用作为构造函数参数创建对应的代理对象
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.copyFrom(this);
// // 检查是否配置了<aop:config />节点的proxy-target-class属性为true-->cglib
if (!proxyFactory.isProxyTargetClass()) {
if (shouldProxyTargetClass(beanClass, beanName)) {
proxyFactory.setProxyTargetClass(true);
} else {
evaluateProxyInterfaces(beanClass, proxyFactory);
}
}
Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
// 为该代理工厂添加辅助功能包装器Advisors,结合Advisors来生成代理对象的方法拦截器
proxyFactory.addAdvisors(advisors);
// 目标类
proxyFactory.setTargetSource(targetSource);
customizeProxyFactory(proxyFactory);
proxyFactory.setFrozen(this.freezeProxy);
if (advisorsPreFiltered()) {
proxyFactory.setPreFiltered(true);
}
// 为目标类创建代理对象,如果配置了aop:config的proxy-target-class为true,则使用CGLIB
// 否则如果目标类为接口则使用JDK代理,否则使用CGLIB
return proxyFactory.getProxy(getProxyClassLoader());
}
上面源码注释已经写得很清楚,下面进入proxyFactory.getProxy方法,由于ProxyFactory继承ProxyCreatorSupport类,所以进入该方法后可知,真正的实现在ProxyCreatorSupport类中,调用的方法是ProxyCreatorSupport类中的方法,而ProxyFactory只是做了一层封装,
public Object getProxy(ClassLoader classLoader) {
// 下面的createAopProxy()方法是ProxyCreatorSupport类中的方法
return createAopProxy().getProxy(classLoader);
}
重点来了,下面将浮现jdk和cglib代理的真正面目
createAopProxy()方法返回的是AopProxy接口类型,它有两个实现类,分别是:
- CglibAopProxy(通过cglib方式生成代理对象)
- JdkDynamicAopProxy(通过JDK动态代理方式生成对象)
AopProxy的作用是用于生成代理对象,稍后将会分析这两种不同的实现方式。
那么,CglibAopProxy或者JdkDynamicAopProxy又是如何生成的呢?进入createAopProxy方法,该方法就是获取AopProxy的地方,由方法可知,这里使用了AopProxyFactory来创建AopProxy,而AopProxyFactory使用的是DefaultAopProxyFactory默认的代理工厂类。
public class DefaultAopProxyFactory implements AopProxyFactory, Serializable {
@Override
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
// 选择jdk动态代理 或 cglib 代理
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.");
}
// 如果targetClass是接口类,那么使用JDK来生成代理对象,返回JdkDynamicAopProxy类型的对象
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
return new JdkDynamicAopProxy(config);
}
// 否则,返回ObjenesisCglibAopProxy类型的对象,它是使用cglib的方式生成代理对象
return new ObjenesisCglibAopProxy(config);
} else {
return new JdkDynamicAopProxy(config);
}
}
扩展:Cglib代理,原理是生成目标类的子类(即这个子类对象就是代理对象),它是在内存中构件一个子类对象,从而实现对目标对象的功能拓展。不管有没有实现接口都可以使用Cglib代理, 而不是只有在无接口的情况下才能使用。具体可以查看《【Java必备】Java代理模式(静态代理、JDK/Cglib动态代理)》。
到这里,我们已经基本清楚AopProxy对象是如何生成的了,接下来我们介绍CglibAopProxy和JdkDynamicAopProxy又是如何生成代理对象的?
JDK动态代理
基于接口实现,通过实现目标类所包含的接口的方法来实现代理,即返回的代理对象为接口的实现类。由于是基于JDK的动态代理实现,即实现了JDK提供的InvocationHandler接口,故在运行时在invoke方法拦截目标类对应被代理的接口的所有方法的执行:获取当前执行的方法对应的方法拦截器链,然后通过反射执行该方法时,在方法执行前后执行对应的方法拦截器。
JdkDynamicAopProxy#getProxy
@Override
public Object getProxy(@Nullable ClassLoader classLoader) {
if (logger.isDebugEnabled()) {
logger.debug("Creating JDK dynamic proxy: target source is " + this.advised.getTargetSource());
}
Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);
findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
}
JdkDynamicAopProxy#getProxy
// JDK的动态代理是基于接口的,故只能代理接口中定义的方法。
// 该类需要通过代理工厂,具体为继承了AdvisedSupport的代理工厂来创建,而不是直接创建,
// 因为AdvisedSupport提供了AOP的相关配置信息,如Advisors列表等。
final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializable {
// 重写InvocationHandler接口的invoke方法
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
MethodInvocation invocation;
Object oldProxy = null;
boolean setProxyContext = false;
TargetSource targetSource = this.advised.targetSource;
Object target = null;
try {
if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
// The target does not implement the equals(Object) method itself.
return equals(args[0]);
} else if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
// The target does not implement the hashCode() method itself.
return hashCode();
} else if (method.getDeclaringClass() == DecoratingProxy.class) {
// There is only getDecoratedClass() declared -> dispatch to proxy config.
return AopProxyUtils.ultimateTargetClass(this.advised);
} else if (!this.advised.opaque && method.getDeclaringClass().isInterface() &&
method.getDeclaringClass().isAssignableFrom(Advised.class)) {
// Service invocations on ProxyConfig with the proxy config...
return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);
}
Object retVal;
if (this.advised.exposeProxy) {
// Make invocation available if necessary.
oldProxy = AopContext.setCurrentProxy(proxy);
setProxyContext = true;
}
// Get as late as possible to minimize the time we "own" the target,
// in case it comes from a pool.
target = targetSource.getTarget();
Class<?> targetClass = (target != null ? target.getClass() : null);
// 获取该方法对应的方法拦截器列表
// 实现:通过该方法所在类对应的Advisors,获取该方法的辅助功能Advices列表,即方法拦截器列表。这里的实现为懒加载,
// 即当方法第一次调用的时候才创建该方法拦截器列表,然后使用一个ConcurrentHashMap缓存起来,之后的方法调用直接使用。
// 其中advised就是该方法的所在bean对应的ProxyFactory对象引用,通过ProxyFactory来创建AopProxy,即当前类对象实例。
// Get the interception chain for this method.
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
// Check whether we have any advice. If we don't, we can fallback on direct
// reflective invocation of the target, and avoid creating a MethodInvocation.
// 当前执行的方法不包括方法拦截器,即不需要额外的辅助功能,则可以直接执行
if (chain.isEmpty()) {
// We can skip creating a MethodInvocation: just invoke the target directly
// Note that the final invoker must be an InvokerInterceptor so we know it does
// nothing but a reflective operation on the target, and no hot swapping or fancy proxying.
Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
} else {
// 如果当前方法包括方法拦截器,即在执行时需要其他额外的辅助功能,则创建ReflectiveMethodInvocation
// We need to create a method invocation...
invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
// Proceed to the joinpoint through the interceptor chain.
retVal = invocation.proceed();
}
// Massage return value if necessary.
Class<?> returnType = method.getReturnType();
if (retVal != null && retVal == target &&
returnType != Object.class && returnType.isInstance(proxy) &&
!RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {
// Special case: it returned "this" and the return type of the method
// is type-compatible. Note that we can't help if the target sets
// a reference to itself in another returned object.
retVal = proxy;
} else if (retVal == null && returnType != Void.TYPE && returnType.isPrimitive()) {
throw new AopInvocationException(
"Null return value from advice does not match primitive return type for: " + method);
}
return retVal;
} finally {
if (target != null && !targetSource.isStatic()) {
// Must have come from TargetSource.
targetSource.releaseTarget(target);
}
if (setProxyContext) {
// Restore old proxy.
AopContext.setCurrentProxy(oldProxy);
}
}
}
。。。。
CGLIB代理
创建目标类的子类来实现代理,代理拦截的只能是目标类的public和protected方法,核心方法为getProxy(),即创建代理对象,在这里织入了辅助功能。
注意:基于类的代理,具体实现为通过创建目标类的子类来实现代理,即代理对象对应的类为目标类的子类。 所以目标类的需要被代理的方法不能为final,因为子类无法重写final的方法;同时被代理的方法需要是public或者protected,不能是static,private或者包可见,即不加可见修饰符。如在事务中,@Transactional注解不能对private,static,final,包可见的方法添加事务功能,只能为public方法。这个代理对象也需要通过代理工厂来创建,具体为继承了AdvisedSupport的代理工厂来创建,而不是直接创建。
class CglibAopProxy implements AopProxy, Serializable {
// 创建代理对象
@Override
public Object getProxy(@Nullable 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);
// 创建目标类的子类来实现代理,即织入辅助功能
// 创建并配置Enhancer,它是cglib主要的操作类,用于代理对象的生成
// Configure CGLIB Enhancer...
Enhancer enhancer = createEnhancer();
if (classLoader != null) {
enhancer.setClassLoader(classLoader);
if (classLoader instanceof SmartClassLoader &&
((SmartClassLoader) classLoader).isClassReloadable(proxySuperClass)) {
enhancer.setUseCache(false);
}
}
// 配置enhancer对象,比如 代理接口,父类,回调方法等
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);
// 通过enhancer来生成代理对象
// Generate the proxy class and create a proxy instance.
return createProxyClassAndInstance(enhancer, callbacks);
}
。。。。
}
到此,目标对象的代理对象已经生成,并且已经设置好了拦截器(通知),当代理对象调用目标方法时,就会触发这些拦截器。
参考:
●阿里巴巴为什么能抗住90秒100亿?--服务端高并发分布式架构演进之路
●SpringCloud电商秒杀微服务-Redisson分布式锁方案
查看更多好文,进入公众号--撩我--往期精彩
一只 有深度 有灵魂 的公众号0.0