- /**
- * JDK-based {@link AopProxy} implementation for the Spring AOP framework
- *InvocationHandler接口的invoke方法就是拦截回调的入口,即对目标方法的调用会先被invoke方法拦截,并在invoke方法里面来调用目标方法
- */
- final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializable {
- public JdkDynamicAopProxy(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;
- }
- @Override
- public Object getProxy() {
- return getProxy(ClassUtils.getDefaultClassLoader());
- }
- @Override
- public Object getProxy(ClassLoader classLoader) {
- if (logger.isDebugEnabled()) {
- logger.debug("Creating JDK dynamic proxy: target source is " + this.advised.getTargetSource());
- }
- //首先从advised对象中取得代理对象的代理接口配置
- Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);
- findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
- //第三个参数需要实现InvocationHandler接口和invoke方法,这个invoke方法是Proxy代理对象的回调方法
- //这种方式其实就是用JDK的动态代理来为目标对象创建代理对象,对目标对象方法的调用就是由这个代理对象来调用的
- return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
- }
- /**
- * Implementation of {@code InvocationHandler.invoke}.
- * <p>Callers will see exactly the exception thrown by the target,
- * unless a hook method throws an exception.
- * 拦截回调入口
- */
- @Override
- public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
- MethodInvocation invocation;
- Object oldProxy = null;
- boolean setProxyContext = false;
- TargetSource targetSource = this.advised.targetSource;
- Class<?> targetClass = null;
- Object target = null;
- try {
- //如果目标对象没有实现Object类的基本方法:equals
- if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
- // The target does not implement the equals(Object) method itself.
- return equals(args[0]);
- }
- //如果目标对象没有实现Object类的基本方法:hashcode
- 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;
- }
- // May be null. Get as late as possible to minimize the time we "own" the target,
- // in case it comes from a pool.
- //得到目标对象
- target = targetSource.getTarget();
- if (target != null) {
- targetClass = target.getClass();
- }
- // Get the interception chain for this method. 获取方法method的拦截器链
- // 拦截器链实际就是由一系列的Advice通知对象组成的
- 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.
- //如果没有定义拦截器链,就直接调用target对象的对应方法
- 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); //适配参数
- //调用target对象的对应方法
- retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
- }
- else {
- // We need to create a method invocation...
- //如果有拦截器的设定,那么需要调用拦截器之后才调用目标对象的相应方法,通过构造一个ReflectiveMethodInvocation来实现
- 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.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);
- }
- }
- }
- }
来源: http://blog.csdn.net/u011734144/article/details/73436666