spring源码学习之AOP(二)
接着上一篇中的内容!
3、创建代理
在获取了所有的bean对应的增强器之后,便可以进行代理的创建了
org.springframework.aop.framework.autoproxy包下的AbstractAutoProxyCreator类中的createProxy方法
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 = new ProxyFactory();
// 获取当前类中的相关属性
proxyFactory.copyFrom(this); // 决定对于给定的bean是否应该使用targetClass属性,而不是他的接口代理,检查proxyTargetClass设置以及preserveTargetClass属性
if (!proxyFactory.isProxyTargetClass()) {
if (shouldProxyTargetClass(beanClass, beanName)) {
proxyFactory.setProxyTargetClass(true);
}
else {
// 添加代理接口
evaluateProxyInterfaces(beanClass, proxyFactory);
}
} Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
// 加入增强器
proxyFactory.addAdvisors(advisors);
// 设置要代理的类
proxyFactory.setTargetSource(targetSource);
// 定制代理
customizeProxyFactory(proxyFactory);
// 用来控制代理工厂被配置之后,是否还允许修改通知
// 缺省值为false(即在代理被设置之后,不允许修改代理的配置)
proxyFactory.setFrozen(this.freezeProxy);
if (advisorsPreFiltered()) {
proxyFactory.setPreFiltered(true);
} return proxyFactory.getProxy(getProxyClassLoader());
}
对于代理类的创建和处理,spring委托给ProxyFactory处理,而此函数中主要是对ProxyFactory的初始化操作,进而对真正的创建代理做准备,这些初始化操作如下:
(1)获取当前类中的属性
(2)添加代理接口
(3)封装advisor并加入到ProxyFactory中
(4)设置要代理的类
(5)当然spring中还为子类提供了定制的函数customizeProxyFactory,子类在此函数中对ProxyFactory进一步封装
(6)进行获取代理操作
其中封装advisor并加入到ProxyFactory中以及创建代理是两个相对繁琐的过程,可以通过ProxyFactory提供的addAdvisor方法直接将增强器置入代理创建工厂中,
但是将拦截器封装成增强器还是需要一定的逻辑的
org.springframework.aop.framework.autoproxy包下的AbstractAutoProxyCreator类
 protected Advisor[] buildAdvisors(@Nullable String beanName, @Nullable Object[] specificInterceptors) {
     // Handle prototypes correctly...
     // 解析注册的所有的InterceptorName
     Advisor[] commonInterceptors = resolveInterceptorNames();
     List<Object> allInterceptors = new ArrayList<>();
     if (specificInterceptors != null) {
         // 加入拦截器
         allInterceptors.addAll(Arrays.asList(specificInterceptors));
         if (commonInterceptors.length > 0) {
             if (this.applyCommonInterceptorsFirst) {
                 allInterceptors.addAll(0, Arrays.asList(commonInterceptors));
             }
             else {
                 allInterceptors.addAll(Arrays.asList(commonInterceptors));
             }
         }
     }
     if (logger.isDebugEnabled()) {
         int nrOfCommonInterceptors = commonInterceptors.length;
         int nrOfSpecificInterceptors = (specificInterceptors != null ? specificInterceptors.length : 0);
         logger.debug("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++) {
         // 拦截器进行封装转化为Advisor
         advisors[i] = this.advisorAdapterRegistry.wrap(allInterceptors.get(i));
     }
     return advisors;
 }
wrap方法在org.springframework.aop.framework.adapter.DefaultAdvisorAdapterRegistry类中重写
@Override
public Advisor wrap(Object adviceObject) throws UnknownAdviceTypeException {
// 如果要封装的对象本身就是Advisor类型的,无需做过多的处理
if (adviceObject instanceof Advisor) {
return (Advisor) adviceObject;
}
// 因为此封装方法只对Advisor和Advice两种类型有效,不是的话,就抛出异常
if (!(adviceObject instanceof Advice)) {
throw new UnknownAdviceTypeException(adviceObject);
}
Advice advice = (Advice) adviceObject;
if (advice instanceof MethodInterceptor) {
// So well-known it doesn't even need an adapter.
// 如果是MethodInterceptor类型,则使用DefaultPointcutAdvisor类封装
return new DefaultPointcutAdvisor(advice);
}
// 如果存在Advisor的适配器那么也同样需要进行封装
for (AdvisorAdapter adapter : this.adapters) {
// Check that it is supported.
if (adapter.supportsAdvice(advice)) {
return new DefaultPointcutAdvisor(advice);
}
}
throw new UnknownAdviceTypeException(advice);
}
由于spring中涉及过多的拦截器、增强器、增强方法等方式来对逻辑进行增强,所以非常有必要统一封装成Advisor来进行代理的创建,完成了增强的封装过程,那么解析的
最重要的一步就是代理的创建和获取了
(1)创建代理
// org.springframework.aop.framework.ProxyFactory类中的
public Object getProxy(@Nullable ClassLoader classLoader) {
return createAopProxy().getProxy(classLoader);
} protected final synchronized AopProxy createAopProxy() {
if (!this.active) {
activate();
}
// 创建代理
return getAopProxyFactory().createAopProxy(this);
}
// org.springframework.aop.framework.DefaultAopProxyFactory类对createAopProxy()方法进行了重写 @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);
}
}
从源码可以看出,spring中存在着两种代理JdkDynamicAopProxy和ObjenesisCglibAopProxy两种
看一下createAopProxy方法中影响这spring使用何种代理的判断条件,也就是if中的条件
(1)isOptimize
用来控制通过CGLIB创建的代理是否使用激进的优化策略。除非了解AOP代理如何处理优化,否则不推荐使用这个设置,目前这个属性仅用于CGLIB代理,JDK代理无效
(2)isProxyTargetClass
这个属性为true时,目标类本身被代理而不是目标类的接口,如果这个属性设置为true,CGLIB代理将被创建,设置方式<aop:aspectj-autoproxy proxy-target-class="true" />
(3)hasNoUserSuppliedProxyInterfaces
是否存在代理接口
JDK代理与CGLIB代理的总结:
  如果目标对象实现了接口,默认情况下会使用JDK动态代理实现AOP
  如果目标对象实现了接口,可以强制使用CGLIB实现AOP
  如果目标对象没有实现接口,必须采用CGLIB库,spring会自动在JDK动态代理和CGLIB代理之前切换
