BeanNameAutoProxyCreator与ProxyFactoryBean区别
我们项目用到的是BeanNameAutoProxyCreator,说道aop可能大家更熟悉的是ProxyFactoryBean。它们的区别很简单,BeanNameAutoProxyCreator只不过可以配置多个target
使用
配置中有两个参数:
- beanNames:要拦截的bean
- interceptorNames:拦截器
配置示例:
<bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator" id="ims_core_new_ServiceAutoProxy">
<property name="beanNames">
<list>
<!--需要拦截的服务-->
<value>imsinner_innerService</value>
<value>imsinner_innerQueryService</value>
<value>imssdl_iImsSyncAppService</value>
<value>imsts_iImsTsAppService</value>
<value>imsxdr_iImsXdrService</value>
</list>
</property>
<property name="interceptorNames">
<list>
<value>ims_new_interceptor</value>
</list>
</property>
</bean>
源码分析
那么重点就是来看下BeanNameAutoProxyCreator了
public class BeanNameAutoProxyCreator extends AbstractAutoProxyCreator {
}
AbstractAutoProxyCreator里几个重要的属性
private String interceptorNames[];
private BeanFactory beanFactory;
private ClassLoader proxyClassLoader;
凭直觉,createProxy应该是一个重要的方法,分析一下
protected Object createProxy(Class beanClass, String beanName, Object specificInterceptors[], TargetSource targetSource)
{
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.copyFrom(this);
if(!shouldProxyTargetClass(beanClass, beanName))
{
Class targetInterfaces[] = ClassUtils.getAllInterfacesForClass(beanClass, proxyClassLoader);
Class aclass[];
int k = (aclass = targetInterfaces).length;
for(int i = 0; i < k; i++)
{
Class targetInterface = aclass[i];
proxyFactory.addInterface(targetInterface);
}
}
Advisor advisors[] = buildAdvisors(beanName, specificInterceptors);
Advisor aadvisor[];
int l = (aadvisor = advisors).length;
for(int j = 0; j < l; j++)
{
Advisor advisor = aadvisor[j];
proxyFactory.addAdvisor(advisor);
}
proxyFactory.setTargetSource(targetSource);
customizeProxyFactory(proxyFactory);
proxyFactory.setFrozen(freezeProxy);
if(advisorsPreFiltered())
proxyFactory.setPreFiltered(true);
return proxyFactory.getProxy(proxyClassLoader);
}
一路追踪到了这个方法
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())
return new JdkDynamicAopProxy(config);
if(!cglibAvailable)
throw new AopConfigException("Cannot proxy target class because CGLIB2 is not available. Add CGLIB to the class path or specify proxy interfaces.");
else
return CglibProxyFactory.createCglibProxy(config);
} else
{
return new JdkDynamicAopProxy(config);
}
}
JdkDynamicAopProxy 的getProxy如下
public Object getProxy(ClassLoader classLoader)
{
if(logger.isDebugEnabled())
logger.debug((new StringBuilder("Creating JDK dynamic proxy: target source is ")).append(advised.getTargetSource()).toString());
Class proxiedInterfaces[] = AopProxyUtils.completeProxiedInterfaces(advised);
findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
}
到这里我们就看到了创建jdk的proxy代理
这里我们的JdkDynamicAopProxy实现了InvocationHandler这个接口,this参数对应的是InvocationHandler对象,也就是说当 Proxy对象的函数被调用的时候,InvocationHandler的invoke方法会被作为回调函数调用:下面也有一个回调的分析。
分析到这里关键就看下invoke方法了
这里得到一个拦截器链
List chain = advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
if(chain.isEmpty())
{
//如果拦截器为空,则直接调用被代理的方法
retVal = AopUtils.invokeJoinpointUsingReflection(target, method, args);
} else
{
//拦截器不为空,则
MethodInvocation invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
retVal = invocation.proceed();
}
public static Object invokeJoinpointUsingReflection(Object target, Method method, Object args[])
throws Throwable
{
ReflectionUtils.makeAccessible(method);
return method.invoke(target, args);
InvocationTargetException ex;
ex;
throw ex.getTargetException();
ex;
throw new AopInvocationException((new StringBuilder("AOP configuration seems to be invalid: tried calling method [")).append(method).append("] on target [").append(target).append("]").toString(), ex);
ex;
throw new AopInvocationException((new StringBuilder("Could not access method [")).append(method).append("]").toString(), ex);
}
public Object proceed()
throws Throwable
{
//已经没有拦截器要调用了,则直接调用主方法
if(currentInterceptorIndex == interceptorsAndDynamicMethodMatchers.size() - 1)
return invokeJoinpoint();
Object interceptorOrInterceptionAdvice = interceptorsAndDynamicMethodMatchers.get(++currentInterceptorIndex);
if(interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher)
{
InterceptorAndDynamicMethodMatcher dm = (InterceptorAndDynamicMethodMatcher)interceptorOrInterceptionAdvice;
if(dm.methodMatcher.matches(method, targetClass, arguments))
return dm.interceptor.invoke(this);
else
return proceed();
} else
{
return ((MethodInterceptor)interceptorOrInterceptionAdvice).invoke(this);
}
}
这里有一个什么匹配的逻辑,如果匹配,调用这个拦截器,如果不匹配,继续下一个拦截器,这个匹配就不细看了
那如果匹配了,下一个就不走了?
挺关键的这个地方,这个ReflectiveMethodInvocation实现了MethodInvocation接口,在调用拦截器的invoke的方法的时候,把自己做为参数传给了拦截器,在拦截器A执行完以后,如果想继续执行拦截器链的下一个,只需要在它实现的invoke方法的proceed方法,就可以回调proceed,继续执行下一个
return dm.interceptor.invoke(this);
public Object invoke(MethodInvocation invocation) throws Throwable
总结
在整个的分析过程中,可以看到理解了这么几个技术点,基本上就理解了AOP
- 动态代理
- 责任链
- 回调
当然还有spring最基本的工厂模式,太基本了就不罗列它了。