上文介绍了代理类是由默认AOP代理工厂DefaultAopProxyFactory中createAopProxy方法产生的。如果代理对象是接口类型,则生成JdkDynamicAopProxy代理;否则生成ObjenesisCglibAopProxy代理,ObjenesisCglibAopProxy代理是继承于CglibAopProxy。下面先从熟悉的入手,选择JdkDynamicAopProxy分析。
查看源码,可以看到JdkDynamicAopProxy是一个final类,不能被继承和实现。其实现了AopProxy, InvocationHandler, Serializable接口,如下所示:
- final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializable
下面看看JdkDynamicAopProxy 构造器,源码如下:
- 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;
- }
从构造器可以看出,JdkDynamicAopProxy依赖于AdvisedSupport,根据config配置信息创建动态代理对象。代码中
提供的是Advisor列表。
- config.getAdvisors()
getProxy 方法是实现AopProxy接口,源码如下:
- @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());
- }
- Class < ?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);
- findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
- return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
- }
- /**
- * Finds any {@link #equals} or {@link #hashCode} method that may be defined
- * on the supplied set of interfaces.
- * @param proxiedInterfaces the interfaces to introspect
- */
- private void findDefinedEqualsAndHashCodeMethods(Class < ?>[] proxiedInterfaces) {
- for (Class < ?>proxiedInterface: proxiedInterfaces) {
- Method[] methods = proxiedInterface.getDeclaredMethods();
- for (Method method: methods) {
- if (AopUtils.isEqualsMethod(method)) {
- this.equalsDefined = true;
- }
- if (AopUtils.isHashCodeMethod(method)) {
- this.hashCodeDefined = true;
- }
- if (this.equalsDefined && this.hashCodeDefined) {
- return;
- }
- }
- }
- }
在创建代理时,既可以采用默认的类加载器,也可以指定特定的类加载器。JDK动态代理的代理对象是接口类型,先获取被代理对象的完整接口、根据指定的类加载器以及实现的调用处理器应用静态方法
创建代理对象。
- Proxy.newProxyInstance
上文介绍了InvocationHandler 接口,invoke该接口中唯一一个定义的方法。JdkDynamicAopProxy 是final类并且实现了InvocationHandler 接口,那么也必然实现了invoke方法,其源码如下:
- @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 {
- if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
- return equals(args[0]);
- }
- else if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
- return hashCode();
- }
- else if (method.getDeclaringClass() == DecoratingProxy.class) {
- return AopProxyUtils.ultimateTargetClass(this.advised);
- }
- else if (!this.advised.opaque && method.getDeclaringClass().isInterface() &&
- method.getDeclaringClass().isAssignableFrom(Advised.class)) {
- return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);
- }
- Object retVal;
- if (this.advised.exposeProxy) {
- oldProxy = AopContext.setCurrentProxy(proxy);
- setProxyContext = true;
- }
- target = targetSource.getTarget();
- if (target != null) {
- targetClass = target.getClass();
- }
- List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
- if (chain.isEmpty()) {
- Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
- retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
- }
- else {
- invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
- retVal = invocation.proceed();
- }
- Class<?> returnType = method.getReturnType();
- if (retVal != null && retVal == target &&
- returnType != Object.class && returnType.isInstance(proxy) &&
- !RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {
- 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()) {
- targetSource.releaseTarget(target);
- }
- if (setProxyContext) {
- AopContext.setCurrentProxy(oldProxy);
- }
- }
- }
前面只是一些校验,直接省略,步入重点。通过
得到被代理对象的类名。再根据被代理类名和方法名得到拦截链,也即通知链。如下所示:
- target = targetSource.getTarget()
- List < Object > chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
如果拦截链为空,则直接反射调用被代理方法,否则需要创建代理方法,此代理方法中已经加入附加处理(通知)。如下:
- if (chain.isEmpty()) {
- //处理被代理方法参数
- Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
- //反射执行被代理方法
- retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
- } else {
- // 创建代理方法
- invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
- // 执行代理方法
- retVal = invocation.proceed();
- }
反射执行被代理方法是调用工具类AopUtils中方法invokeJoinpointUsingReflection实现的,具体如下:
- public static Object invokeJoinpointUsingReflection(Object target, Method method, Object[] args)
- throws Throwable {
- // Use reflection to invoke the method.
- try {
- ReflectionUtils.makeAccessible(method);
- return method.invoke(target, args);
- }
- catch (InvocationTargetException ex) {
- // Invoked method threw a checked exception.
- // We must rethrow it. The client won't see the interceptor.
- throw ex.getTargetException();
- }
- catch (IllegalArgumentException ex) {
- throw new AopInvocationException("AOP configuration seems to be invalid: tried calling method [" +
- method + "] on target [" + target + "]", ex);
- }
- catch (IllegalAccessException ex) {
- throw new AopInvocationException("Could not access method [" + method + "]", ex);
- }
- }
创建代理方法是通过ReflectiveMethodInvocation实现的,然后调用proceed()方法执行拦截链和被代理方法。ReflectiveMethodInvocation实现了Joinpoint接口,其构造器如下:
- protected ReflectiveMethodInvocation(
- Object proxy, Object target, Method method, Object[] arguments,
- 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;
- }
ReflectiveMethodInvocation调用proceed方法执行代理,proceed方法是在Joinpoint接口中定义的,ReflectiveMethodInvocation中进行了实现。具体实现如下:
- 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.
- return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
- }
- }
从上面分析源码大致可以了解Spring AOP 动态代理的设计思想,采用类加载器根据接口产生代理方法,代理方法是在原方法的基础上加上通知链,以实现AOP功能。当执行方法时,判断该方法通知链是否为空,若为空,则通过反射直接调用原方法;若不为空,则产生代理方法,执行代理方法。下一节将继续探讨Spring AOP 的另一种实现方法CGLIB
来源: http://www.cnblogs.com/hthuang/p/7797588.html