(2)获取代理
JDK代理使用案例
// 创建业务接口,业务对外提供的接口,包含着业务可以对外提供的功能
public interface UserService{ // 目标方法
public abstract void add();
} // 创建业务接口实现类
public class UserServiceImpl implements UserService { public void add(){
System.out.println("---------add()----------");
}
} // 创建自定义的InvocationHandler,用于对接口提供的方法进行增强
public class MyInvocationHandler implements InvocationHandler{
private Object target; public MyInvocationHandler(Object target){
super();
this.target = target;
} // 执行目标对象方法
public Object invoke(Obejct proxy, Method method, Object[] args) throws Throwable {
System.out.println("---------before()----------");
Obejct result = method.invoke(target, args);
System.out.println("---------after()----------");
return result;
} // 获取目标对象的代理对象
public Object getProxy(){
return Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(),target.getClass().getInterfaces(),this);
}
} // 测试类
public class ProxyTest{ @Test
public void testProxy(){
UserService userService = new UserServiceImpl();
// 实例化InvocationHandler
MyInvocationHandler invocationHandler = new MyInvocationHandler(userService);
// 根据目标对象生成代理对象
UserService proxy = (UserService) invocationHandler.getProxy();
// 执行代理对象方法
proxy.add();
}
}
用起来很简单,这其实就是AOP的简单的实现,在目标方法的执行之前和执行之后进行了增强,spring的AOP实现其实也就是用了Proxy、InvocationHandler这两个类
再次回顾一下使用JDK代理的方式,在整个创建过程中,对于InvocationHandler的创建是最为核心的,在自定义的InvocationHandler中需要重写三个函数
	  构造函数,将代理对象传入
	  invoke方法,此方法中实现了AOP增强的所有逻辑
	  getProxy方法
