文章目录
代理对象的生成
advisor对象已经生成完毕之前已经介绍完了,现在来看代理对象的生成,以及代理对象是如何使用advisor的。
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.
//已经获取到所有符合条件的advisor
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;
}
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);
}
//创建proxyFactory对象
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.copyFrom(this);
if (!proxyFactory.isProxyTargetClass()) {
//根据beanName检查对应的beandefinition的PRESERVE_TARGET_CLASS_ATTRIBUTE属性,
//返回true,则ProxyTargetClass设置为true
if (shouldProxyTargetClass(beanClass, beanName)) {
proxyFactory.setProxyTargetClass(true);
}
else {
//类没有实现接口的话,则ProxyTargetClass设置为true
evaluateProxyInterfaces(beanClass, proxyFactory);
}
}
//将传入进来的specificInterceptors进一步包装
Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
//将advisors设置进来
proxyFactory.addAdvisors(advisors);
//把被代理实例放入进来
proxyFactory.setTargetSource(targetSource);
customizeProxyFactory(proxyFactory);
proxyFactory.setFrozen(this.freezeProxy);
//AbstractAdvisorAutoProxyCreator的advisorsPreFiltered方法返回true
if (advisorsPreFiltered()) {
//preFiltered被设置为true
proxyFactory.setPreFiltered(true);
}
//创建代理对象
return proxyFactory.getProxy(getProxyClassLoader());
}
protected Advisor[] buildAdvisors(@Nullable String beanName, @Nullable Object[] specificInterceptors) {
// Handle prototypes correctly...
//这里添加实例化interceptorNames容器中存的beanName作为advisor
//可以通过实现BeanPostProcess接口和PriorityOrdered接口(要在AnnotationAwareAspectJAutoProxyCreator(实现了Ordered接口)注册到容器之前实例化),往interceptorNames容器中放入beanName
Advisor[] commonInterceptors = resolveInterceptorNames();
List<Object> allInterceptors = new ArrayList<>();
if (specificInterceptors != null) {
//将原本的之前匹配的advisors加入到allInterceptors中
allInterceptors.addAll(Arrays.asList(specificInterceptors));
if (commonInterceptors.length > 0) {
//默认为true
if (this.applyCommonInterceptorsFirst) {
//commonInterceptors 放在最前面 最先执行
allInterceptors.addAll(0, Arrays.asList(commonInterceptors));
}
//改为falsed的话,则添加到后面
else {
allInterceptors.addAll(Arrays.asList(commonInterceptors));
}
}
}
if (logger.isTraceEnabled()) {
int nrOfCommonInterceptors = commonInterceptors.length;
int nrOfSpecificInterceptors = (specificInterceptors != null ? specificInterceptors.length : 0);
logger.trace("Creating implicit proxy for bean '" + beanName + "' with " + nrOfCommonInterceptors +
" common interceptors and " + nrOfSpecificInterceptors + " specific interceptors");
}
Advisor[] advisors = new Advisor[allInterceptors.size()];
for (int i = 0; i < allInterceptors.size(); i++) {
advisors[i] = this.advisorAdapterRegistry.wrap(allInterceptors.get(i));
}
return advisors;
}
private Advisor[] resolveInterceptorNames() {
BeanFactory bf = this.beanFactory;
ConfigurableBeanFactory cbf = (bf instanceof ConfigurableBeanFactory ? (ConfigurableBeanFactory) bf : null);
List<Advisor> advisors = new ArrayList<>();
//循环interceptorNames
for (String beanName : this.interceptorNames) {
if (cbf == null || !cbf.isCurrentlyInCreation(beanName)) {
Assert.state(bf != null, "BeanFactory required for resolving interceptor names");
//实例化bean
Object next = bf.getBean(beanName);
//将bean包装为Advisor放入advisors中
advisors.add(this.advisorAdapterRegistry.wrap(next));
}
}
return advisors.toArray(new Advisor[0]);
}
public Advisor wrap(Object adviceObject) throws UnknownAdviceTypeException {
//已经是Advisor了,直接返回
if (adviceObject instanceof Advisor) {
return (Advisor) adviceObject;
}
//可以没有pointCut,但必须实现Advice接口
if (!(adviceObject instanceof Advice)) {
throw new UnknownAdviceTypeException(adviceObject);
}
Advice advice = (Advice) adviceObject;
//实现了MethodInterceptor,包装为DefaultPointcutAdvisor(PointCut为Pointcut.TRUE)
if (advice instanceof MethodInterceptor) {
// So well-known it doesn't even need an adapter.
return new DefaultPointcutAdvisor(advice);
}
//没有实现MethodInterceptor接口
//adapters 包含 MethodBeforeAdviceAdapter AfterReturningAdviceAdapter ThrowsAdviceAdapter
for (AdvisorAdapter adapter : this.adapters) {
// Check that it is supported.
//必须是实现AfterReturningAdvice MethodBeforeAdvice ThrowsAdvice接口中一种
//包装为DefaultPointcutAdvisor
if (adapter.supportsAdvice(advice)) {
return new DefaultPointcutAdvisor(advice);
}
}
throw new UnknownAdviceTypeException(advice);
}
public Object getProxy(@Nullable ClassLoader classLoader) {
return createAopProxy().getProxy(classLoader);
}
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
//isOptimize默认false
//isProxyTargetClass没有在EnableAspectJAutoProxy注解去配置,则默认为false
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.");
}
//实现了接口,或者已经是被jdk动态代理的类
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
//则采用jdk动态代理
return new JdkDynamicAopProxy(config);
}
//采用cglib动态代理
return new ObjenesisCglibAopProxy(config);
}
//ProxyTargetClass为false,则采用jdk动态代理
else {
//config为proxyFactory,将config赋值给JdkDynamicAopProxy中的advised字段
return new JdkDynamicAopProxy(config);
}
}
//已jdk动态代理为例
public Object getProxy(@Nullable ClassLoader classLoader) {
if (logger.isTraceEnabled()) {
logger.trace("Creating JDK dynamic proxy: " + this.advised.getTargetSource());
}
Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);
findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
//生成代理对象返回
return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
}
代理对象的具体拦截逻辑
以jdk动态代理为例,来看JdkDynamicAopProxy的具体的拦截逻辑。
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
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;
//如果配置的exposeProxy为true,则将代理对象放入threadLocal中
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);
// Get the interception chain for this method.
//对当前被调用的方法和符合的advisor的poincut进行match,拿到所有符合的advice,将所有的advice做为MethodInterceptor类型的list集合返回(方法拦截链)
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 {
// We need to create a method invocation...
//包装为ReflectiveMethodInvocation对象
MethodInvocation invocation =
new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
// Proceed to the joinpoint through the interceptor chain.
// advice和目标方法调用
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);
}
}
}
public List<Object> getInterceptorsAndDynamicInterceptionAdvice(Method method, @Nullable Class<?> targetClass) {
MethodCacheKey cacheKey = new MethodCacheKey(method);
//第一次进来没有
List<Object> cached = this.methodCache.get(cacheKey);
if (cached == null) {
//获取被调用方法可用的方法拦截链
cached = this.advisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice(
this, method, targetClass);
//后续再次调用,直接从methodCache获取到
this.methodCache.put(cacheKey, cached);
}
return cached;
}
public List<Object> getInterceptorsAndDynamicInterceptionAdvice(
Advised config, Method method, @Nullable Class<?> targetClass) {
// This is somewhat tricky... We have to process introductions first,
// but we need to preserve order in the ultimate list.
AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance();
Advisor[] advisors = config.getAdvisors();
List<Object> interceptorList = new ArrayList<>(advisors.length);
Class<?> actualClass = (targetClass != null ? targetClass : method.getDeclaringClass());
Boolean hasIntroductions = null;
//循环所有的advisors
for (Advisor advisor : advisors) {
//InstantiationModelAwarePointcutAdvisorImpl实现了PointcutAdvisor接口
if (advisor instanceof PointcutAdvisor) {
// Add it conditionally.
PointcutAdvisor pointcutAdvisor = (PointcutAdvisor) advisor;
//先调用ClassFilter的matches方法
if (config.isPreFiltered() || pointcutAdvisor.getPointcut().getClassFilter().matches(actualClass)) {
//再调用MethodMatcher的matches方法
MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher();
boolean match;
//引介类型的MethodMatcher
if (mm instanceof IntroductionAwareMethodMatcher) {
if (hasIntroductions == null) {
hasIntroductions = hasMatchingIntroductions(advisors, actualClass);
}
match = ((IntroductionAwareMethodMatcher) mm).matches(method, actualClass, hasIntroductions);
}
//非引介类型
else {
match = mm.matches(method, actualClass);
}
//匹配成功
if (match) {
//将advice包装为MethodInterceptor返回
MethodInterceptor[] interceptors = registry.getInterceptors(advisor);
//如果MethodMatcher的isRuntime返回true(可以自己实现MethodMatcher接口,重写isRuntime,返回为true,可以不只匹配到方法级别判断是否拦截,还可以匹配到参数内容判断是否拦截)
if (mm.isRuntime()) {
// Creating a new object instance in the getInterceptors() method
// isn't a problem as we normally cache created chains.
//包装为InterceptorAndDynamicMethodMatcher对象
for (MethodInterceptor interceptor : interceptors) {
interceptorList.add(new InterceptorAndDynamicMethodMatcher(interceptor, mm));
}
}
else {
interceptorList.addAll(Arrays.asList(interceptors));
}
}
}
}
//引介类型的advisor,只做ClassFilter匹配。
else if (advisor instanceof IntroductionAdvisor) {
IntroductionAdvisor ia = (IntroductionAdvisor) advisor;
if (config.isPreFiltered() || ia.getClassFilter().matches(actualClass)) {
Interceptor[] interceptors = registry.getInterceptors(advisor);
interceptorList.addAll(Arrays.asList(interceptors));
}
}
else {
Interceptor[] interceptors = registry.getInterceptors(advisor);
interceptorList.addAll(Arrays.asList(interceptors));
}
}
return interceptorList;
}
public MethodInterceptor[] getInterceptors(Advisor advisor) throws UnknownAdviceTypeException {
List<MethodInterceptor> interceptors = new ArrayList<>(3);
Advice advice = advisor.getAdvice();
//如果advice实现了MethodInterceptor
if (advice instanceof MethodInterceptor) {
interceptors.add((MethodInterceptor) advice);
}
//adapters 包含 MethodBeforeAdviceAdapter AfterReturningAdviceAdapter ThrowsAdviceAdapter
for (AdvisorAdapter adapter : this.adapters) {
//判断advice是否实现 MethodBeforeAdvice AfterReturningAdvice ThrowsAdvice接口
if (adapter.supportsAdvice(advice)) {
//将advice封装为 MethodBeforeAdviceInterceptor AfterReturningAdviceInterceptor ThrowsAdviceInterceptor返回
interceptors.add(adapter.getInterceptor(advisor));
}
}
if (interceptors.isEmpty()) {
throw new UnknownAdviceTypeException(advisor.getAdvice());
}
return interceptors.toArray(new MethodInterceptor[0]);
}
public Object proceed() throws Throwable {
//proceed方法会被多次调用,知道调用完所有的方法拦截链的方法,最后调用目标方法
// We start with an index of -1 and increment early.
//currentInterceptorIndex 初始为-1
//currentInterceptorIndex 等于interceptorsAndDynamicMethodMatchers方法拦截链的大小-1
//也就是,方法拦截链的方法已经全部调用到了
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
//反射调用目标方法
return invokeJoinpoint();
}
//++this.currentInterceptorIndex
//根据下标拿到方法拦截链里的方法
Object interceptorOrInterceptionAdvice =
this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
//如果是InterceptorAndDynamicMethodMatcher类型
if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
// Evaluate dynamic method matcher here: static part will already have
// been evaluated and found to match.
InterceptorAndDynamicMethodMatcher dm =
(InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
Class<?> targetClass = (this.targetClass != null ? this.targetClass : this.method.getDeclaringClass());
//this.arguments (目标方法的参数)控制更细粒度的拦截
if (dm.methodMatcher.matches(this.method, targetClass, this.arguments)) {
//调用拦截方法
return dm.interceptor.invoke(this);
}
else {
// Dynamic matching failed.
// Skip this interceptor and invoke the next in the chain.
//递归调用proceed方法,执行其他拦截方法
return proceed();
}
}
else {
// It's an interceptor, so we just invoke it: The pointcut will have
// been evaluated statically before this object was constructed.
//调用拦截方法
return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
}
}
来看看常用的几个注解生成的拦截逻辑
public class AspectJAroundAdvice extends AbstractAspectJAdvice implements MethodInterceptor, Serializable {
public AspectJAroundAdvice(
Method aspectJAroundAdviceMethod, AspectJExpressionPointcut pointcut, AspectInstanceFactory aif) {
super(aspectJAroundAdviceMethod, pointcut, aif);
}
@Override
public boolean isBeforeAdvice() {
return false;
}
@Override
public boolean isAfterAdvice() {
return false;
}
@Override
protected boolean supportsProceedingJoinPoint() {
return true;
}
@Override
public Object invoke(MethodInvocation mi) throws Throwable {
if (!(mi instanceof ProxyMethodInvocation)) {
throw new IllegalStateException("MethodInvocation is not a Spring ProxyMethodInvocation: " + mi);
}
ProxyMethodInvocation pmi = (ProxyMethodInvocation) mi;
//将MethodInvocation封装到ProceedingJoinPoint 中
ProceedingJoinPoint pjp = lazyGetProceedingJoinPoint(pmi);
JoinPointMatch jpm = getJoinPointMatch(pmi);
//反射调用拦截方法,这里ProceedingJoinPoint参数参入给了拦截方法,自己手动调用proceed方法,完成全部调用。
return invokeAdviceMethod(pjp, jpm, null, null);
}
/**
* Return the ProceedingJoinPoint for the current invocation,
* instantiating it lazily if it hasn't been bound to the thread already.
* @param rmi the current Spring AOP ReflectiveMethodInvocation,
* which we'll use for attribute binding
* @return the ProceedingJoinPoint to make available to advice methods
*/
protected ProceedingJoinPoint lazyGetProceedingJoinPoint(ProxyMethodInvocation rmi) {
return new MethodInvocationProceedingJoinPoint(rmi);
}
}
public class MethodBeforeAdviceInterceptor implements MethodInterceptor, BeforeAdvice, Serializable {
private final MethodBeforeAdvice advice;
/**
* Create a new MethodBeforeAdviceInterceptor for the given advice.
* @param advice the MethodBeforeAdvice to wrap
*/
public MethodBeforeAdviceInterceptor(MethodBeforeAdvice advice) {
Assert.notNull(advice, "Advice must not be null");
this.advice = advice;
}
//调用目标方法之前
@Override
public Object invoke(MethodInvocation mi) throws Throwable {
//反射调用before方法
this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis());
//递归调用proceed方法,执行其他的拦截方法
return mi.proceed();
}
}
public class AspectJAfterAdvice extends AbstractAspectJAdvice
implements MethodInterceptor, AfterAdvice, Serializable {
public AspectJAfterAdvice(
Method aspectJBeforeAdviceMethod, AspectJExpressionPointcut pointcut, AspectInstanceFactory aif) {
super(aspectJBeforeAdviceMethod, pointcut, aif);
}
@Override
public Object invoke(MethodInvocation mi) throws Throwable {
try {
//递归调用proceed方法,执行其他拦截器方法
return mi.proceed();
}
finally {
//反射执行拦截方法
invokeAdviceMethod(getJoinPointMatch(), null, null);
}
}
@Override
public boolean isBeforeAdvice() {
return false;
}
@Override
public boolean isAfterAdvice() {
return true;
}
}
public class AfterReturningAdviceInterceptor implements MethodInterceptor, AfterAdvice, Serializable {
private final AfterReturningAdvice advice;
/**
* Create a new AfterReturningAdviceInterceptor for the given advice.
* @param advice the AfterReturningAdvice to wrap
*/
public AfterReturningAdviceInterceptor(AfterReturningAdvice advice) {
Assert.notNull(advice, "Advice must not be null");
this.advice = advice;
}
@Override
public Object invoke(MethodInvocation mi) throws Throwable {
//递归调用proceed方法,执行其他的拦截方法,拿到返回值
Object retVal = mi.proceed();
//调用拦截方法
this.advice.afterReturning(retVal, mi.getMethod(), mi.getArguments(), mi.getThis());
return retVal;
}
}
public class AspectJAfterThrowingAdvice extends AbstractAspectJAdvice
implements MethodInterceptor, AfterAdvice, Serializable {
public AspectJAfterThrowingAdvice(
Method aspectJBeforeAdviceMethod, AspectJExpressionPointcut pointcut, AspectInstanceFactory aif) {
super(aspectJBeforeAdviceMethod, pointcut, aif);
}
@Override
public boolean isBeforeAdvice() {
return false;
}
@Override
public boolean isAfterAdvice() {
return true;
}
@Override
public void setThrowingName(String name) {
setThrowingNameNoCheck(name);
}
@Override
public Object invoke(MethodInvocation mi) throws Throwable {
try {
//递归调用proceed方法,执行其他的拦截方法,
return mi.proceed();
}
catch (Throwable ex) {
if (shouldInvokeOnThrowing(ex)) {
//执行拦截方法
invokeAdviceMethod(getJoinPointMatch(), null, ex);
}
throw ex;
}
}
/**
* In AspectJ semantics, after throwing advice that specifies a throwing clause
* is only invoked if the thrown exception is a subtype of the given throwing type.
*/
private boolean shouldInvokeOnThrowing(Throwable ex) {
return getDiscoveredThrowingType().isAssignableFrom(ex.getClass());
}
}
到此,aop的主要流程就解析完毕了。