Spring AOP实现之拦截器调用的实现
2014-10-25 20:37
471 查看
在Spring AOP通过JDK的Proxy方式或CGLIB方式生成代理对象的时候,相关的拦截器已经配置到代理对象中去了,拦截器在代理对象中起作用是通过对这些方法的回调来完成的。
如果使用JDK的Proxy来生成代理对象,那么需要通过InvocationHandler来设置拦截器回调;如果使用CGLIB来生成代理对象,就需要根据CGLIB的使用要求,通过DynamicAdvisedInterceptor来完成回调。
JdkDynamicAopProxy的invoke拦截
在JdkDynamicAopProxy生成Proxy代理对象时,最后的生成调用是:
AopProxy代理对象的回调
CgligAopProxy的intercept拦截
在CgligAopProxy生成Proxy对象的时候,其回调是在DynamicAdvisedInterceptor对象中实现的。
对于JdkDynamicAopProxy代理对象而言,这个对目标对象的方法调用时通过AopUtils使用反射机制实现的。
对于使用CglibAopProxy的代理对象,它对目标对象的调用时通过CGLIB的MethodProxy来完成的,这个对象的使用是由CGLIB的设计决定的。
AOP拦截器链的调用
JDK的JdkDynamicAopProxy和CGLIB虽然会生成不同的AopProxy代理对象,但是它们对拦截器链的调用都是在ReflectiveMethodInvocation中通过proceed方法实现的。其核心代码如下:
以上就是整个拦截器及target目标对象方法被调用的过程。在这里已经可以看到advice通知的调用入口。
通知器的配置
在上面的proceed方法中有这样的一行代码
Object interceptorOrInterceptionAdvice =
this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex); 这个interceptorOrInterceptionAdvice是获得的拦截器,它通过拦截器机制对目标对象的行为进行增强。在ReflectiveMethodInvocation类的构造函数中有以下代码
this.interceptorsAndDynamicMethodMatchers = interceptorsAndDynamicMethodMatchers;在JdkDynamicAopProxy中有
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);从代码中可以看到,获得interceptors的操作时有advised对象完成的,而这个advised是一个AdvisedSupport对象。从类的继承关系上看,这个AdvisedSupport类同时也是ProxyFactoryBean的基类。在AdvisedSupport中有以下代码:
public List<Object> getInterceptorsAndDynamicInterceptionAdvice(Method method, Class<?> targetClass) {
//为提高取得拦截器的效率,这里使用了cache,利用cache去获取已有的interceptor链,但是第一次还是需要自己动手生成
MethodCacheKey cacheKey = new MethodCacheKey(method);
List<Object> cached = this.methodCache.get(cacheKey);
if (cached == null) {//这个interceptor链的生成是由advisorChainFactory完成的,在这里使用的是DefaultAdvisorChainFactory
cached = this.advisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice(
this, method, targetClass);
this.methodCache.put(cacheKey, cached);
}
return cached;
}
取得拦截器链的工作是由配置好的advisorChainFactory来完成的,这里的advisorChainFactory被配置成一个DefaultAdvisorChainFactory。在DefaultAdvisorChainFactory中
有以下代码
public List<Object> getInterceptorsAndDynamicInterceptionAdvice(
Advised config, Method method, Class<?> targetClass) {
//拦截器链的长度是由config中配置的通知器的个数来决定的,这个配置就是XML中interceptNames属性的配置
List<Object> interceptorList = new ArrayList<Object>(config.getAdvisors().length);
boolean hasIntroductions = hasMatchingIntroductions(config, targetClass);
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(targetClass)) {
//拦截器是通过AdvisorAdapterRegistry来加入的,这个AdvisorAdapterRegistry对advice织入起了很大的作用
//这里的advisor通知器是从AdvisorSupport中取得的。
MethodInterceptor[] interceptors = registry.getInterceptors(advisor);
MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher();
if (MethodMatchers.matches(mm, method, targetClass, 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(targetClass)) {
Interceptor[] interceptors = registry.getInterceptors(advisor);
interceptorList.addAll(Arrays.asList(interceptors));
}
}
else {
Interceptor[] interceptors = registry.getInterceptors(advisor);
interceptorList.addAll(Arrays.asList(interceptors));
}
}
return interceptorList;
}
在ProxyFactoryBean的getObject方法中有对advisor进行初始化。在initializeAdvisorChain方法中有
private synchronized void initializeAdvisorChain() throws AopConfigException, BeansException {
if (this.advisorChainInitialized) {
return;
}
if (!ObjectUtils.isEmpty(this.interceptorNames)) {
if (this.beanFactory == null) {
throw new IllegalStateException("No BeanFactory available anymore (probably due to serialization) " +
"- cannot resolve interceptor names " + Arrays.asList(this.interceptorNames));
}
if (this.interceptorNames[this.interceptorNames.length - 1].endsWith(GLOBAL_SUFFIX) &&
this.targetName == null && this.targetSource == EMPTY_TARGET_SOURCE) {
throw new AopConfigException("Target required after globals");
}
for (String name : this.interceptorNames) {
if (logger.isTraceEnabled()) {
logger.trace("Configuring advisor or advice '" + name + "'");
}
if (name.endsWith(GLOBAL_SUFFIX)) {
if (!(this.beanFactory instanceof ListableBeanFactory)) {
throw new AopConfigException(
"Can only use global advisors or interceptors with a ListableBeanFactory");
}
addGlobalAdvisor((ListableBeanFactory) this.beanFactory,
name.substring(0, name.length() - GLOBAL_SUFFIX.length()));
}
else {
Object advice;//需要对Bean的类型进行判断,是单件类型还是prototype类型
if (this.singleton || this.beanFactory.isSingleton(name)) {
//这里是取得advisor的地方,是通过beanFactory取得的,把interceptorNames这个List中的interceptor名字交个beanFactory
//然后通过调用BeanFactory的getBean去获取
advice = this.beanFactory.getBean(name);
}
else {
advice = new PrototypePlaceholderAdvisor(name);
}
addAdvisorOnChainCreation(advice, name);//取得advice后,由interceptName和advice来决定一个advisor并添加到拦截器链中 }
}
}
this.advisorChainInitialized = true;
}
Advice通知的实现
在前面的注册器中,使用的是GlobalAdvisorAdapterRegistry来完成适配器的适配和注册。它的getInterceptors方法封装这advice织入实现的入口。
GlobalAdvisorAdapterRegistry的实现很简单,它起到的是一个适配器的作用,同时也是一个单件模式的应用。
public abstract class GlobalAdvisorAdapterRegistry {
private static AdvisorAdapterRegistry instance = new DefaultAdvisorAdapterRegistry();
public static AdvisorAdapterRegistry getInstance() {
return instance;
}
static void reset() {
instance = new DefaultAdvisorAdapterRegistry();
}
}
这是一个单件模式的实现,它使用静态类变量来保持一个唯一的实例。然后通过getInstance方法返回单件DefaultAdvisorAdapterRegister对象。
在DefaultAdvisorAdapterRegister对象中,设置了一系列的adapter适配器,正是这些adapter适配器的实现,为Spring AOP的advice提供编织能力。
public class DefaultAdvisorAdapterRegistry implements AdvisorAdapterRegistry, Serializable {
//定义一个AdvisorAdapter的List,这个List中的Adapter是与实现Spring AOP的advice增强功能是相对应的
private final List<AdvisorAdapter> adapters = new ArrayList<AdvisorAdapter>(3);
/**
* 这里把已有的advice实现的Adapter加入进来,这里有MethodBeforeAdviceAdapter、AfterReturningAdviceAdapter、ThrowsAdviceAdapter这些AOP的advice封装
* AOP的advice封装实现
*/
public DefaultAdvisorAdapterRegistry() {
registerAdvisorAdapter(new MethodBeforeAdviceAdapter());
registerAdvisorAdapter(new AfterReturningAdviceAdapter());
registerAdvisorAdapter(new ThrowsAdviceAdapter());
}
@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);
}
@Override
public MethodInterceptor[] getInterceptors(Advisor advisor) throws UnknownAdviceTypeException {
List<MethodInterceptor> interceptors = new ArrayList<MethodInterceptor>(3);
Advice advice = advisor.getAdvice();//从Advisor通知器配置中取得advice通知
if (advice instanceof MethodInterceptor) {//如果通知是MethodInterceptor的类型,直接加入interceptors的list中,不需要适配
interceptors.add((MethodInterceptor) advice);
}
//对通知进行适配,使用已经配置好的Adapter:MethodBeforeAdviceAdapter、AfterReturningAdviceAdapter、ThrowsAdviceAdapter,
//然后从对应的adapter中取出封装好AOP编织功能的拦截器
for (AdvisorAdapter adapter : this.adapters) {
if (adapter.supportsAdvice(advice)) {
interceptors.add(adapter.getInterceptor(advisor));
}
}
if (interceptors.isEmpty()) {
throw new UnknownAdviceTypeException(advisor.getAdvice());
}
return interceptors.toArray(new MethodInterceptor[interceptors.size()]);
}
@Override
public void registerAdvisorAdapter(AdvisorAdapter adapter) {
this.adapters.add(adapter);
}
}
以MethodBeforeAdviceAdapter为例来说明advice的实现原理。MethodBeforeAdviceAdapter的实现:
class MethodBeforeAdviceAdapter implements AdvisorAdapter, Serializable {
@Override
public boolean supportsAdvice(Advice advice) {
return (advice instanceof MethodBeforeAdvice);
}
@Override
public MethodInterceptor getInterceptor(Advisor advisor) {
MethodBeforeAdvice advice = (MethodBeforeAdvice) advisor.getAdvice();
return new MethodBeforeAdviceInterceptor(advice);
}
} 在这里的getInterceptor中,返回的是new MethodBeforeAdviceInterceptor(advice),MethodBeforeAdviceInterceptor完成的是对MethodBeforeAdvice的封装,可以在
MethodBeforeAdviceInterceptor设计的invoke回调方法中,看到首先触发了advice的before回调,然后才是MethodInvocation的proceed方法调用。在这里和前面的
ReflectiveMethodInvocation的proceed联系起来了
public class MethodBeforeAdviceInterceptor implements MethodInterceptor, Serializable {
private MethodBeforeAdvice advice;
/**
* 为指定的Advice创建对应的MethodBeforeInterceptor对象
* @param advice the MethodBeforeAdvice to wrap
*/
public MethodBeforeAdviceInterceptor(MethodBeforeAdvice advice) {
Assert.notNull(advice, "Advice must not be null");
this.advice = advice;
}
//这个invoke方法是拦截器的回调方法,会在代理对象的方法被调用时触发回调
@Override
public Object invoke(MethodInvocation mi) throws Throwable {
this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis() );
return mi.proceed();
}
}
在AopProxy代理对象触发的ReflectiveMethodInvocation的proceed方法中,在取得拦截器以后,启动了对拦截器invoke方法的调用。按照AOP的配置规则,ReflectiveMethodInvocation触发的拦截器invoke方法,最终会根据不同的advice类型,触发Spring对不同的advice的拦截器的封装,比如对MethodBeforeAdvice,最终
会触发MethodBeforeAdviceInterceptor的invoke方法。在该方法中,会先调用advice的before方法,这就是MethodBeforeAdvice所需要的对目标对象的增强效果;在方法调用之前完成通知增强。
如果使用JDK的Proxy来生成代理对象,那么需要通过InvocationHandler来设置拦截器回调;如果使用CGLIB来生成代理对象,就需要根据CGLIB的使用要求,通过DynamicAdvisedInterceptor来完成回调。
JdkDynamicAopProxy的invoke拦截
在JdkDynamicAopProxy生成Proxy代理对象时,最后的生成调用是:
Proxy.newProxyInstance(classLoader, proxiedInterfaces, this)在这里的this参数对应就是InvocationHandler,InvocationHandler是JDK定义的反射类的一个接口,该接口中定义了invoke方法,而这个invoke方法是作为JDK Proxy代理对象进行拦截的回调入口出现的。也就是说当代理对象的代理方法被调用时,JdkDynamicAopProxy的invoke方法作为Proxy对象的回调函数被触发,从而通过invoke的具体实现,来完成对目标对象方法调用的拦截或者说功能增强的工作。
AopProxy代理对象的回调
@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]); } if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) { return hashCode(); } 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) { // Make invocation available if necessary. oldProxy = AopContext.setCurrentProxy(proxy); setProxyContext = true; } //得到目标对象的地方 target = targetSource.getTarget(); if (target != null) { targetClass = target.getClass(); } // 这里获得定义好的拦截器链 List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass); // 对拦截器链进行判断,如果没有设定拦截器链,那么就直接调用target的对应方法 if (chain.isEmpty()) { retVal = AopUtils.invokeJoinpointUsingReflection(target, method, args); } else { // 如果有拦截器的设定,则需要调用拦截器之后才调用目标对象的相应方法 //通过构造一个ReflectiveMethodInvocation来实现。 invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain); // 沿着拦截器链继续前进 retVal = invocation.proceed(); } Class<?> returnType = method.getReturnType(); if (retVal != null && retVal == target && 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); } } }
CgligAopProxy的intercept拦截
在CgligAopProxy生成Proxy对象的时候,其回调是在DynamicAdvisedInterceptor对象中实现的。
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) { oldProxy = AopContext.setCurrentProxy(proxy); setProxyContext = true; } target = getTarget(); if (target != null) { targetClass = target.getClass(); } List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass); Object retVal; if (chain.isEmpty() && Modifier.isPublic(method.getModifiers())) { retVal = methodProxy.invoke(target, args); } else { //通过CglibMethodInvocation来启动advice通知 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); } } }如果没有拦截器的时候,那么会对目标对象的方法进行调用。
对于JdkDynamicAopProxy代理对象而言,这个对目标对象的方法调用时通过AopUtils使用反射机制实现的。
public static Object invokeJoinpointUsingReflection(Object target, Method method, Object[] args) throws Throwable { // 这里是使用反射机制调用target对象方法的地方。 首先得到调用方法的反射对象,然后使用invoke启动对方法反射对象的调用 try { ReflectionUtils.makeAccessible(method); return method.invoke(target, args); } catch (InvocationTargetException ex) { // 抛出AOP异常,对异常进行转换 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); } }
对于使用CglibAopProxy的代理对象,它对目标对象的调用时通过CGLIB的MethodProxy来完成的,这个对象的使用是由CGLIB的设计决定的。
AOP拦截器链的调用
JDK的JdkDynamicAopProxy和CGLIB虽然会生成不同的AopProxy代理对象,但是它们对拦截器链的调用都是在ReflectiveMethodInvocation中通过proceed方法实现的。其核心代码如下:
public Object proceed() throws Throwable { //从索引为-1的拦截器开始调用,并按序递增,如果拦截器链中的拦截器迭代调用完毕, //这里开始调用target的函数,这个函数是通过反射机制完成的,具体实现是在AopUtils.invokeJoinpointUsingReflection方法中 if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) { return invokeJoinpoint(); } Object interceptorOrInterceptionAdvice = this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex); if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) { // 这里对拦截器进行动态匹配的判断,这里是触发进行匹配的地方,如果和定义的PointCut // 匹配,那么这个advice将会得到执行。 InterceptorAndDynamicMethodMatcher dm = (InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice; if (dm.methodMatcher.matches(this.method, this.targetClass, this.arguments)) { return dm.interceptor.invoke(this);//对advice通知的调用入口 } else { // 如果不匹配,那么proceed会被递归调用,直到所有的拦截器都被运行过为止 return proceed(); } } else { // 如果是一个interceptor,直接调用这个interceptor对应的方法 return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this); } }
以上就是整个拦截器及target目标对象方法被调用的过程。在这里已经可以看到advice通知的调用入口。
通知器的配置
在上面的proceed方法中有这样的一行代码
Object interceptorOrInterceptionAdvice =
this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex); 这个interceptorOrInterceptionAdvice是获得的拦截器,它通过拦截器机制对目标对象的行为进行增强。在ReflectiveMethodInvocation类的构造函数中有以下代码
this.interceptorsAndDynamicMethodMatchers = interceptorsAndDynamicMethodMatchers;在JdkDynamicAopProxy中有
invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);这里的chain就是拦截器链。这个chain是在JdkDynamicAopProxy中进行赋值的
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);从代码中可以看到,获得interceptors的操作时有advised对象完成的,而这个advised是一个AdvisedSupport对象。从类的继承关系上看,这个AdvisedSupport类同时也是ProxyFactoryBean的基类。在AdvisedSupport中有以下代码:
public List<Object> getInterceptorsAndDynamicInterceptionAdvice(Method method, Class<?> targetClass) {
//为提高取得拦截器的效率,这里使用了cache,利用cache去获取已有的interceptor链,但是第一次还是需要自己动手生成
MethodCacheKey cacheKey = new MethodCacheKey(method);
List<Object> cached = this.methodCache.get(cacheKey);
if (cached == null) {//这个interceptor链的生成是由advisorChainFactory完成的,在这里使用的是DefaultAdvisorChainFactory
cached = this.advisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice(
this, method, targetClass);
this.methodCache.put(cacheKey, cached);
}
return cached;
}
取得拦截器链的工作是由配置好的advisorChainFactory来完成的,这里的advisorChainFactory被配置成一个DefaultAdvisorChainFactory。在DefaultAdvisorChainFactory中
有以下代码
public List<Object> getInterceptorsAndDynamicInterceptionAdvice(
Advised config, Method method, Class<?> targetClass) {
//拦截器链的长度是由config中配置的通知器的个数来决定的,这个配置就是XML中interceptNames属性的配置
List<Object> interceptorList = new ArrayList<Object>(config.getAdvisors().length);
boolean hasIntroductions = hasMatchingIntroductions(config, targetClass);
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(targetClass)) {
//拦截器是通过AdvisorAdapterRegistry来加入的,这个AdvisorAdapterRegistry对advice织入起了很大的作用
//这里的advisor通知器是从AdvisorSupport中取得的。
MethodInterceptor[] interceptors = registry.getInterceptors(advisor);
MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher();
if (MethodMatchers.matches(mm, method, targetClass, 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(targetClass)) {
Interceptor[] interceptors = registry.getInterceptors(advisor);
interceptorList.addAll(Arrays.asList(interceptors));
}
}
else {
Interceptor[] interceptors = registry.getInterceptors(advisor);
interceptorList.addAll(Arrays.asList(interceptors));
}
}
return interceptorList;
}
在ProxyFactoryBean的getObject方法中有对advisor进行初始化。在initializeAdvisorChain方法中有
private synchronized void initializeAdvisorChain() throws AopConfigException, BeansException {
if (this.advisorChainInitialized) {
return;
}
if (!ObjectUtils.isEmpty(this.interceptorNames)) {
if (this.beanFactory == null) {
throw new IllegalStateException("No BeanFactory available anymore (probably due to serialization) " +
"- cannot resolve interceptor names " + Arrays.asList(this.interceptorNames));
}
if (this.interceptorNames[this.interceptorNames.length - 1].endsWith(GLOBAL_SUFFIX) &&
this.targetName == null && this.targetSource == EMPTY_TARGET_SOURCE) {
throw new AopConfigException("Target required after globals");
}
for (String name : this.interceptorNames) {
if (logger.isTraceEnabled()) {
logger.trace("Configuring advisor or advice '" + name + "'");
}
if (name.endsWith(GLOBAL_SUFFIX)) {
if (!(this.beanFactory instanceof ListableBeanFactory)) {
throw new AopConfigException(
"Can only use global advisors or interceptors with a ListableBeanFactory");
}
addGlobalAdvisor((ListableBeanFactory) this.beanFactory,
name.substring(0, name.length() - GLOBAL_SUFFIX.length()));
}
else {
Object advice;//需要对Bean的类型进行判断,是单件类型还是prototype类型
if (this.singleton || this.beanFactory.isSingleton(name)) {
//这里是取得advisor的地方,是通过beanFactory取得的,把interceptorNames这个List中的interceptor名字交个beanFactory
//然后通过调用BeanFactory的getBean去获取
advice = this.beanFactory.getBean(name);
}
else {
advice = new PrototypePlaceholderAdvisor(name);
}
addAdvisorOnChainCreation(advice, name);//取得advice后,由interceptName和advice来决定一个advisor并添加到拦截器链中 }
}
}
this.advisorChainInitialized = true;
}
Advice通知的实现
在前面的注册器中,使用的是GlobalAdvisorAdapterRegistry来完成适配器的适配和注册。它的getInterceptors方法封装这advice织入实现的入口。
GlobalAdvisorAdapterRegistry的实现很简单,它起到的是一个适配器的作用,同时也是一个单件模式的应用。
public abstract class GlobalAdvisorAdapterRegistry {
private static AdvisorAdapterRegistry instance = new DefaultAdvisorAdapterRegistry();
public static AdvisorAdapterRegistry getInstance() {
return instance;
}
static void reset() {
instance = new DefaultAdvisorAdapterRegistry();
}
}
这是一个单件模式的实现,它使用静态类变量来保持一个唯一的实例。然后通过getInstance方法返回单件DefaultAdvisorAdapterRegister对象。
在DefaultAdvisorAdapterRegister对象中,设置了一系列的adapter适配器,正是这些adapter适配器的实现,为Spring AOP的advice提供编织能力。
public class DefaultAdvisorAdapterRegistry implements AdvisorAdapterRegistry, Serializable {
//定义一个AdvisorAdapter的List,这个List中的Adapter是与实现Spring AOP的advice增强功能是相对应的
private final List<AdvisorAdapter> adapters = new ArrayList<AdvisorAdapter>(3);
/**
* 这里把已有的advice实现的Adapter加入进来,这里有MethodBeforeAdviceAdapter、AfterReturningAdviceAdapter、ThrowsAdviceAdapter这些AOP的advice封装
* AOP的advice封装实现
*/
public DefaultAdvisorAdapterRegistry() {
registerAdvisorAdapter(new MethodBeforeAdviceAdapter());
registerAdvisorAdapter(new AfterReturningAdviceAdapter());
registerAdvisorAdapter(new ThrowsAdviceAdapter());
}
@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);
}
@Override
public MethodInterceptor[] getInterceptors(Advisor advisor) throws UnknownAdviceTypeException {
List<MethodInterceptor> interceptors = new ArrayList<MethodInterceptor>(3);
Advice advice = advisor.getAdvice();//从Advisor通知器配置中取得advice通知
if (advice instanceof MethodInterceptor) {//如果通知是MethodInterceptor的类型,直接加入interceptors的list中,不需要适配
interceptors.add((MethodInterceptor) advice);
}
//对通知进行适配,使用已经配置好的Adapter:MethodBeforeAdviceAdapter、AfterReturningAdviceAdapter、ThrowsAdviceAdapter,
//然后从对应的adapter中取出封装好AOP编织功能的拦截器
for (AdvisorAdapter adapter : this.adapters) {
if (adapter.supportsAdvice(advice)) {
interceptors.add(adapter.getInterceptor(advisor));
}
}
if (interceptors.isEmpty()) {
throw new UnknownAdviceTypeException(advisor.getAdvice());
}
return interceptors.toArray(new MethodInterceptor[interceptors.size()]);
}
@Override
public void registerAdvisorAdapter(AdvisorAdapter adapter) {
this.adapters.add(adapter);
}
}
以MethodBeforeAdviceAdapter为例来说明advice的实现原理。MethodBeforeAdviceAdapter的实现:
class MethodBeforeAdviceAdapter implements AdvisorAdapter, Serializable {
@Override
public boolean supportsAdvice(Advice advice) {
return (advice instanceof MethodBeforeAdvice);
}
@Override
public MethodInterceptor getInterceptor(Advisor advisor) {
MethodBeforeAdvice advice = (MethodBeforeAdvice) advisor.getAdvice();
return new MethodBeforeAdviceInterceptor(advice);
}
} 在这里的getInterceptor中,返回的是new MethodBeforeAdviceInterceptor(advice),MethodBeforeAdviceInterceptor完成的是对MethodBeforeAdvice的封装,可以在
MethodBeforeAdviceInterceptor设计的invoke回调方法中,看到首先触发了advice的before回调,然后才是MethodInvocation的proceed方法调用。在这里和前面的
ReflectiveMethodInvocation的proceed联系起来了
public class MethodBeforeAdviceInterceptor implements MethodInterceptor, Serializable {
private MethodBeforeAdvice advice;
/**
* 为指定的Advice创建对应的MethodBeforeInterceptor对象
* @param advice the MethodBeforeAdvice to wrap
*/
public MethodBeforeAdviceInterceptor(MethodBeforeAdvice advice) {
Assert.notNull(advice, "Advice must not be null");
this.advice = advice;
}
//这个invoke方法是拦截器的回调方法,会在代理对象的方法被调用时触发回调
@Override
public Object invoke(MethodInvocation mi) throws Throwable {
this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis() );
return mi.proceed();
}
}
在AopProxy代理对象触发的ReflectiveMethodInvocation的proceed方法中,在取得拦截器以后,启动了对拦截器invoke方法的调用。按照AOP的配置规则,ReflectiveMethodInvocation触发的拦截器invoke方法,最终会根据不同的advice类型,触发Spring对不同的advice的拦截器的封装,比如对MethodBeforeAdvice,最终
会触发MethodBeforeAdviceInterceptor的invoke方法。在该方法中,会先调用advice的before方法,这就是MethodBeforeAdvice所需要的对目标对象的增强效果;在方法调用之前完成通知增强。
相关文章推荐
- spring AOP中对拦截器调用的实现
- Spring AOP拦截器调用实现
- spring AOP中对拦截器调用的实现
- Spring源代码解析(七):Spring AOP中对拦截器调用的实现
- Spring源代码解析(七):Spring AOP中对拦截器调用的实现
- Spring AOP框架学习笔记(2):AOP拦截器调用的实现
- spring AOP中对拦截器调用的实现
- spring AOP中对拦截器调用的实现
- spring AOP中对拦截器调用的实现
- Spring源代码解析(七):Spring AOP中对拦截器调用的实现
- spring AOP中对拦截器调用的实现
- Spring Aop 实现拦截器功能之基础 - 001
- Spring AOP深入理解之拦截器调用
- Spring学习总结(15)——Spring AOP 拦截器的基本实现
- Spring AOP进行日志记录,管理 (使用Spring的拦截器功能获取对action中每个方法的调用情况,在方法调用前和调用后记录相关日志。)
- Spring源码分析----建立AopProxy代理对象和AOP拦截器的调用
- Spring AOP进行日志记录,管理 (使用Spring的拦截器功能获取对action中每个方法的调用情况,在方法调用前和调用后记录相关日志。)
- Spring AOP进行日志记录,管理 (使用Spring的拦截器功能获取对action中每个方法的调用情况,在方法调用前
- 从零开始学 Java - Spring AOP 拦截器的基本实现
- 使用Spring AOP前置通知实现提高方法调用的安全性能