JdkDynamicAopProxy的getProxy()源码:
org.springframework.aop.framework.JdkDynamicAopProxy类中
@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);
}
JDKProxy的使用关键是创建自定义的InvocationHandler,而InvocationHandler中包含了需要覆盖的函数getProxy,并且JdkDynamicAopProxy还实现了InvocationHandler接口,
因此,在该类中肯定存在一个重写的invoke方法,完成AOP的核心逻辑:invoke函数源码:
@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 {
// equals方法的处理
if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
// The target does not implement the equals(Object) method itself.
return equals(args[0]);
}
// hash方法的处理
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); // 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 {
// We need to create a method invocation...
// 将拦截器封装在ReflectiveMethodInvocation以便于其使用proceed进行链接表用拦截器
MethodInvocation 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);
}
}
}
上面的方法中最主要的就是创建了一个拦截器链,并使用ReflectiveMethodInvocation类进行了封装,而在ReflectiveMethodInvocation的proceed中实现了拦截器的逐一
调用,那继续看proceed方法的源码,如何实现前置增强与后置增强的:
此方法是在org.springframework.aop.framework.ReflectiveMethodInvocation类中进行重写的:
@Override
@Nullable
public Object proceed() throws Throwable {
// We start with an index of -1 and increment early.
// 执行完所有增强后,执行切点方法
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
return invokeJoinpoint();
} // 获取下一个要执行的拦截器
Object interceptorOrInterceptionAdvice =
this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
// Evaluate dynamic method matcher here: static part will already have
// been evaluated and found to match.
// 动态匹配
InterceptorAndDynamicMethodMatcher dm =
(InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
if (dm.methodMatcher.matches(this.method, this.targetClass, this.arguments)) {
return dm.interceptor.invoke(this);
}
else {
// Dynamic matching failed.
// Skip this interceptor and invoke the next in the chain.
// 不匹配则不执行拦截器
return proceed();
}
}
else {
// It's an interceptor, so we just invoke it: The pointcut will have
// been evaluated statically before this object was constructed.
/**
* 普通拦截器则直接调用拦截器
* 例如:
* MethodBeforeAdviceIntercepter
* AspectJAroundAdvice
* AspectJAfterAdvice
*/
// 将this作为参数传递以保证当前实例中调用链的执行
return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
}
}
CGLIB代理使用案例
CGLIB是一个强大的高性能的代码生成包。CGLIB包的底层是通过使用一个小而快的字节码处理框架ASM,来转换字节码并生成新的类。
看如何使用CGLIB
需要导入外部net.sf.cglib.proxy包
 public class EnhancerDemo{
     public static void main(String[] args){
         Enhancer enhancer = new Enhancer();
         enhancer.setSupperclass(EnhancerDemo.class);
         enhancer.setCallback(new MethodInterceptorImpl());
         EnhancerDemo demo = (EnhancerDemo) enhancer.create();
         demo.test();
         System.out.println(demo);
     }
     public void test(){
         System.out.println("EnhancerDemo test()");
     }
     public static class MethodInterceptorImpl implements MethodInterceptor{
         @Override
         public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy){
             System.out.println("Before invoke" + method);
             Object result = proxy.invokeSuper(obj, args);
             System.out.println("After invoke" + method);
             return result;
         }
     }
 }
完成CGLIB代理的类是委托给Cglib2AopProxy类去实现的,Cglib2AopProxy的入口应该是getProxy,也就是说Cglib2AopProxy类的getProxy中实现了Enhancer的创建和接口封装
我就有点搞不懂了,作者从哪里搞出来一个Cglib2AopProxy,明明是CglibAopProxy,看getProxy的源码
org.springframework.aop.framework.CglibAopProxy类中的getProxy
@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.
// 验证Class
validateClassIfNecessary(proxySuperClass, classLoader); // Configure CGLIB Enhancer...
// 创建和配置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 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); // Generate the proxy class and create a proxy instance.
// 生成代理类和创建代理
return createProxyClassAndInstance(enhancer, callbacks);
}
catch (CodeGenerationException | IllegalArgumentException ex) {
throw new AopConfigException("Could not generate CGLIB subclass of " + this.advised.getTargetClass() +
": Common causes of this problem include using a final class or a non-visible class",
ex);
}
catch (Throwable ex) {
// TargetSource.getTarget() failed
throw new AopConfigException("Unexpected AOP exception", ex);
}
}
以上函数完成的说明了spring中创建Enhancer的过程,这里最重要的是getCallbacks设置拦截器链,看getCallbacks的源码:
org.springframework.aop.framework.CglibAopProxy类中:
 private Callback[] getCallbacks(Class<?> rootClass) throws Exception {
     // Parameters used for optimization choices...
     // 对expose-proxy属性的处理
     boolean exposeProxy = this.advised.isExposeProxy();
     boolean isFrozen = this.advised.isFrozen();
     boolean isStatic = this.advised.getTargetSource().isStatic();
     // Choose an "aop" interceptor (used for AOP calls).
     // 将拦截器封装在DynamicAdvisedInterceptor中
     Callback aopInterceptor = new DynamicAdvisedInterceptor(this.advised);
     // Choose a "straight to target" interceptor. (used for calls that are
     // unadvised but can return this). May be required to expose the proxy.
     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()));
     }
     // Choose a "direct to target" dispatcher (used for
     // unadvised calls to static targets that cannot return this).
     Callback targetDispatcher = (isStatic ?
             new StaticDispatcher(this.advised.getTargetSource().getTarget()) : new SerializableNoOp());
     Callback[] mainCallbacks = new Callback[] {
             // 将拦截器链加入到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 the target is a static one and the advice chain is frozen,
     // then we can make some optimizations by sending the AOP calls
     // direct to the target using the fixed chain for that method.
     if (isStatic && isFrozen) {
         Method[] methods = rootClass.getMethods();
         Callback[] fixedCallbacks = new Callback[methods.length];
         this.fixedInterceptorMap = new HashMap<>(methods.length);
         // TODO: small memory optimization here (can skip creation for methods with no advice)
         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);
         }
         // Now copy both the callbacks from mainCallbacks
         // and fixedCallbacks into the callbacks array.
         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;
 }
