protected Object createProxy(
Class<?> beanClass, String beanName, Object[] specificInterceptors, TargetSource targetSource) {
//..................略
//代理工厂
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.copyFrom(this);
//判断是否targetClass代理不是接口代理
if (!proxyFactory.isProxyTargetClass()) {
if (shouldProxyTargetClass(beanClass, beanName)) {
proxyFactory.setProxyTargetClass(true);
} else {
//如果是接口代理,需要添加接口属性
evaluateProxyInterfaces(beanClass, proxyFactory);
}
}
//适配器模式把拿到的拦截器统一封装成Advisor
Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
for (Advisor advisor : advisors) {
proxyFactory.addAdvisor(advisor);
}
//创建代理
return proxyFactory.getProxy(getProxyClassLoader());
//...................略
}
拦截器封装为Advisor的适配处理看这边:
@Override
public Advisor wrap(Object adviceObject) throws UnknownAdviceTypeException {
if (adviceObject instanceof Advisor) {
return (Advisor) adviceObject;
}
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.
return new DefaultPointcutAdvisor(advice);
}
for (AdvisorAdapter adapter : this.adapters) {
// Check that it is supported.
if (adapter.supportsAdvice(advice)) {
return new DefaultPointcutAdvisor(advice);
}
}
throw new UnknownAdviceTypeException(advice);
}
getProxy方法主要包含两个步骤:
public Object getProxy(ClassLoader classLoader) {
return createAopProxy().getProxy(classLoader);
}
创建代理的方法createProxy会根据配置以及是否继承接口分别生成Jdk或者Cglib代理
protected Object createProxy(
Class<?> beanClass, String beanName, Object[] specificInterceptors, TargetSource targetSource) {
//.......................略
proxyFactory.setFrozen(this.freezeProxy);
if (advisorsPreFiltered()) {
proxyFactory.setPreFiltered(true);
}
//生成代理类返回
return proxyFactory.getProxy(getProxyClassLoader());
}
public Object getProxy(ClassLoader classLoader) {
/**
* @see JdkDynamicAopProxy#getProxy(ClassLoader)
* @see CglibAopProxy#getProxy
*/
return createAopProxy().getProxy(classLoader);
}
@Override
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
/**
* 满足强制使用CGLIB配置、目标类不是接口、不存在代理接口
* 使用CGLIB方式进行代理
* 否则使用JDK动态代理
* 这边是创建不同AopProxy返回,回去看具体的调用逻辑
*/
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);
}
}
JDK代理主要引用于接口代理,他必须继承InvocationHandler接口,实现getProxy、Invoke方法
常规写法:getProxy
/**
* 可以看到JDK的动态代理是接口的代理,需要继承InvocationHandler类,并实现invoke方法,这边是proxy的写法。
* 具体看一下invoke方法
* @see #invoke(Object, Method, Object[])
*/
@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);
}
这边的invoke方法主要分成这几步:
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//...........略
try {
/**
* equals、hash、method所属类是接口的处理
*/
if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
//...................略
}
//目标对象内部的自我调用无法实施切面增强,通过此参数暴露代理
if (this.advised.exposeProxy) {
// Make invocation available if necessary.
oldProxy = AopContext.setCurrentProxy(proxy);
setProxyContext = true;
}
//.....................略
/**
* 获取当前方法的拦截器链
* 这边可以看到这个其实是从初始化的Map>中去拿到的.
*/
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
if (chain.isEmpty()) {
/**
* 如果没有拦截器链,直接调用method.invoke方法实现
*/
Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
}
else {
/**
* 把过滤器链放进来初始化一个invocation,并调用这个invocation
* @see ReflectiveMethodInvocation#proceed()
*/
invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
// Proceed to the joinpoint through the interceptor chain.
retVal = invocation.proceed();
}
//返回结果
Class<?> returnType = method.getReturnType();
//.............略
return retVal;
}
finally {
//....................略
}
}
这边可以看到,获取拦截器链的方式是
public List<Object> getInterceptorsAndDynamicInterceptionAdvice(Method method, Class<?> targetClass) {
MethodCacheKey cacheKey = new MethodCacheKey(method);
List<Object> cached = this.methodCache.get(cacheKey);
if (cached == null) {
cached = this.advisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice(
this, method, targetClass);
this.methodCache.put(cacheKey, cached);
}
return cached;
}
@Override
public List<Object> getInterceptorsAndDynamicInterceptionAdvice(
Advised config, Method method, Class<?> targetClass) {
// This is somewhat tricky... We have to process introductions first,
// but we need to preserve order in the ultimate list.
List<Object> interceptorList = new ArrayList<Object>(config.getAdvisors().length);
Class<?> actualClass = (targetClass != null ? targetClass : method.getDeclaringClass());
boolean hasIntroductions = hasMatchingIntroductions(config, actualClass);
AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance();
for (Advisor advisor : config.getAdvisors()) {
if (advisor instanceof PointcutAdvisor) {
// Add it conditionally.
PointcutAdvisor pointcutAdvisor = (PointcutAdvisor) advisor;
if (config.isPreFiltered() || pointcutAdvisor.getPointcut().getClassFilter().matches(actualClass)) {
MethodInterceptor[] interceptors = registry.getInterceptors(advisor);
MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher();
if (MethodMatchers.matches(mm, method, actualClass, hasIntroductions)) {
if (mm.isRuntime()) {
// Creating a new object instance in the getInterceptors() method
// isn't a problem as we normally cache created chains.
for (MethodInterceptor interceptor : interceptors) {
interceptorList.add(new InterceptorAndDynamicMethodMatcher(interceptor, mm));
}
}
else {
interceptorList.addAll(Arrays.asList(interceptors));
}
}
}
}
else if (advisor instanceof IntroductionAdvisor) {
IntroductionAdvisor ia = (IntroductionAdvisor) advisor;
if (config.isPreFiltered() || ia.getClassFilter().matches(actualClass)) {
Interceptor[] interceptors = registry.getInterceptors(advisor);
interceptorList.addAll(Arrays.asList(interceptors));
}
}
else {
Interceptor[] interceptors = registry.getInterceptors(advisor);
interceptorList.addAll(Arrays.asList(interceptors));
}
}
return interceptorList;
}
如果拦截器链不为空,会一直去执行完所有匹配的拦截器链(method的invoke调用)
@Override
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) {
/**
* 如果是一个拦截器的匹配对象,则动态匹配拦截器和匹配到的拦截器进行执行
*/
InterceptorAndDynamicMethodMatcher dm =
(InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
if (dm.methodMatcher.matches(this.method, this.targetClass, this.arguments)) {
return dm.interceptor.invoke(this);
}
else {
/**
* 下一次匹配
*/
return proceed();
}
}
else {
/**
* 普通拦截器直接调用invoke
*/
return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
}
}
cglib需要通过Enhancer类来使用,所以这边的操作其实也是构建这样的类,来实现具体操作
@Override
public Object getProxy(ClassLoader classLoader) {
try {
//.................略
//创建Enhancer并设置属性,这个是CGLB调用的具体实现--设置属性
Enhancer enhancer = createEnhancer();
//.......设置属性,略
//拦截器的获取和设置
Callback[] callbacks = getCallbacks(rootClass);
//.......................略
// Enhancer创建
return createProxyClassAndInstance(enhancer, callbacks);
}
catch (CodeGenerationException ex) {
// ..................略
}
}
这边主要看一下拦截器链包装的处理 DynamicAdvisedInterceptor继承自Methodlnterceptor.这个接口是Spring支持的,实现他的intercept方法可以实现代理的目的
private Callback[] getCallbacks(Class<?> rootClass) throws Exception {
//............略
/**
* 66.拦截器的包装,DynamicAdvisedInterceptor继承自Methodlnterceptor,会实现他的intercept方法来实现CGLB调用
* @see DynamicAdvisedInterceptor#intercept(Object, Method, Object[], MethodProxy)
*/
Callback aopInterceptor = new DynamicAdvisedInterceptor(this.advised);
//............略
//将拦截器添加到Callback数组中
Callback[] mainCallbacks = new Callback[] {aopInterceptor, targetInterceptor, new SerializableNoOp(), targetDispatcher, this.advisedDispatcher, new EqualsInterceptor(this.advised),new HashCodeInterceptor(this.advised)};
//.......................略
return callbacks;
}
也就是说这里返回的callback回调数组其实是DynamicAdvisedInterceptor的实现.把callback数组设置到Enhancer中帮助实现调用
DynamicAdvisedInterceptor实现了MethodInterceptor接口,并实现了intercept方法.可以看到,这里的itercept的实现和JDK代理是一样的
@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.
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) {
releaseTarget(target);
}
if (setProxyContext) {
// Restore old proxy.
AopContext.setCurrentProxy(oldProxy);
}
}
}