Spring AOP所使用的到的原理就是采取一种代理模式,spring AOP中提供了两种方式产生代理对象:jdk动态代理和CGLIB代理。这两者的优势和局限性在这里不做讨论。
一、代理对象的生成
Spring AOP模块中,一个主要的部分就是代理对象的生成,从中Spring AOP(一) 基本概念和例子我们可以知道,可以通过配置和调用Spring的ProxyFactoryBean来完成这个任务。当然Spring AOP中提供了多种方式来生成代理对象。下面给出主要的继承关系(并非全部继承关系)
- ProxyConfig:可以看成是一个数据基类,这个数据基类为ProxyFactoryBean这样的子类提供了配置属性。
- AdvisedSupport:封装了AOP对通知和通知器的相关操作,这些操作对于不同的AOP的代理对象的生成都是一样的,对于具体的AOP代理对象的创建,AdvisedSupport把它交给它的子类们去完成。
- ProxyCreatorSupport:可以看作是其子类创建AOP代理对象的一个辅助类。
- AspectJProxyFactory、ProxyFactory、ProxyFactoryBean:分别是具体AOP代理对象生成的类。对于需要使用AspectJ的AOP应用,AspectJProxyFactory起到了集成Spring和AspectJ的作用;对于使用Spring AOP的应用,ProxyFactoryBean和ProxyFactory都提供了AOP功能的封装,不同在于ProxyFactoryBean提供了IoC容器声明式配置,而ProxyFactory需要编程式的使用Spring AOP的功能。
- AbstractSingletonProxyFactoryBean:抽象类,用于只生成单例的代理工厂bean。
- TransactionProxyFactoryBean:简化的声明式事务处理的代理工厂bean。
具体的AOP代理对象的生成,可以根据不同需要,采取上述的一些实现类去生成,在这里我们以ProxyFactoryBean作为例子来具体看看Spring AOP代理对象的生成。ProxyFactoryBean继承了FactoryBean,它是一个工厂bean,我们知道工厂bean实例化的时候回调用到getObject()方法
public Object getObject() throws BeansException {
//初始化Advisor链
initializeAdvisorChain();
if (isSingleton()) {
//单例
return getSingletonInstance();
}
else {
if (this.targetName == null) {
logger.warn("Using non-singleton proxies with singleton targets is often undesirable. " +
"Enable prototype proxies by setting the 'targetName' property.");
}
//非单例
return newPrototypeInstance();
}
}
1. 初始化advisor链
initializeAdvisorChain()所做的工作很简单,就是将ProxyFactoryBean配置中的interceptorNames列表加入到advisors列表中(其中的advice将会自动封装成advisor)。
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));
}
// Globals can't be last unless we specified a targetSource using the property...
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");
}
// 这里是添加Advisor链的调用,是通过interceptorNames属性进行配置的
for (int i = 0; i < this.interceptorNames.length; i++) {
String name = this.interceptorNames[i];
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 = null;
//singletion类型bean
if (this.singleton || this.beanFactory.isSingleton(this.interceptorNames[i])) {
// Add the real Advisor/Advice to the chain.
advice = this.beanFactory.getBean(this.interceptorNames[i]);
}
else {
//对prototype类型的bean的处理
advice = new PrototypePlaceholderAdvisor(this.interceptorNames[i]);
}
//将advisor加入到advisor链中,其中advice会被封装成advisor后添加
addAdvisorOnChainCreation(advice, this.interceptorNames[i]);
}
}
}
this.advisorChainInitialized = true;
}
具体的过程会调用到
//advisorAdapterRegistry实例是DefaultAdvisorAdapterRegistry对象
this.advisorAdapterRegistry.wrap(next);
DefaultAdvisorAdapterRegistry对象用于注册AdviceAdapter对象,每一种AdviceAdapter用于判断advice是不是属于该AdviceAdapter所对应的advice以及用于将advice转换成相应的拦截器。Spring中一种advice都有相应与之对应的AdviceAdapter和拦截器对应。
public class DefaultAdvisorAdapterRegistry implements AdvisorAdapterRegistry, Serializable {
private final List adapters = new ArrayList(3);
//注册已知的AdviceAdapter,每一种advice对应一种AdviceAdapter,Spring AOP默认提供了下面三种AdviceAdapter
public DefaultAdvisorAdapterRegistry() {
registerAdvisorAdapter(new MethodBeforeAdviceAdapter());
registerAdvisorAdapter(new AfterReturningAdviceAdapter());
registerAdvisorAdapter(new ThrowsAdviceAdapter());
}
//这里就是将advice封装成advisor
public Advisor wrap(Object adviceObject) throws UnknownAdviceTypeException {
//如果已经是advisor对象了,就直接返回
if (adviceObject instanceof Advisor) {
return (Advisor) adviceObject;
}
if (!(adviceObject instanceof Advice)) {
throw new UnknownAdviceTypeException(adviceObject);
}
Advice advice = (Advice) adviceObject;
//如果这个advice已经是一个拦截器了,
if (advice instanceof MethodInterceptor) {
// So well-known it doesn't even need an adapter.
return new DefaultPointcutAdvisor(advice);
}
for (int i = 0; i < this.adapters.size(); i++) {
// Check that it is supported.
AdvisorAdapter adapter = (AdvisorAdapter) this.adapters.get(i);
if (adapter.supportsAdvice(advice)) {
return new DefaultPointcutAdvisor(advice);
}
}
throw new UnknownAdviceTypeException(advice);
}
public MethodInterceptor[] getInterceptors(Advisor advisor) throws UnknownAdviceTypeException {
List interceptors = new ArrayList(3);
Advice advice = advisor.getAdvice();
if (advice instanceof MethodInterceptor) {
interceptors.add(advice);
}
//通过adapter将advice封装成对应的拦截器
for (int i = 0; i < this.adapters.size(); i++) {
AdvisorAdapter adapter = (AdvisorAdapter) this.adapters.get(i);
if (adapter.supportsAdvice(advice)) {
interceptors.add(adapter.getInterceptor(advisor));
}
}
if (interceptors.isEmpty()) {
throw new UnknownAdviceTypeException(advisor.getAdvice());
}
return (MethodInterceptor[]) interceptors.toArray(new MethodInterceptor[interceptors.size()]);
}
public void registerAdvisorAdapter(AdvisorAdapter adapter) {
this.adapters.add(adapter);
}
}
现在我们就以MethodBeforeAdvice为例子来看看advice对应的Adapter以及Interceptor长的什么样子
//MethodBeforeAdvice对应的MethodBeforeAdviceAdapter
class MethodBeforeAdviceAdapter implements AdvisorAdapter, Serializable {
//判断是不是MethodBeforeAdvice
public boolean supportsAdvice(Advice advice) {
return (advice instanceof MethodBeforeAdvice);
}
//将MethodBeforeAdvice封装成MethodBeforeAdviceInterceptor
public MethodInterceptor getInterceptor(Advisor advisor) {
MethodBeforeAdvice advice = (MethodBeforeAdvice) advisor.getAdvice();
return new MethodBeforeAdviceInterceptor(advice);
}
}
//MethodBeforeAdvice对应的MethodBeforeAdviceInterceptor
public class MethodBeforeAdviceInterceptor implements MethodInterceptor, Serializable {
private MethodBeforeAdvice advice;
//通过MethodBeforeAdvice封装成拦截器
public MethodBeforeAdviceInterceptor(MethodBeforeAdvice advice) {
Assert.notNull(advice, "Advice must not be null");
this.advice = advice;
}
//拦截器主要的调用逻辑,MethodBeforeAdviceInterceptor的逻辑很简单,就是在调用方法之前,先调用MethodBeforeAdvice的before方法
public Object invoke(MethodInvocation mi) throws Throwable {
this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis() );
return mi.proceed();
}
}
上面我们已经讲了初始化advisor链的过程中,只是简单的将advisor加入到advisor链中,其中如果传进去的是一个advice,则通过DefaultAdvisorAdapterRegistry这个一个默认实现将advice封装成advisor然后加入到advisor链中(DefaultAdvisorAdapterRegistry通过注册在对象里面的AdviceAdapter来判断是否是支持的advice类型)。我们都知道Spring AOP使用到了代理以及拦截器技术,上面我也讲了Advice、AdviceAdaptor以及AdviceInterceptor之间的关系,代理对象中只是将advice封装成了advisor,这么做的好处是什么呢?等整个AOP过程分析完之后,再做讨论。
2.代理对象生成
代理对象的生成就是通过AopProxy取得的,在Spring AOP中提供了两种方式的AopProxy:jdk的AopProxy和CGLIB的AopProxy,分别为JdkDynamicAopProxy和Cglib2AopProxy。具体采用哪种方式的AopProxy呢?
首先,我们在看看上面ProxyFactoryBean中提供的getObject()方法,取得实例的两种情况:Singleton和Prototype。不管哪种方式,我们看到,取得AopProxy的方式都是通过调用到AopProxyFactory接口的默认实现类DefaultAopProxyFactory中的createAopProxy方法
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.");
}
return CglibProxyFactory.createCglibProxy(config);
}
else {
return new JdkDynamicAopProxy(config);
}
}
从上面代码我们可以很清楚的看到Spring AOP才用两种方式生成代理的条件,默认采取jdk动态代理,如果这个类没有接口或者在config中配置了满足上述条件的属性,那么就走cglib的方式,当然如果目标类本身就是接口,那么也走jdk动态代理(其中的原因是cglib采取的继承的方式)。
接下来,通过AopProxy取得代理对象的过程就是jdk以及cglib如何生成代理对象的过程了,在这里我们不做讨论。
protected Object getProxy(AopProxy aopProxy) {
//通过jdk或者cglib类型的AopProxy取得代理对象
return aopProxy.getProxy(this.proxyClassLoader);
}
二、代理方法的调用
JdkDynamicAopProxy生成代理对象的时候,会将this作为参数传入,这里的this指的是InvocationHandler类型的参数,因为JdkDynamicAopProxy实现了InvocationHandler接口,重写了invoke方法
Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
根据jdk动态代理的知识,我们可以知道,代理方法在被调用的时候会调用到JdkDynamicAopProxy中的invoke方法。cglib也会以类似的形式调用到相应拦截器中的intercept方法,在这里我们以JdkDynamicAopProxy为例子来详细看看Spring AOP代理方法调用的过程。
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
MethodInvocation invocation = null;
Object oldProxy = null;
boolean setProxyContext = false;
TargetSource targetSource = this.advised.targetSource;
Class targetClass = null;
Object target = null;
try {
//如果是equals方法、hashCode方法,并且没有定义equals、hashCode方法,就直接调用目标类中的
if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
return (equals(args[0]) ? Boolean.TRUE : Boolean.FALSE);
}
if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
return new Integer(hashCode());
}
//通过反射调用
if (!this.advised.opaque && method.getDeclaringClass().isInterface() &&
method.getDeclaringClass().isAssignableFrom(Advised.class)) {
return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);
}
Object retVal = null;
if (this.advised.exposeProxy) {
// Make invocation available if necessary.
oldProxy = AopContext.setCurrentProxy(proxy);
setProxyContext = true;
}
// May be <code>null</code>. 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();
}
//取得方法对应的拦截器(在这里会调用到DefaultAdvisorChainFactory的getInterceptorsAndDynamicInterceptionAdvice方法,这个方法中会生成拦截器)
List chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
//如果这个方法的拦截器链为空,那么直接以反射的方式调用目标对象的该方法
if (chain.isEmpty()) {
retVal = AopUtils.invokeJoinpointUsingReflection(target, method, args);
}
else {
//创建一个method invocation
invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
//执行
retVal = invocation.proceed();
}
if (retVal != null && retVal == target && method.getReturnType().isInstance(proxy) &&
!RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {
retVal = proxy;
}
return retVal;
}
finally {
if (target != null && !targetSource.isStatic()) {
// Must have come from TargetSource.
targetSource.releaseTarget(target);
}
if (setProxyContext) {
// Restore old proxy.
AopContext.setCurrentProxy(oldProxy);
}
}
}
在代理方法调用的过程中,会根据advisor获得该方法的所有拦截器,上述取得拦截器链的方法会最总调用到DefaultAdvisorChainFactory中的getInterceptorsAndDynamicInterceptionAdvice方法。
public List getInterceptorsAndDynamicInterceptionAdvice(Advised config, Method method, Class targetClass) {
List interceptorList = new ArrayList(config.getAdvisors().length);
//判断是否存在有Introduction
boolean hasIntroductions = hasMatchingIntroductions(config, targetClass);
AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance();
Advisor[] advisors = config.getAdvisors();
for (int i = 0; i < advisors.length; i++) {
Advisor advisor = advisors[i];
//生成方法的拦截器,Pointcut类型处理方式
if (advisor instanceof PointcutAdvisor) {
// Add it conditionally.
PointcutAdvisor pointcutAdvisor = (PointcutAdvisor) advisor;
if (config.isPreFiltered() || pointcutAdvisor.getPointcut().getClassFilter().matches(targetClass)) {
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 (int j = 0; j < interceptors.length; j++) {
interceptorList.add(new InterceptorAndDynamicMethodMatcher(interceptors[j], mm));
}
}
else {
interceptorList.addAll(Arrays.asList(interceptors));
}
}
}
}
//生成方法拦截器,Introduction的处理方式
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;
}
private static boolean hasMatchingIntroductions(Advised config, Class targetClass) {
for (int i = 0; i < config.getAdvisors().length; i++) {
Advisor advisor = config.getAdvisors()[i];
if (advisor instanceof IntroductionAdvisor) {
IntroductionAdvisor ia = (IntroductionAdvisor) advisor;
if (ia.getClassFilter().matches(targetClass)) {
return true;
}
}
}
return false;
}
拦截器的运行
public Object proceed() throws Throwable {
//拦截器调用完毕之后调用target方法
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);
}
}
上面会调用到拦截器的invoke方法,然后通过查看各种拦截器的invoke方法,我们可以看到拦截器链中的拦截器会被执行到,并且各个拦截器中的advice方法能保持预期的顺序执行到。
//MethodBeforeAdviceInterceptor
//调用接下来的拦截器之前先调用before方法
public Object invoke(MethodInvocation mi) throws Throwable {
this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis() );
return mi.proceed();
}
//AfterReturningAdviceInterceptor
//调用剩下的拦截器之后再调用after方法
public Object invoke(MethodInvocation mi) throws Throwable {
Object retVal = mi.proceed();
this.advice.afterReturning(retVal, mi.getMethod(), mi.getArguments(), mi.getThis());
return retVal;
}
//ThrowsAdviceInterceptor
//调用方法发生异常时执行到,注意:捕获之后接着往上抛出去
public Object invoke(MethodInvocation mi) throws Throwable { public Object invoke(MethodInvocation mi) throws Throwable {
try {
return mi.proceed();
}
catch (Throwable ex) {
Method handlerMethod = getExceptionHandler(ex);
if (handlerMethod != null) {
invokeHandlerMethod(mi, ex, handlerMethod);
}
throw ex;
}
}
try {
return mi.proceed();
}
catch (Throwable ex) {
Method handlerMethod = getExceptionHandler(ex);
if (handlerMethod != null) {
invokeHandlerMethod(mi, ex, handlerMethod);
}
throw ex;
}
}
这样 我们看到Spring AOP的整个流程。