在getCallbacks中spring考虑了很多情况,但是对于我们来说,只需要理解最常用的就可以了,比如将advised属性封装在DynamicAdvisedInterceptor并加入在
callbacks中,这么做的目的是什么,为什么会这么做?在前面的示例中,我们了解到CGLIB中对于方法的拦截是通过将自定义的拦截器(实现MethodInterceptor接口)加入
Callback中并在调用代理的时候直接激活拦截器中的intercept方法来实现的,那么在getCallback中正是实现了这样的一个目的,DynamicAdvisedInterceptor继承自MethodInterceptor
加入CallBack中后,再次调用代理时会直接调用DynamicAdvisedInterceptor中的intercept方法,所以,由此推断,对于CGLIB方式实现的代理,其核心逻辑在
DynamicAdvisedInterceptor中的intercept方法,DynamicAdvisedInterceptor作为CglibAopProxy内部封装私有类,其在org.springframework.aop.framework.CglibAopProxy类中:
@Override
@Nullable
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
Object oldProxy = null;
boolean setProxyContext = false;
Object target = null;
TargetSource targetSource = this.advised.getTargetSource();
try {
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);
// 获取拦截链
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.
Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
// 如果拦截链为空则直接激活原方法
retVal = methodProxy.invoke(target, argsToUse);
}
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 && !targetSource.isStatic()) {
targetSource.releaseTarget(target);
}
if (setProxyContext) {
// Restore old proxy.
AopContext.setCurrentProxy(oldProxy);
}
}
}
上述的实现与JDK方式实现代理中的invoke方法基本相同,都是首先构造链,然后封装此链进行串联调用,区别就是在JDK代理中直接构造ReflectiveMethodInvocation类,而在
CGLIB代理中使用CglibMethodInvocation,CglibMethodInvocation继承自ReflectiveMethodInvocation,但是process方法没有重写
注意:spring还支持静态代理,这里没有写!!!不想写了
spring源码学习之AOP(二)的更多相关文章
- Spring源码学习-容器BeanFactory(二) BeanDefinition的创建-解析前BeanDefinition的前置操作
		写在前面 上文 Spring源码学习-容器BeanFactory(一) BeanDefinition的创建-解析资源文件主要讲Spring容器创建时通过XmlBeanDefinitionReader读 ... 
- spring源码学习之AOP(一)
		继续源码学习,看了spring中基础的容器和AOP感觉自己也没有什么长进,哈哈,我也不知道到底有用没有,这可能是培养自己的一种精神吧,不管那么多,继续学习!AOP中 AOP中几个重要的概念:(1)Ad ... 
- Spring源码学习
		Spring源码学习--ClassPathXmlApplicationContext(一) spring源码学习--FileSystemXmlApplicationContext(二) spring源 ... 
