springAOP之framework包的解讀(三)
阿新 • • 發佈:2019-01-26
抽象類 AopProxyUtils
package org.springframework.aop.framework;
import java.util.Arrays;
import org.springframework.aop.SpringProxy;
import org.springframework.aop.TargetClassAware;
import org.springframework.aop.TargetSource;
import org.springframework.aop.support.AopUtils;
import org.springframework.aop.target.SingletonTargetSource;
import org.springframework.util.Assert;
/**
* AOP代理工廠的工具方法。主要是AOP框架內部使用。
* 檢視AopUtils,一系列通知的AOP工具類方法,不依賴於AOP框架內部。
*/
public abstract class AopProxyUtils {
/**
* 定義給定bean例項的最終目標,不僅貫穿低級別的代理,也包括了任意數量內嵌的代理,對於單例目標,無其他影響
* @param candidate 檢查的例項(可能為aop代理)
* @return 目標類(或者給定的類作為後備),不為空
*/
public static Class<?> ultimateTargetClass(Object candidate) {
Assert.notNull(candidate, "Candidate object must not be null");
Object current = candidate;
Class<?> result = null;
while (current instanceof TargetClassAware) {
result = ((TargetClassAware) current).getTargetClass();
Object nested = null ;
if (current instanceof Advised) {
TargetSource targetSource = ((Advised) current).getTargetSource();
if (targetSource instanceof SingletonTargetSource) {
nested = ((SingletonTargetSource) targetSource).getTarget();
}
}
current = nested;
}
if (result == null) {
result = (AopUtils.isCglibProxy(candidate) ? candidate.getClass().getSuperclass() : candidate.getClass());
}
return result;
}
/**
* 根據給定的AOP配置定義全部的代理介面。總是新增Advised介面,除非AdvisedSupport的opaque=true.
* 總是新增SpringProxy標誌介面
* @return 全部的代理介面集合
*/
public static Class<?>[] completeProxiedInterfaces(AdvisedSupport advised) {
Class<?>[] specifiedInterfaces = advised.getProxiedInterfaces();
if (specifiedInterfaces.length == 0) {
// No user-specified interfaces: check whether target class is an interface.
Class<?> targetClass = advised.getTargetClass();
if (targetClass != null && targetClass.isInterface()) {
specifiedInterfaces = new Class<?>[] {targetClass};
}
}
boolean addSpringProxy = !advised.isInterfaceProxied(SpringProxy.class);
boolean addAdvised = !advised.isOpaque() && !advised.isInterfaceProxied(Advised.class);
int nonUserIfcCount = 0;
if (addSpringProxy) {
nonUserIfcCount++;
}
if (addAdvised) {
nonUserIfcCount++;
}
Class<?>[] proxiedInterfaces = new Class<?>[specifiedInterfaces.length + nonUserIfcCount];
System.arraycopy(specifiedInterfaces, 0, proxiedInterfaces, 0, specifiedInterfaces.length);
if (addSpringProxy) {
proxiedInterfaces[specifiedInterfaces.length] = SpringProxy.class;
}
if (addAdvised) {
proxiedInterfaces[proxiedInterfaces.length - 1] = Advised.class;
}
return proxiedInterfaces;
}
/**
* 根據給定的代理實現提取使用者指定的介面,例如:所有不是Advised介面的代理實現
* @param proxy 分析的代理(通常是一個JDK動態代理)
* @return 所有使用者指定的代理實現介面,按照原先的順序,不為空。
*/
public static Class<?>[] proxiedUserInterfaces(Object proxy) {
Class<?>[] proxyInterfaces = proxy.getClass().getInterfaces();
int nonUserIfcCount = 0;
if (proxy instanceof SpringProxy) {
nonUserIfcCount++;
}
if (proxy instanceof Advised) {
nonUserIfcCount++;
}
Class<?>[] userInterfaces = new Class<?>[proxyInterfaces.length - nonUserIfcCount];
System.arraycopy(proxyInterfaces, 0, userInterfaces, 0, userInterfaces.length);
Assert.notEmpty(userInterfaces, "JDK proxy must implement one or more interfaces");
return userInterfaces;
}
/**
* 檢查AdvisedSupport物件的代理是否相等。不符合以下條件的AdvisedSupport物件不相等:介面、advisors、目標源都要相等
*/
public static boolean equalsInProxy(AdvisedSupport a, AdvisedSupport b) {
return (a == b ||
(equalsProxiedInterfaces(a, b) && equalsAdvisors(a, b) && a.getTargetSource().equals(b.getTargetSource())));
}
/**
* 檢查AdvisedSupport物件的代理介面是否相等
*/
public static boolean equalsProxiedInterfaces(AdvisedSupport a, AdvisedSupport b) {
return Arrays.equals(a.getProxiedInterfaces(), b.getProxiedInterfaces());
}
/**
* 檢查AdvisedSupport物件的顧問(advisors)是否相等
*/
public static boolean equalsAdvisors(AdvisedSupport a, AdvisedSupport b) {
return Arrays.equals(a.getAdvisors(), b.getAdvisors());
}
}
類CglibAopProxy
package org.springframework.aop.framework;
import java.io.Serializable;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.UndeclaredThrowableException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.WeakHashMap;
import org.aopalliance.aop.Advice;
import org.aopalliance.intercept.MethodInvocation;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.aop.Advisor;
import org.springframework.aop.AopInvocationException;
import org.springframework.aop.PointcutAdvisor;
import org.springframework.aop.RawTargetAccess;
import org.springframework.aop.TargetSource;
import org.springframework.aop.support.AopUtils;
import org.springframework.cglib.core.CodeGenerationException;
import org.springframework.cglib.core.SpringNamingPolicy;
import org.springframework.cglib.proxy.Callback;
import org.springframework.cglib.proxy.CallbackFilter;
import org.springframework.cglib.proxy.Dispatcher;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.Factory;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
import org.springframework.cglib.proxy.NoOp;
import org.springframework.cglib.transform.impl.UndeclaredThrowableStrategy;
import org.springframework.core.SmartClassLoader;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.ObjectUtils;
/**
* springAOP框架中基於CGLIB的AopProxy實現類
* 原先命名為Cglib2AopProxy,在spring3.2中,該類依賴於spring內部,需要重新打包CGLIB3
* 該型別的物件必須通過代理工廠獲取,根據AdvisedSupport物件的配置。該類是springAOP框架內部的,不能直接用於客戶端。
* 如果需要,DefaultAopProxyFactory會自動建立基於CGLIB的代理,例如,代理目標類。
* 當目標是執行緒安全的,那麼用該類建立的代理也是執行緒安全的。
*/
@SuppressWarnings("serial")
class CglibAopProxy implements AopProxy, Serializable {
// CGLIB回撥的陣列的索引
private static final int AOP_PROXY = 0;
private static final int INVOKE_TARGET = 1;
private static final int NO_OVERRIDE = 2;
private static final int DISPATCH_TARGET = 3;
private static final int DISPATCH_ADVISED = 4;
private static final int INVOKE_EQUALS = 5;
private static final int INVOKE_HASHCODE = 6;
/** Logger available to subclasses; static to optimize serialization */
protected final static Log logger = LogFactory.getLog(CglibAopProxy.class);
/** 保持跟蹤那些final方法已驗證的類 */
private static final Map<Class<?>, Boolean> validatedClasses = new WeakHashMap<Class<?>, Boolean>();
/** 代理的配置 */
protected final AdvisedSupport advised;
private Object[] constructorArgs;
private Class<?>[] constructorArgTypes;
/** 通知介面方法的呼叫 */
private final transient AdvisedDispatcher advisedDispatcher;
private transient Map<String, Integer> fixedInterceptorMap;
private transient int fixedInterceptorOffset;
/**
* 用給的AOP配置建立新的CglibAopProxy。
* @param config AOP配置物件
* @throws AopConfigException 當配置無效,我們丟擲提供相關資訊的異常,而不是未知的失敗
*/
public CglibAopProxy(AdvisedSupport config) throws AopConfigException {
Assert.notNull(config, "AdvisedSupport must not be null");
if (config.getAdvisors().length == 0 && config.getTargetSource() == AdvisedSupport.EMPTY_TARGET_SOURCE) {
throw new AopConfigException("No advisors and no TargetSource specified");
}
this.advised = config;
this.advisedDispatcher = new AdvisedDispatcher(this.advised);
}
/**
* 設定建立代理的構造引數
*/
public void setConstructorArguments(Object[] constructorArgs, Class<?>[] constructorArgTypes) {
if (constructorArgs == null || constructorArgTypes == null) {
throw new IllegalArgumentException("Both 'constructorArgs' and 'constructorArgTypes' need to be specified");
}
if (constructorArgs.length != constructorArgTypes.length) {
throw new IllegalArgumentException("Number of 'constructorArgs' (" + constructorArgs.length +
") must match number of 'constructorArgTypes' (" + constructorArgTypes.length + ")");
}
this.constructorArgs = constructorArgs;
this.constructorArgTypes = constructorArgTypes;
}
@Override
public Object getProxy() {
return getProxy(null);
}
@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 UndeclaredThrowableStrategy(UndeclaredThrowableException.class));
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 (Exception ex) {
// TargetSource.getTarget() failed
throw new AopConfigException("Unexpected AOP exception", ex);
}
}
protected Object createProxyClassAndInstance(Enhancer enhancer, Callback[] callbacks) {
enhancer.setInterceptDuringConstruction(false);
enhancer.setCallbacks(callbacks);
return (this.constructorArgs != null ?
enhancer.create(this.constructorArgTypes, this.constructorArgs) :
enhancer.create());
}
/**
* 建立CGLIB的增強。子類可能會重寫,可返回自定義的增強的實現
*/
protected Enhancer createEnhancer() {
return new Enhancer();
}
/**
* 提供的類是否已驗證,若沒有,驗證它。
private void validateClassIfNecessary(Class<?> proxySuperClass, ClassLoader proxyClassLoader) {
if (logger.isInfoEnabled()) {
synchronized (validatedClasses) {
if (!validatedClasses.containsKey(proxySuperClass)) {
doValidateClass(proxySuperClass, proxyClassLoader);
validatedClasses.put(proxySuperClass, Boolean.TRUE);
}
}
}
}
/**
* 檢查給定類的方法,包括類載入器的包可見方法。
*/
private void doValidateClass(Class<?> proxySuperClass, ClassLoader proxyClassLoader) {
if (!Object.class.equals(proxySuperClass)) {
Method[] methods = proxySuperClass.getDeclaredMethods();
for (Method method : methods) {
int mod = method.getModifiers();
if (!Modifier.isStatic(mod)) {
if (Modifier.isFinal(mod)) {
logger.info("Unable to proxy method [" + method + "] because it is final: " +
"All calls to this method via a proxy will NOT be routed to the target instance.");
}
else if (!Modifier.isPublic(mod) && !Modifier.isProtected(mod) && !Modifier.isPrivate(mod) &&
proxyClassLoader != null && proxySuperClass.getClassLoader() != proxyClassLoader) {
logger.info("Unable to proxy method [" + method + "] because it is package-visible " +
"across different ClassLoaders: All calls to this method via a proxy will " +
"NOT be routed to the target instance.");
}
}
}
doValidateClass(proxySuperClass.getSuperclass(), proxyClassLoader);
}
}
private Callback[] getCallbacks(Class<?> rootClass) throws Exception {
// 用於優化的引數
boolean exposeProxy = this.advised.isExposeProxy();
boolean isFrozen = this.advised.isFrozen();
boolean isStatic = this.advised.getTargetSource().isStatic();
// 選擇一個aop攔截器(用於Aopr的呼叫)
Callback aopInterceptor = new DynamicAdvisedInterceptor(this.advised);
// 選擇一個直接的目標攔截器。(未通知的呼叫,可以返回)。可能需要暴露代理
Callback targetInterceptor;
if (exposeProxy) {
targetInterceptor = isStatic ?
new StaticUnadvisedExposedInterceptor(this.advised.getTargetSource().getTarget()) :
new DynamicUnadvisedExposedInterceptor(this.advised.getTargetSource());
}
else {
targetInterceptor = isStatic ?
new StaticUnadvisedInterceptor(this.advised.getTargetSource().getTarget()) :
new DynamicUnadvisedInterceptor(this.advised.getTargetSource());
}
// 選擇一個介面的目標排程者(用於未通知的靜態目標,無法返回
Callback targetDispatcher = isStatic ?
new StaticDispatcher(this.advised.getTargetSource().getTarget()) : new SerializableNoOp();
Callback[] mainCallbacks = new Callback[]{
aopInterceptor, // for normal advice
targetInterceptor, // invoke target without considering advice, if optimized
new SerializableNoOp(), // no override for methods mapped to this
targetDispatcher, this.advisedDispatcher,
new EqualsInterceptor(this.advised),
new HashCodeInterceptor(this.advised)
};
Callback[] callbacks;
//如果目標是靜態的,且通知鏈是凍結的,我們可以直接呼叫固定鏈的目標進行優化
if (isStatic && isFrozen) {
Method[] methods = rootClass.getMethods();
Callback[] fixedCallbacks = new Callback[methods.length];
this.fixedInterceptorMap = new HashMap<String, Integer>(methods.length);
// 優化記憶體(跳過沒有通知的方法建立)
for (int x = 0; x < methods.length; x++) {
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(methods[x], rootClass);
fixedCallbacks[x] = new FixedChainStaticTargetInterceptor(
chain, this.advised.getTargetSource().getTarget(), this.advised.getTargetClass());
this.fixedInterceptorMap.put(methods[x].toString(), x);
}
// 將主要的回撥和混合的回撥複製到回撥陣列
callbacks = new Callback[mainCallbacks.length + fixedCallbacks.length];
System.arraycopy(mainCallbacks, 0, callbacks, 0, mainCallbacks.length);
System.arraycopy(fixedCallbacks, 0, callbacks, mainCallbacks.length, fixedCallbacks.length);
this.fixedInterceptorOffset = mainCallbacks.length;
}
else {
callbacks = mainCallbacks;
}
return callbacks;
}
/**
* 處理返回值。如果需要,處理返回值成為代理,為null不返回原始型別
*/
private static Object processReturnType(Object proxy, Object target, Method method, Object retVal) {
// Massage return value if necessary
if (retVal != null && retVal == target && !RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {
// Special case: it returned "this". Note that we can't help
// if the target sets a reference to itself in another returned object.
retVal = proxy;
}
Class<?> returnType = method.getReturnType();
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;
}
@Override
public boolean equals(Object other) {
return (this == other || (other instanceof CglibAopProxy &&
AopProxyUtils.equalsInProxy(this.advised, ((CglibAopProxy) other).advised)));
}
@Override
public int hashCode() {
return CglibAopProxy.class.hashCode() * 13 + this.advised.getTargetSource().hashCode();
}
/**
* 替代CGLIB的 NoOp介面
*/
public static class SerializableNoOp implements NoOp, Serializable {
}
/**
* 用於沒有通知鏈的靜態目標的方法攔截器。呼叫直接傳到目標物件。當代理需要暴露使用,不能決定方法會返回
*/
private static class StaticUnadvisedInterceptor implements MethodInterceptor, Serializable {
private final Object target;
public StaticUnadvisedInterceptor(Object target) {
this.target = target;
}
@Override
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
Object retVal = methodProxy.invoke(this.target, args);
return processReturnType(proxy, this.target, method, retVal);
}
}
/**
* 當代理需要暴露,用於沒有通知鏈的靜態目標的方法攔截器。
*/
private static class StaticUnadvisedExposedInterceptor implements MethodInterceptor, Serializable {
private final Object target;
public StaticUnadvisedExposedInterceptor(Object target) {
this.target = target;
}
@Override
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
Object oldProxy = null;
try {
oldProxy = AopContext.setCurrentProxy(proxy);
Object retVal = methodProxy.invoke(this.target, args);
return processReturnType(proxy, this.target, method, retVal);
}
finally {
AopContext.setCurrentProxy(oldProxy);
}
}
}
/**
* 該攔截器就可以呼叫的動態目標,該目標不需要建立方法呼叫或評估通知鏈。(我們知道沒有這個方法的通知)
*/
private static class DynamicUnadvisedInterceptor implements MethodInterceptor, Serializable {
private final TargetSource targetSource;
public DynamicUnadvisedInterceptor(TargetSource targetSource) {
this.targetSource = targetSource;
}
@Override
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
Object target = this.targetSource.getTarget();
try {
Object retVal = methodProxy.invoke(target, args);
return processReturnType(proxy, target, method, retVal);
}
finally {
this.targetSource.releaseTarget(target);
}
}
}
/**
* 攔截器用於無通知的動態目標,該目標代理需要暴露
*/
private static class DynamicUnadvisedExposedInterceptor implements MethodInterceptor, Serializable {
private final TargetSource targetSource;
public DynamicUnadvisedExposedInterceptor(TargetSource targetSource) {
this.targetSource = targetSource;
}
@Override
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
Object oldProxy = null;
Object target = this.targetSource.getTarget();
try {
oldProxy = AopContext.setCurrentProxy(proxy);
Object retVal = methodProxy.invoke(target, args);
return processReturnType(proxy, target, method, retVal);
}
finally {
AopContext.setCurrentProxy(oldProxy);
this.targetSource.releaseTarget(target);
}
}
}
/**
* 靜態目標的排程者。排程者比攔截器更快。當一個方法明確地不會返回"this"時使用。
*/
private static class StaticDispatcher implements Dispatcher, Serializable {
private Object target;
public StaticDispatcher(Object target) {
this.target = target;
}
@Override
public Object loadObject() {
return this.target;
}
}
/**
* 通知類的任何宣告的方法的排程者
* Dispatcher for any methods declared on the Advised class.
*/
private static class AdvisedDispatcher implements Dispatcher, Serializable {
private final AdvisedSupport advised;
public AdvisedDispatcher(AdvisedSupport advised) {
this.advised = advised;
}
@Override
public Object loadObject() throws Exception {
return this.advised;
}
}
/**
* 相等方法的攔截器,確保方法的呼叫總是用這個類處理
*/
private static class EqualsInterceptor implements MethodInterceptor, Serializable {
private final AdvisedSupport advised;
public EqualsInterceptor(AdvisedSupport advised) {
this.advised = advised;
}
@Override
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) {
Object other = args[0];
if (proxy == other) {
return true;
}
if (other instanceof Factory) {
Callback callback = ((Factory) other).getCallback(INVOKE_EQUALS);
if (!(callback instanceof EqualsInterceptor)) {
return false;
}
AdvisedSupport otherAdvised = ((EqualsInterceptor) callback).advised;
return AopProxyUtils.equalsInProxy(this.advised, otherAdvised);
}
else {
return false;
}
}
}
/**
* hashCode方法的攔截器,確保方法的呼叫總是用這個類處理
*/
private static class HashCodeInterceptor implements MethodInterceptor, Serializable {
private final AdvisedSupport advised;
public HashCodeInterceptor(AdvisedSupport advised) {
this.advised = advised;
}
@Override
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) {
return CglibAopProxy.class.hashCode() * 13 + this.advised.getTargetSource().hashCode();
}
}
/**
* 攔截器,明確的用於通知方法,在凍結的、靜態的代理物件裡
*/
private static class FixedChainStaticTargetInterceptor implements MethodInterceptor, Serializable {
private final List<Object> adviceChain;
private final Object target;
private final Class<?> targetClass;
public FixedChainStaticTargetInterceptor(List<Object> adviceChain, Object target, Class<?> targetClass) {
this.adviceChain = adviceChain;
this.target = target;
this.targetClass = targetClass;
}
@Override
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
MethodInvocation invocation = new CglibMethodInvocation(proxy, this.target, method, args,
this.targetClass, this.adviceChain, methodProxy);
// If we get here, we need to create a MethodInvocation.
Object retVal = invocation.proceed();
retVal = processReturnType(proxy, this.target, method, retVal);
return retVal;
}
}
/**
* 通用的AOP回撥。當目標是動態的或者代理沒被凍結時使用
*/
private static class DynamicAdvisedInterceptor implements MethodInterceptor, Serializable {
private final AdvisedSupport advised;
public DynamicAdvisedInterceptor(AdvisedSupport advised) {
this.advised = advised;
}
@Override
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
Object oldProxy = null;
boolean setProxyContext = false;
Class<?> targetClass = null;
Object target = null;
try {
if (this.advised.exposeProxy) {
// Make invocation available if necessary.
oldProxy = AopContext.setCurrentProxy(proxy);
setProxyContext = true;
}
// May be null. Get as late as possible to minimize the time we
// "own" the target, in case it comes from a pool...
target = getTarget();
if (target != null) {
targetClass = target.getClass();
}
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
Object retVal;
// Check whether we only have one InvokerInterceptor: that is,
// no real advice, but just reflective invocation of the target.
if (chain.isEmpty() && Modifier.isPublic(method.getModifiers())) {
// 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.
retVal = methodProxy.invoke(target, args);
}
else {
// We need to create a method invocation...
retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();
}
retVal = processReturnType(proxy, target, method, retVal);
return retVal;
}
finally {
if (target != null) {
releaseTarget(target);
}
if (setProxyContext) {
// Restore old proxy.
AopContext.setCurrentProxy(oldProxy);
}
}
}
@Override
public boolean equals(Object other) {
return (this == other ||
(other instanceof DynamicAdvisedInterceptor &&
this.advised.equals(((DynamicAdvisedInterceptor) other).advised)));
}
/**
* CGLIB uses this to drive proxy creation.
*/
@Override
public int hashCode() {
return this.advised.hashCode();
}
protected Object getTarget() throws Exception {
return this.advised.getTargetSource().getTarget();
}
protected void releaseTarget(Object target) throws Exception {
this.advised.getTargetSource().releaseTarget(target);
}
}
/**
* AOP框架方法呼叫的實現,通過aop代理
*/
private static class CglibMethodInvocation extends ReflectiveMethodInvocation {
private final MethodProxy methodProxy;
private final boolean publicMethod;
public CglibMethodInvocation(Object proxy, Object target, Method method, Object[] arguments,
Class<?> targetClass, List<Object> interceptorsAndDynamicMethodMatchers, MethodProxy methodProxy) {
super(proxy, target, method, arguments, targetClass, interceptorsAndDynamicMethodMatchers);
this.methodProxy = methodProxy;
this.publicMethod = Modifier.isPublic(method.getModifiers());
}
/**
* 提供一個臨界的效能提升,與呼叫的反射相對抗,當呼叫公開的方法時。
*/
@Override
protected Object invokeJoinpoint() throws Throwable {
if (this.publicMethod) {
return this.methodProxy.invoke(this.target, this.arguments);
}
else {
return super.invokeJoinpoint();
}
}
}
/**
* 回撥過濾
*/
private static class ProxyCallbackFilter implements CallbackFilter {
private final AdvisedSupport advised;
private final Map<String, Integer> fixedInterceptorMap;
private final int fixedInterceptorOffset;
public ProxyCallbackFilter(AdvisedSupport advised, Map<String, Integer> fixedInterceptorMap, int fixedInterceptorOffset) {
this.advised = advised;
this.fixedInterceptorMap = fixedInterceptorMap;
this.fixedInterceptorOffset = fixedInterceptorOffset;
}
/**
* CallbackFilter.accept()的實現,返回我們需要回調的下標。
* 每個代理的回撥由一系列的固定的回撥組成,這些回撥是通用的,並且對一個方法是具體的,該方法用於固定的通知鏈的靜態目標
* 回撥的使用由以下決定:
* 1.對於暴露的代理,暴露的代理,需要程式碼在方法/鏈呼叫的之前與之後執行,
* 這意味著我們必須使用DynamicAdvisedInterceptor,自從其他的攔截器能避免try/catch塊。
* 2.對於Object.finalize():方法無重寫會被使用。
* 3.對於equals():EqualsInterceptor會被使用,重新呼叫equals(),對於該代理的一個特定的處理器。
* 4.對於通知類的方法:AdvisedDispatcher會被使用,用來排程目標的直接呼叫。
* 5.對於通知方法:如果目標是靜態的,通知鏈是凍結的,那麼FixedChainStaticTargetInterceptor關於該具體的方法會用於呼叫通知鏈,
* 否則使用DyanmicAdvisedInterceptor
* 6.對於未通知的方法:可以確定該方法將不會返回this,或者ProxyFactory.getExposeProxy()返回false
* Dispatcher會被使用。對於靜態的目標,使用StaticDispatcher,對於動態的目標,使用DynamicUnadvisedInterceptor.
* 該方法有可能返回this,StaticUnadvisedInterceptor就會用於靜態的目標,DynamicUnadvisedInterceptor已經考慮到這種情況。
* </dl>
*/
@Override
public int accept(Method method) {
if (AopUtils.isFinalizeMethod(method)) {
logger.debug("Found finalize() method - using NO_OVERRIDE");
return NO_OVERRIDE;
}
if (!this.advised.isOpaque() && method.getDeclaringClass().isInterface() &&
method.getDeclaringClass().isAssignableFrom(Advised.class)) {
if (logger.isDebugEnabled()) {
logger.debug("Method is declared on Advised interface: " + method);
}
return DISPATCH_ADVISED;
}
// We must always proxy equals, to direct calls to this.
if (AopUtils.isEqualsMethod(method)) {
logger.debug("Found 'equals' method: " + method);
return INVOKE_EQUALS;
}
// We must always calculate hashCode based on the proxy.
if (AopUtils.isHashCodeMethod(method)) {
logger.debug("Found 'hashCode' method: " + method);
return INVOKE_HASHCODE;
}
Class<?> targetClass = this.advised.getTargetClass();
// Proxy is not yet available, but that shouldn't matter.
List<?> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
boolean haveAdvice = !chain.isEmpty();
boolean exposeProxy = this.advised.isExposeProxy();
boolean isStatic = this.advised.getTargetSource().isStatic();
boolean isFrozen = this.advised.isFrozen();
if (haveAdvice || !isFrozen) {
// If exposing the proxy, then AOP_PROXY must be used.
if (exposeProxy) {
if (logger.isDebugEnabled()) {
logger.debug("Must expose proxy on advised method: " + method);
}
return AOP_PROXY;
}
String key = method.toString();
// Check to see if we have fixed interceptor to serve this method.
// Else use the AOP_PROXY.
if (isStatic && isFrozen && this.fixedInterceptorMap.containsKey(key)) {
if (logger.isDebugEnabled()) {
logger.debug("Method has advice and optimisations are enabled: " + method);
}
// We know that we are optimising so we can use the
// FixedStaticChainInterceptors.
int index = this.fixedInterceptorMap.get(key);
return (index + this.fixedInterceptorOffset);
}
else {
if (logger.isDebugEnabled()) {
logger.debug("Unable to apply any optimisations to advised method: " + method);
}
return AOP_PROXY;
}
}
else {
// See if the return type of the method is outside the class hierarchy
// of the target type. If so we know it never needs to have return type
// massage and can use a dispatcher.
// If the proxy is being exposed, then must use the interceptor the