??????????Spring AOP
????????????????????????????????Spring AOP??
??????????????xml????????У??????????????
????1.        ????ProxyFactoryBean???????????advisors?? advice?? target??
????2.        ????AutoProxyCreator?????????£????????????????????bean????????????л?????????????????
????3.        ???<aop:config>??????
????4.        ???<aop: aspectj-autoproxy>??????????AspectJ???????????????????
???????????????ProxyFactory????????????Spring AOP?????ProxyFactory???????????????target???? advisor??????????????? getProxy()????????????????
???????????????????google. ???????
????Spring AOP????????????
????Spring??????????????????????: JDKProxy??Cglib?????????????????????AopProxyFactory????AdvisedSupport????????????????????????????????????????????JDK???????????????????Cglib?????????????????????о????Spring??????JDK???????????????????????????JdkDynamicAopProxy??????У????????????
????/**
????* <ol>
????* <li>?????????????????????Advised???????????????????SpringProxy?? Advised(opaque=false)
????* <li>???????????????????ж??? equals????hashcode????
????* <li>????Proxy.newProxyInstance???????????
????* </ol>
????*/
????public Object getProxy(ClassLoader classLoader) {
????if (logger.isDebugEnabled()) {
????logger.debug("Creating JDK dynamic proxy: target source is " +this.advised.getTargetSource());
????}
????Class[] proxiedInterfaces =AopProxyUtils.completeProxiedInterfaces(this.advised);
????findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
????return Proxy.newProxyInstance(classLoader?? proxiedInterfaces?? this);
????}
??????????????????????????????д???????????????
??????????????????????????????????????????????
???????????InvocationHandler??JDK????????????????????????????????????е?InvocationHandler.invoke()???????????JdkDynamicAopProxy?????????????????????????????InvocationHandler????????????????????????????invoke()?????????忴??Spring AOP??????????????
publicObject invoke(Object proxy?? Method method?? Object[] args) throwsThrowable {
MethodInvocation invocation = null;
Object oldProxy = null;
boolean setProxyContext = false;
TargetSource targetSource = this.advised.targetSource;
Class targetClass = null;
Object target = null;
try {
//eqauls()??????????????δ???????
if (!this.equalsDefined && AopUtils.isEqualsMethod(method)){
return (equals(args[0])? Boolean.TRUE : Boolean.FALSE);
}
//hashCode()??????????????δ???????
if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)){
return newInteger(hashCode());
}
//Advised???????丸????ж??????????????????????????
if (!this.advised.opaque &&method.getDeclaringClass().isInterface()
&&method.getDeclaringClass().isAssignableFrom(Advised.class)) {
// Service invocations onProxyConfig with the proxy config...
return AopUtils.invokeJoinpointUsingReflection(this.advised??method?? args);
}
Object retVal = null;
if (this.advised.exposeProxy) {
// Make invocation available ifnecessary.
oldProxy = AopContext.setCurrentProxy(proxy);
setProxyContext = true;
}
//????????????
target = targetSource.getTarget();
if (target != null) {
targetClass = target.getClass();
}
//???????????????????Interceptor?б?
List chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method??targetClass);
//?????п????????????????(Interceptor)????????????? method.invoke(target?? args)
if (chain.isEmpty()) {
retVal = AopUtils.invokeJoinpointUsingReflection(target??method?? args);
} else {
//????MethodInvocation
invocation = newReflectiveMethodInvocation(proxy?? target?? method?? args?? targetClass?? chain);
retVal = invocation.proceed();
}
// Massage return value if necessary.
if (retVal != null && retVal == target &&method.getReturnType().isInstance(proxy)
&&!RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {
// Special case: it returned"this" and the return type of the method
// is type-compatible. Notethat we can't help if the target sets
// a reference to itself inanother returned object.
retVal = proxy;
}
return retVal;
} finally {
if (target != null && !targetSource.isStatic()) {
// Must have come fromTargetSource.
targetSource.releaseTarget(target);
}
if (setProxyContext) {
// Restore old proxy.
AopContext.setCurrentProxy(oldProxy);
}
}
}