- Spring源码学习-容器BeanFactory(三) BeanDefinition的创建-解析Spring的默认标签
		写在前面 上文Spring源码学习-容器BeanFactory(二) BeanDefinition的创建-解析前BeanDefinition的前置操作中Spring对XML解析后创建了对应的Docum ... 
- Spring 源码学习笔记10——Spring AOP
		Spring 源码学习笔记10--Spring AOP 参考书籍<Spring技术内幕>Spring AOP的实现章节 书有点老,但是里面一些概念还是总结比较到位 源码基于Spring-a ... 
- spring源码学习之路---深入AOP(终)
		作者:zuoxiaolong8810(左潇龙),转载请注明出处,特别说明:本博文来自博主原博客,为保证新博客中博文的完整性,特复制到此留存,如需转载请注明新博客地址即可. 上一章和各位一起看了一下sp ... 
- spring源码学习之路---IOC初探(二)
		作者:zuoxiaolong8810(左潇龙),转载请注明出处,特别说明:本博文来自博主原博客,为保证新博客中博文的完整性,特复制到此留存,如需转载请注明新博客地址即可. 上一章当中我没有提及具体的搭 ... 
- Spring 源码学习——Aop
		Spring 源码学习--Aop 什么是 AOP 以下是百度百科的解释:AOP 为 Aspect Oriented Programming 的缩写,意为:面向切面编程通过预编译的方式和运行期动态代理实 ... 
- Spring源码学习-容器BeanFactory(一) BeanDefinition的创建-解析资源文件
		写在前面 从大四实习至今已一年有余,作为一个程序员,一直没有用心去记录自己工作中遇到的问题,甚是惭愧,打算从今日起开始养成写博客的习惯.作为一名java开发人员,Spring是永远绕不过的话题,它的设 ... 
随机推荐
- 44道JS难题
			国外某网站给出了44道JS难题,试着做了下,只做对了17道.这些题涉及面非常广,涵盖JS原型.函数细节.强制转换.闭包等知识,而且都是非常细节的东西,透过这些小细节可以折射出很多高级的JS知识点. 你 ... 
- 使用应用程序(Java/Python)访问MaxCompute Lightning进行数据开发
			MaxCompute Lightning是MaxCompute产品的交互式查询服务,支持以PostgreSQL协议及语法连接访问Maxcompute项目,让您使用熟悉的工具以标准 SQL查询分析Max ... 
- js摇一摇事件
			今早同事过来说.要做个小游戏.里面有个摇一摇动作. 平时都是做的手机营销h5比较少. 发现很有意思. 一时间没有反应过来. 怎么实现的摇一摇. 现在吧代码叠出来给2货的我. //运动事件监听if ... 
- iOS开发自定义转场动画
			1.转场动画 iOS7之后开发者可以自定义界面切换的转场动画,就是在模态弹出(present.dismiss),Navigation的(push.pop),TabBar的系统切换效果之外自定义切换动画 ... 
- IDEA中log4j  无法输出到本地,properties配置无效问题。
			log4j添加以后无法输出日志信息,经检查(按以下顺序): 1.jar包导入正常 2.log4j.properties配置文件正常 3.logger.info可以输出,但是properties文件无效 ... 
- 提前关闭Scrapy爬虫的设置
			Scrapy的CloseSpider扩展会在满足条件时自动终止爬虫程序.可以设置CLOSESPIDER_TIMEOUT(秒).CLOSESPIDER_ITEMCOUNT.CLOSESPIDER_PAG ... 
- BigNum模板
			#include<iostream> #include<cstring> #include<iomanip> #include<algorithm> u ... 
- css3之文本text-overflow 与 word-wrap, word-break
			CSS3 Text Overflow属性 CSS3文本溢出属性指定应向用户如何显示溢出内容 语法: text-overflow:clip | ellipsis 但是text-overflow只是用来说 ... 
- Reflections框架,类扫描工具
			Reflections是一个能提供一站式服务的对象. 巧用Reflections库实现包扫描(扫描某个包中某个接口实现.注解等) 它扫描工程的classpath,为元数据建索引,允许你运行时查询元数据 ... 
- Android开发 Camera2开发_2_预览分辨率或拍照分辨率的计算
			前言 不管在Camera1或者Camera2在适配不同手机/不同使用场景的情况下都需要计算摄像头里提供的分辨率列表中最合适的那一个分辨率.所以在需要大量机型适配的app,是不建议不经过计算直接自定义分 ... 
