目錄
AbstractAspectJAdvisorFactory
AspectJAnnotation
ReflectiveAspectJAdvisorFactory
getAdvisors
getAdvisor
getPointcut
getAdvice
InstantiationModelAwarePointcutAdvisorImpl
ProxyFactory
TargetClassAware
ProxyConfig
Advised
AdvisedSupport
AdvisorChainFactory
DefaultAdvisorChainFactory
ProxyCreatorSupport
ProxyFactory實作
AopProxyFactory
DefaultAopProxyFactory
AopProxy
JdkDynamicAopProxy
ReflectiveMethodInvocation
ObjenesisCglibAopProxy
Proxy
上篇文章提到Advisor由AspectJAdvisorFactory 的具體實作類ReflectiveAspectJAdvisorFactory真正建立。然後由ProxyFactory使用Advisors實作代理對象的建立。
AbstractAspectJAdvisorFactory
AbstractAspectJAdvisorFactory主要提供了一些通用方法。主要主要涉及的AspectJ注解包括:
private static final Class<?>[] ASPECTJ_ANNOTATION_CLASSES = new Class<?>[] {
Pointcut.class, Around.class, Before.class, After.class, AfterReturning.class, AfterThrowing.class};
判斷是否有@Aspect注解。
@Override
public boolean isAspect(Class<?> clazz) {
return (hasAspectAnnotation(clazz) && !compiledByAjc(clazz));
}
private boolean hasAspectAnnotation(Class<?> clazz) {
return (AnnotationUtils.findAnnotation(clazz, Aspect.class) != null);
}
通過AnnotationUtils擷取注解資訊。
protected static AspectJAnnotation<?> findAspectJAnnotationOnMethod(Method method) {
for (Class<?> clazz : ASPECTJ_ANNOTATION_CLASSES) {
AspectJAnnotation<?> foundAnnotation = findAnnotation(method, (Class<Annotation>) clazz);
if (foundAnnotation != null) {
return foundAnnotation;
}
}
return null;
}
@Nullable
private static <A extends Annotation> AspectJAnnotation<A> findAnnotation(Method method, Class<A> toLookFor) {
A result = AnnotationUtils.findAnnotation(method, toLookFor);
if (result != null) {
return new AspectJAnnotation<>(result);
}
else {
return null;
}
}
AspectJAnnotation
AspectJAnnotation為AspectJ注解的包裝類。
//是什麼注解
private final A annotation;
//注解枚舉值
private final AspectJAnnotationType annotationType;
//注解表達式
private final String pointcutExpression;
//參數名稱
private final String argumentNames;
static {
annotationTypeMap.put(Pointcut.class, AspectJAnnotationType.AtPointcut);
annotationTypeMap.put(Around.class, AspectJAnnotationType.AtAround);
annotationTypeMap.put(Before.class, AspectJAnnotationType.AtBefore);
annotationTypeMap.put(After.class, AspectJAnnotationType.AtAfter);
annotationTypeMap.put(AfterReturning.class, AspectJAnnotationType.AtAfterReturning);
annotationTypeMap.put(AfterThrowing.class, AspectJAnnotationType.AtAfterThrowing);
}
ReflectiveAspectJAdvisorFactory
getAdvisors
getAdvisors
函數會擷取
@Aspect
修飾的執行個體中所有沒有被
@Pointcut
修飾的方法,然後調用
getAdvisor
函數,并且将這些方法作為參數。
@Override
public List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory) {
//擷取Aspect類
Class<?> aspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
String aspectName = aspectInstanceFactory.getAspectMetadata().getAspectName();
validate(aspectClass);
// We need to wrap the MetadataAwareAspectInstanceFactory with a decorator
// so that it will only instantiate once.
MetadataAwareAspectInstanceFactory lazySingletonAspectInstanceFactory =
new LazySingletonAspectInstanceFactoryDecorator(aspectInstanceFactory);
List<Advisor> advisors = new ArrayList<>();
//擷取被@AspectJ注釋的所有方法。
for (Method method : getAdvisorMethods(aspectClass)) {
Advisor advisor = getAdvisor(method, lazySingletonAspectInstanceFactory, advisors.size(), aspectName);
if (advisor != null) {
advisors.add(advisor);
}
}
// If it's a per target aspect, emit the dummy instantiating aspect.
if (!advisors.isEmpty() && lazySingletonAspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) {
Advisor instantiationAdvisor = new SyntheticInstantiationAdvisor(lazySingletonAspectInstanceFactory);
advisors.add(0, instantiationAdvisor);
}
// Find introduction fields.
for (Field field : aspectClass.getDeclaredFields()) {
Advisor advisor = getDeclareParentsAdvisor(field);
if (advisor != null) {
advisors.add(advisor);
}
}
return advisors;
}
沒有被@PointCut注解的,則傳回。
private List<Method> getAdvisorMethods(Class<?> aspectClass) {
final List<Method> methods = new ArrayList<>();
ReflectionUtils.doWithMethods(aspectClass, method -> {
// Exclude pointcuts
if (AnnotationUtils.getAnnotation(method, Pointcut.class) == null) {
methods.add(method);
}
}, ReflectionUtils.USER_DECLARED_METHODS);
methods.sort(METHOD_COMPARATOR);
return methods;
}
getAdvisor
生成Advisor,實際指:InstantiationModelAwarePointcutAdvisorImpl。
PointcutAdvisor
執行個體中必然有一個
Pointcut
和
Advice
執行個體。修飾在方法上的注解包括:
@Pointcut
,
@Around
,
@Before
,
@After
,
@AfterReturning
和
@AfterThrowing
,是以
InstantiationModelAwarePointcutAdvisorImpl
會依據不同的不同的注解生成不同的
Advice
通知。
public Advisor getAdvisor(Method candidateAdviceMethod, MetadataAwareAspectInstanceFactory aspectInstanceFactory,
int declarationOrderInAspect, String aspectName) {
//判斷是否一個合法的AspectJ 類
validate(aspectInstanceFactory.getAspectMetadata().getAspectClass());
// 獲得該方法上的切入點條件表達式
AspectJExpressionPointcut expressionPointcut = getPointcut(
candidateAdviceMethod, aspectInstanceFactory.getAspectMetadata().getAspectClass());
if (expressionPointcut == null) {
return null;
}
//
return new InstantiationModelAwarePointcutAdvisorImpl(expressionPointcut, candidateAdviceMethod,
this, aspectInstanceFactory, declarationOrderInAspect, aspectName);
}
getPointcut
擷取切入點表達式。
@Nullable
private AspectJExpressionPointcut getPointcut(Method candidateAdviceMethod, Class<?> candidateAspectClass) {
// 獲得該函數上@Pointcut, @Around, @Before, @After, @AfterReturning, @AfterThrowing注解的資訊
AspectJAnnotation<?> aspectJAnnotation =
AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod);
if (aspectJAnnotation == null) {
return null;
}
AspectJExpressionPointcut ajexp =
new AspectJExpressionPointcut(candidateAspectClass, new String[0], new Class<?>[0]);
// 獲得注解資訊中的切入點判斷表達式
ajexp.setExpression(aspectJAnnotation.getPointcutExpression());
if (this.beanFactory != null) {
ajexp.setBeanFactory(this.beanFactory);
}
return ajexp;
}
getAdvice
為AspectJ方法構造Advice。根據不同的Aspect注解生成不同的Advice。
public Advice getAdvice(Method candidateAdviceMethod, AspectJExpressionPointcut expressionPointcut,
MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) {
Class<?> candidateAspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
validate(candidateAspectClass);
//擷取方法上的AspectJ注解。
AspectJAnnotation<?> aspectJAnnotation =
AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod);
if (aspectJAnnotation == null) {
return null;
}
//走到此處,說明是個AspectJ方法,判斷是@AspectJ注解的
if (!isAspect(candidateAspectClass)) {
//異常
}
AbstractAspectJAdvice springAdvice;
//根據注解類型生成Advice。
switch (aspectJAnnotation.getAnnotationType()) {
case AtPointcut:
return null;
case AtAround:
springAdvice = new AspectJAroundAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
break;
case AtBefore:
springAdvice = new AspectJMethodBeforeAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
break;
case AtAfter:
springAdvice = new AspectJAfterAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
break;
case AtAfterReturning:
springAdvice = new AspectJAfterReturningAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
AfterReturning afterReturningAnnotation = (AfterReturning) aspectJAnnotation.getAnnotation();
if (StringUtils.hasText(afterReturningAnnotation.returning())) {
springAdvice.setReturningName(afterReturningAnnotation.returning());
}
break;
case AtAfterThrowing:
springAdvice = new AspectJAfterThrowingAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
AfterThrowing afterThrowingAnnotation = (AfterThrowing) aspectJAnnotation.getAnnotation();
if (StringUtils.hasText(afterThrowingAnnotation.throwing())) {
springAdvice.setThrowingName(afterThrowingAnnotation.throwing());
}
break;
default:
throw new UnsupportedOperationException(
"Unsupported advice type on method: " + candidateAdviceMethod);
}
// 配置Advice。
springAdvice.setAspectName(aspectName);
springAdvice.setDeclarationOrder(declarationOrder);
String[] argNames = this.parameterNameDiscoverer.getParameterNames(candidateAdviceMethod);
if (argNames != null) {
springAdvice.setArgumentNamesFromStringArray(argNames);
}
springAdvice.calculateArgumentBindings();
return springAdvice;
}
InstantiationModelAwarePointcutAdvisorImpl
InstantiationModelAwarePointcutAdvisorImpl的繼承結構如下圖,它本身是個Advisor,并且是個PointcutAdvisor。是對各種AspectJ 增強的封裝。
它包括以下屬性:
private static final Advice EMPTY_ADVICE = new Advice() {};
private final AspectJExpressionPointcut declaredPointcut;
//定義類型
private final Class<?> declaringClass;
//方法名
private final String methodName;
//參數類型
private final Class<?>[] parameterTypes;
//AspectJ方法
private transient Method aspectJAdviceMethod;
private final AspectJAdvisorFactory aspectJAdvisorFactory;
private final MetadataAwareAspectInstanceFactory aspectInstanceFactory;
//順序
private final int declarationOrder;
//AspectJ名稱
private final String aspectName;
//切點
private final Pointcut pointcut;
//
private final boolean lazy;
//Advice
@Nullable
private Advice instantiatedAdvice;
@Nullable
private Boolean isBeforeAdvice;
@Nullable
private Boolean isAfterAdvice;
在構造函數中,會根據參數生成Advice。調用的aspectJAdvisorFactory的getAdvice方法。見前面内容。
private Advice instantiateAdvice(AspectJExpressionPointcut pointcut) {
Advice advice = this.aspectJAdvisorFactory.getAdvice(this.aspectJAdviceMethod, pointcut,
this.aspectInstanceFactory, this.declarationOrder, this.aspectName);
return (advice != null ? advice : EMPTY_ADVICE);
}
ProxyFactory
ProxyFactory是真正建立代理對象的類,其類繼承結構如下圖:
TargetClassAware
public interface TargetClassAware {
/**代理實作後面的目标類類型,可能是一個proxy,也可能是代理配置。
*/
@Nullable
Class<?> getTargetClass();
}
ProxyConfig
上篇已介紹,主要是代理配置資訊。
Advised
封裝代理配置資訊的接口,配置包含:Interceptors 、other advice、 Advisors、proxied interfaces。
public interface Advised extends TargetClassAware {
boolean isFrozen();
/**是否代理的target class,而不是特定接口
* Are we proxying the full target class instead of specified interfaces?
*/
boolean isProxyTargetClass();
Class<?>[] getProxiedInterfaces();
boolean isInterfaceProxied(Class<?> intf);
void setTargetSource(TargetSource targetSource);
TargetSource getTargetSource();
void setExposeProxy(boolean exposeProxy);
boolean isExposeProxy();
void setPreFiltered(boolean preFiltered);
boolean isPreFiltered();
/*Advisor相關*/
Advisor[] getAdvisors();
void addAdvisor(Advisor advisor) throws AopConfigException;
void addAdvisor(int pos, Advisor advisor) throws AopConfigException;
boolean removeAdvisor(Advisor advisor);
void removeAdvisor(int index) throws AopConfigException;
int indexOf(Advisor advisor);
boolean replaceAdvisor(Advisor a, Advisor b) throws AopConfigException;
/*Advice相關*/
void addAdvice(Advice advice) throws AopConfigException;
void addAdvice(int pos, Advice advice) throws AopConfigException;
boolean removeAdvice(Advice advice);
int indexOf(Advice advice);
String toProxyConfigString();
}
AdvisedSupport
Advised的一個具體實作,就是怎麼存、取屬性值。引入了AdvisorChainFactory 。
AdvisorChainFactory advisorChainFactory = new DefaultAdvisorChainFactory();
AdvisorChainFactory
AdvisorChainFactory主要實作Advisor鍊。為指定方法構造Advisor鍊。預設實作為:DefaultAdvisorChainFactory。
public interface AdvisorChainFactory {
List<Object> getInterceptorsAndDynamicInterceptionAdvice(Advised config, Method method, @Nullable Class<?> targetClass);
}
DefaultAdvisorChainFactory
傳回方法的所有Advisor,根據Advisor類型來決定是否比對方法。
@Override
public List<Object> getInterceptorsAndDynamicInterceptionAdvice(
Advised config, Method method, @Nullable Class<?> targetClass) {
AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance();
//擷取所有Advisor。
Advisor[] advisors = config.getAdvisors();
List<Object> interceptorList = new ArrayList<>(advisors.length);
//目标類實際類型。
Class<?> actualClass = (targetClass != null ? targetClass : method.getDeclaringClass());
Boolean hasIntroductions = null;
//循環每個Advisor。
for (Advisor advisor : advisors) {
//切點類型Advisor。
if (advisor instanceof PointcutAdvisor) {
PointcutAdvisor pointcutAdvisor = (PointcutAdvisor) advisor;
//類類型是否比對。
if (config.isPreFiltered() || pointcutAdvisor.getPointcut().getClassFilter().matches(actualClass)) {
MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher();
boolean match;
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) {
MethodInterceptor[] interceptors = registry.getInterceptors(advisor);
//動态比對。
if (mm.isRuntime()) {
for (MethodInterceptor interceptor : interceptors) {
interceptorList.add(new InterceptorAndDynamicMethodMatcher(interceptor, mm));
}
}
else {
//靜态比對。
interceptorList.addAll(Arrays.asList(interceptors));
}
}
}
}
//引介類型Advisor。
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));
}
}
//其他Advisor,預設表示比對。
else {
Interceptor[] interceptors = registry.getInterceptors(advisor);
interceptorList.addAll(Arrays.asList(interceptors));
}
}
return interceptorList;
}
ProxyCreatorSupport
代理工廠的實作的基本支援類,引入了AopProxyFactory (DefaultAopProxyFactory)。并且通過AopProxyFactory.createAopProxy()建立AopProxy執行個體。
private AopProxyFactory aopProxyFactory;
public ProxyCreatorSupport() {
this.aopProxyFactory = new DefaultAopProxyFactory();
}
protected final synchronized AopProxy createAopProxy() {
if (!this.active) {
activate();
}
return getAopProxyFactory().createAopProxy(this);
}
ProxyFactory實作
ProxyFactory主要提供了些操作Advised屬性的方法,例如增加接口,設定TargetSource等,内部調用AopProxy.getProxy()方法生成代理執行個體。
AopProxyFactory
根據代理配置資訊,生成Aop代理。
public interface AopProxyFactory {
AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException;
}
DefaultAopProxyFactory
根據代理配置資訊,決定是使用JDK動态代理,還是cglib代理。
@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);
}
}
AopProxy
AopProxy是真正産生代理執行個體的類。包括JDK動态代理實作和cglib實作。
public interface AopProxy {
Object getProxy();
Object getProxy(@Nullable ClassLoader classLoader);
}
JdkDynamicAopProxy
JdkDynamicAopProxy又實作了InvocationHandler接口,使用java.lang.reflect.Proxy 通過反射來構造執行個體。JdkDynamicAopProxy的invoke方法中,如果有Advisor,則會生成一個ReflectiveMethodInvocation對象,執行增強。
@Override
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);
}
@Override
@Nullable
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 {
//target自身沒有實作equal方法,
if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
return equals(args[0]);
}
//target自身沒有實作hashCode方法,
else if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
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;
}
//擷取最後一個Target,targetSource的target會變化。
target = targetSource.getTarget();
Class<?> targetClass = (target != null ? target.getClass() : null);
//擷取方法的攔截器鍊。
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
//如果沒有任何advice,直接調用 target的方法。
if (chain.isEmpty()) {
Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
}
else {
如果有advice,則構造MethodInvocation,調用proceed。
MethodInvocation invocation =
new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, 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())) {
//如果方法傳回結果為this,則傳回proxy。
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()) {
// 如果可能釋放target。
targetSource.releaseTarget(target);
}
if (setProxyContext) {
// Restore old proxy.
AopContext.setCurrentProxy(oldProxy);
}
}
}
ReflectiveMethodInvocation
屬性:
protected ReflectiveMethodInvocation(
Object proxy, @Nullable Object target, Method method, @Nullable Object[] arguments,
@Nullable Class<?> targetClass, List<Object> interceptorsAndDynamicMethodMatchers) {
this.proxy = proxy;
this.target = target;
this.targetClass = targetClass;
this.method = BridgeMethodResolver.findBridgedMethod(method);
this.arguments = AopProxyUtils.adaptArgumentsIfNecessary(method, arguments);
this.interceptorsAndDynamicMethodMatchers = interceptorsAndDynamicMethodMatchers;
}
proceed
@Override
@Nullable
public Object proceed() throws Throwable {
// 最後一個攔截器,則調用invokeJoinpoint,使用代理的方法。
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
return invokeJoinpoint();
}
//循環攔截器。
Object interceptorOrInterceptionAdvice =
this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
//動态攔截器
if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
InterceptorAndDynamicMethodMatcher dm =
(InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
Class<?> targetClass = (this.targetClass != null ? this.targetClass : this.method.getDeclaringClass());
//比對,則傳回攔截器的調用。
if (dm.methodMatcher.matches(this.method, targetClass, this.arguments)) {
return dm.interceptor.invoke(this);
}
else {
//不比對,則下一個。
return proceed();
}
}
else {
//靜态攔截器,直接調用增強方法。
return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
}
}
ObjenesisCglibAopProxy
不細談,具體的了解cglib相關知識。
Proxy
Proxy是反射包中的實作類。主要方法是newProxyInstance。
public static Object newProxyInstance(ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h)
throws IllegalArgumentException
{
Objects.requireNonNull(h);
final Class<?>[] intfs = interfaces.clone();
... ...
/*
* 調用native方法生成代理類.
*/
Class<?> cl = getProxyClass0(loader, intfs);
try {
if (sm != null) {
checkNewProxyPermission(Reflection.getCallerClass(), cl);
}
//擷取代理類的構造函數。InvocationHandler.class
final Constructor<?> cons = cl.getConstructor(constructorParams);
... ...
//執行個體化。
return cons.newInstance(new Object[]{h});
} catch (IllegalAccessException|InstantiationException e) {
... ...
}
}