Spring AOP:基本概念,基础接口,基础类,基本流程

12 篇文章 0 订阅

一、基本概念

Aspect:切面就是一个关注点的模块化,如事务管理、日志管理、权限管理等;

JoinPoint:程序执行的一个点,如方法的执行或者异常的捕获;

Advice:在特定的连接点执行的操作,包括Before,After,Around等类型;

PointCut:描述某一类指定的连接点,Advice通过联系PointCut在任何匹配PointCut的连接点执行Adivce操作;

Advisor:一个特定的Aspect,只包含一个Advice。这是Spring AOP的概念;

Introduction:Spring提供的允许声明额外方法和字段代表一个类型,Spring允许为任意的advised对象引入一个新的接口。

Target:目标对象,被代理(advised)的目标对象。

上面基本概念有些是Spring自定义的,如Advisor,有些是抽象出了类的,有些只是一个概念(如JoinPoint是程序执行的一个点,这个没法通过抽象形成类。)

二、基础接口和基础类

Pointcut:PointCut在Spring中抽象出来的一个类,定义了那些连接点需要被织入横切逻辑。Spring中PointCut结构如下


Advice系列:Spring抽象出来的通知接口和类,Adivce子接口分别有AfterAdvice,BeforeAdvice和Interceptor。Spring类图如下:


Advisor:Advisor是Spring AOP 的一个切面,但只包含一个PointCut和一个Advice。Advisor是切面的一个特例,通过跟踪AdvisedSupport源码可以发现,一个Advisor链表其实就是实现了Aspect的功能。所以Advisor可以看成是Aspect的一个单元吧;

SpringProxy:SpringAOP代理类的一个表示,所有Spring代理类都实现了这个接口;

Advised:AOP代理的一个接口,它的实现类管理AOP配置,如Interceptors,advice,Advisors和被代理的接口。Spring代理类都能够类型转换成Advised类型;

AdvisedSupport:AOP代理配置管理的基础类,继承ProxyConfig并且实现了Advised接口;

ProxyCreatorSupport:代理工程基础类,主要是支持配置和访问AopProxyFactory;

ProxyFactory:代理工厂,提供编程式的Srping AOP应用,其实声明式的Spring AOP照样是要引用它来实现的(这是显然的,声明了最后还是得通过编程式的类来执行的);

AopProxy:AOP代理的一个委托接口,CglibAopProxy,JdkDynamicAopProxy实现这个接口;

CglibAopProxy:基于Cglib代理的Spring AOP代理类,getProxy,getCallbacks是核心方法;

ObjenesisCglibAopProxy:CglibAopProxy的子类,定义了DynamicAdvisedInterceptor等回调类,其中intercept方法是核心。

JdkDynamicAopProxy:基于JDK 动态代理的Spring AOP代理类,其中getProxy,invoke是核心;

AopProxyFactory:被用来通过工厂模式实现基于(AdvisedSupport)配置创建对应代理类的基础接口。

DefaultAopProxyFactory:AopProxyFactory的默认实现类;

AdvisorChainFactory:advisor链的工厂接口。提供getInterceptorsAndDynamicInterceptionAdvice目标对象方法执行的切面;

DefaultAdvisorChainFactory:AdvisorChainFactory的默认实现类;

ReflectiveMethodInvocation:提供反射调用目标对象的功能。

ProxyFactoryBean:提供声明式的SpringAOP引用。

三、代理类创建流程

1、ProxyFactory创建代理类是利用AOPProxyFactory进行的,ProxyFactory继承ProxyCreatorSupport,ProxyCreatorSupport通过getAOPProxyFactory()方法获取到AOPProxyFactory对象,AOPProxyFactory创建对应的AopProxy实现类,AopProxy实现类通过getProxy()方法返回代理对象。下面分别是ProxyFactory的结构和AopProxy接口及其实现类的结构图。

 


2、ProxyFactory获取代理类对象源码

public ObjectgetProxy() {
//调用父类的createAopProxy返回AOPProxy实现类,通过实现类创建并返回代理对应
returncreateAopProxy().getProxy();
}

3、ProxyFactory父类ProxyCreatorSupport的createAopProxy()方法源码,看出来它其实是依赖aopProxyFactory完成创建对应AOPProxy实现类对象的

public classProxyCreatorSupport extends AdvisedSupport {
//AOPProxy工厂
privateAopProxyFactory aopProxyFactory;
//当第一个AOPProxy代理对象被创建时,设置为true
private booleanactive = false;
publicAopProxyFactory getAopProxyFactory() {
returnthis.aopProxyFactory;
}
//默认使用DefaultAopProxyFactory作用AOP代理工厂
publicProxyCreatorSupport() {
this.aopProxyFactory= new DefaultAopProxyFactory();
}
//创建AOPProxy代理的入口方法
protected finalsynchronized AopProxy createAopProxy() {
if(!this.active) {
activate();
}
//调用DefaultAopProxyFactory的创建AOPProxy代理的方法
returngetAopProxyFactory().createAopProxy(this);
}
//激活AOP代理配置,向容器注册代理回调监听器,第一次创建AOP代理时调用
private voidactivate() {
this.active= true;
for(AdvisedSupportListener listener : this.listeners) {
listener.activated(this);
}
}
……
}
 

4、AopProxyFactory对象通常是DefaultAopProxyFactory对象,DefaultAopProxyFactory主要源码

public classDefaultAopProxyFactory implements AopProxyFactory, Serializable {
//判断CGLIB类库是否在classpath中
private static finalboolean cglibAvailable =
ClassUtils.isPresent("net.sf.cglib.proxy.Enhancer",DefaultAopProxyFactory.class.getClassLoader());
//创建AOP代理对象
public AopProxycreateAopProxy(AdvisedSupport config) throws AopConfigException {
//如果AOP使用显式优化,或者配置了目标类,或者只使用Spring支持的代理接口
if(config.isOptimize() || config.isProxyTargetClass() ||hasNoUserSuppliedProxyInterfaces(config)) {
//获取AOP配置的目标类
ClasstargetClass = config.getTargetClass();
if(targetClass == null) {
thrownew AopConfigException("TargetSource cannot determine target class: "+
"Eitheran interface or a target is required for proxy creation.");
}
//如果配置的AOP目标类是接口,则使用JDK动态代理机制来生成AOP代理
if(targetClass.isInterface()) {
returnnew JdkDynamicAopProxy(config);
}
//如果AOP配置的目标类不是接口,则使用CGLIB的方式来生成AOP代理
if(!cglibAvailable) {
thrownew AopConfigException(
"Cannotproxy target class because CGLIB2 is not available. " +
"AddCGLIB to the class path or specify proxy interfaces.");
}
returnCglibProxyFactory.createCglibProxy(config);
}
else{
returnnew JdkDynamicAopProxy(config);
}
}
//判断AOP是否只配置了SpringProxy代理接口或者没有配置任何代理接口
privateboolean hasNoUserSuppliedProxyInterfaces(AdvisedSupport config) {
//获取AOP配置的所有AOP代理接口
Class[]interfaces = config.getProxiedInterfaces();
return(interfaces.length == 0 || (interfaces.length == 1 &&SpringProxy.class.equals(interfaces[0])));
}
}
 

5、JdkDynamicAopProxy通过JDK提供的动态代理创建代理类,通过源码看看其实现过程

final classJdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializable {
……
//JdkDynamicAopProxy的构造方法
publicJdkDynamicAopProxy(AdvisedSupport config) throws AopConfigException {
Assert.notNull(config,"AdvisedSupport must not be null");
//获取AOPBeanFactory中配置的通知器链和目标源
if(config.getAdvisors().length == 0 && config.getTargetSource() ==AdvisedSupport.EMPTY_TARGET_SOURCE) {
thrownew AopConfigException("No advisors and no TargetSource specified");
}
//为当前对象设置AOP配置
this.advised= config;
}
//获取AOP代理对象的入口方法
publicObject getProxy() {
returngetProxy(ClassUtils.getDefaultClassLoader());
}
//创建AOP代理对象
publicObject getProxy(ClassLoader classLoader) {
if(logger.isDebugEnabled()) {
logger.debug("CreatingJDK dynamic proxy: target source is " + this.advised.getTargetSource());
}
//获取AOPBeanFactory中配置的代理接口
Class[]proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised);
//查找代理目标的接口中是否定义equals()和hashCode()方法
findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
//使用JDK的动态代理机制创建AOP代理对象
returnProxy.newProxyInstance(classLoader, proxiedInterfaces, this);
}
//查找给定类或接口中是否定义了equals()和hashCode()方法
privatevoid findDefinedEqualsAndHashCodeMethods(Class[] proxiedInterfaces) {
//遍历给定的类/接口数组
for(Class proxiedInterface : proxiedInterfaces) {
//或者给定类/接口中所有声明的方法
Method[]methods = proxiedInterface.getDeclaredMethods();
//遍历类/接口中的声明的方法
for(Method method : methods) {
//如果方法是equals()方法,则设置当前对象equalsDefined属性
if(AopUtils.isEqualsMethod(method)) {
this.equalsDefined= true;
}
//如果方法是hashCode()方法,则设置当前对象hashCodeDefined属性
if(AopUtils.isHashCodeMethod(method)) {
this.hashCodeDefined= true;
}
if(this.equalsDefined && this.hashCodeDefined) {
return;
}
}
}
}
……
}<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);"> </span>

6、通过ObjenesisCglibAopProxy创建代理类源码,目标对象没有接口的就通过Cglib生成,注意的是如果方法为final是不能够被代理的,final类不能够被继承类@Override

//通过CGLIB方式创建AOP代理对象
public ObjectgetProxy(ClassLoader classLoader) {
if(logger.isDebugEnabled()) {
logger.debug("CreatingCGLIB2 proxy: target source is " + this.advised.getTargetSource());
}
try{
//从代理创建辅助类中获取在IoC容器中配置的目标对象
ClassrootClass = this.advised.getTargetClass();
Assert.state(rootClass!= null, "Target class must be available for creating a CGLIBproxy");
//将目标对象本身做为自己的基类
ClassproxySuperClass = rootClass;
//检查获取到的目标类是否是CGLIB产生的
if(AopUtils.isCglibProxyClass(rootClass)) {
//如果目标类是有CGLIB产生的,获取目标类的基类
proxySuperClass= rootClass.getSuperclass();
//获取目标类的接口
Class[]additionalInterfaces = rootClass.getInterfaces();
//将目标类的接口添加到容器AOP代理创建辅助类的配置中
for(Class additionalInterface : additionalInterfaces) {
this.advised.addInterface(additionalInterface);
}
}
//校验代理基类
validateClassIfNecessary(proxySuperClass);
//配置CGLIB的Enhancer类,Enhancer是CGLIB中的主要操作类
Enhancerenhancer = createEnhancer();
if(classLoader != null) {
enhancer.setClassLoader(classLoader);
if(classLoader instanceof SmartClassLoader &&
((SmartClassLoader)classLoader).isClassReloadable(proxySuperClass)) {
enhancer.setUseCache(false);
}
}
//设置enhancer的基类
enhancer.setSuperclass(proxySuperClass);
enhancer.setStrategy(newUndeclaredThrowableStrategy(UndeclaredThrowableException.class));
//设置enhancer的接口        enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised));
enhancer.setInterceptDuringConstruction(false);
//设置enhancer的回调方法
Callback[]callbacks = getCallbacks(rootClass);
enhancer.setCallbacks(callbacks);
//将通知器中配置作为enhancer的方法过滤
enhancer.setCallbackFilter(newProxyCallbackFilter(
this.advised.getConfigurationOnlyCopy(),this.fixedInterceptorMap, this.fixedInterceptorOffset));
Class[]types = new Class[callbacks.length];
for(int x = 0; x < types.length; x++) {
types[x]= callbacks[x].getClass();
}
//设置enhancer的回调类型
enhancer.setCallbackTypes(types);
//创建代理对象
Objectproxy;
if(this.constructorArgs != null) {
proxy= enhancer.create(this.constructorArgTypes, this.constructorArgs);
}
else{
proxy= enhancer.create();
}
returnproxy;
}
catch(CodeGenerationException ex) {
thrownew AopConfigException("Could not generate CGLIB subclass of class ["+
this.advised.getTargetClass()+ "]: " +
"Commoncauses of this problem include using a final class or a non-visibleclass",
ex);
}
catch(IllegalArgumentException ex) {
thrownew AopConfigException("Could not generate CGLIB subclass of class ["+
this.advised.getTargetClass()+ "]: " +
"Commoncauses of this problem include using a final class or a non-visibleclass",
ex);
}
catch(Exception ex) {
//TargetSource.getTarget() failed
thrownew AopConfigException("Unexpected AOP exception", ex);
}
}
//获取给定类的回调通知
 private Callback[] getCallbacks(ClassrootClass) throws Exception {
//优化参数
booleanexposeProxy = this.advised.isExposeProxy();
booleanisFrozen = this.advised.isFrozen();
booleanisStatic = this.advised.getTargetSource().isStatic();
//根据AOP配置创建一个动态通知拦截器,CGLIB创建的动态代理会自动调用
//DynamicAdvisedInterceptor类的intercept方法对目标对象进行拦截处理
CallbackaopInterceptor = new DynamicAdvisedInterceptor(this.advised);
CallbacktargetInterceptor;
//根据是否暴露代理,创建直接应用目标的通知
if(exposeProxy) {
targetInterceptor= isStatic ?
newStaticUnadvisedExposedInterceptor(this.advised.getTargetSource().getTarget()) :
newDynamicUnadvisedExposedInterceptor(this.advised.getTargetSource());
}
else{
targetInterceptor= isStatic ?
newStaticUnadvisedInterceptor(this.advised.getTargetSource().getTarget()) :
newDynamicUnadvisedInterceptor(this.advised.getTargetSource());
}
//创建目标分发器
CallbacktargetDispatcher = isStatic ?
newStaticDispatcher(this.advised.getTargetSource().getTarget()) : newSerializableNoOp();
Callback[]mainCallbacks = new Callback[]{
aopInterceptor,//普通通知
targetInterceptor,// 如果优化则不考虑配置的通知
newSerializableNoOp(), //没有被覆盖的方法
targetDispatcher,this.advisedDispatcher,
newEqualsInterceptor(this.advised),
newHashCodeInterceptor(this.advised)
};
Callback[]callbacks;
//如果目标是静态的,并且通知链被冻结,则使用优化AOP调用,直接对方法使用
//固定的通知链
if(isStatic && isFrozen) {
Method[]methods = rootClass.getMethods();
Callback[]fixedCallbacks = new Callback[methods.length];
this.fixedInterceptorMap= new HashMap<String, Integer>(methods.length);
for(int x = 0; x < methods.length; x++) {
List<Object>chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(methods[x],rootClass);
fixedCallbacks[x]= new FixedChainStaticTargetInterceptor(
chain,this.advised.getTargetSource().getTarget(), this.advised.getTargetClass());
this.fixedInterceptorMap.put(methods[x].toString(),x);
}
//将固定回调和主要回调拷贝到回调数组中
callbacks= new Callback[mainCallbacks.length + fixedCallbacks.length];
System.arraycopy(mainCallbacks,0, callbacks, 0, mainCallbacks.length);
System.arraycopy(fixedCallbacks,0, callbacks, mainCallbacks.length, fixedCallbacks.length);
this.fixedInterceptorOffset= mainCallbacks.length;
}
//如果目标不是静态的,或者通知链不被冻结,则使用AOP主要的通知
else{
callbacks= mainCallbacks;
}
returncallbacks;
}

四、代理类被创建后调用过程源码分析

代理类被创建后调用方法是如何执行Advice和Intercepter的呢,JdkDynamicAopProxy和CglibAopProxy创建代理对象时都注册了回调函数,JdkDynamicAopProxy实现,InvocationHandler接口,当代理对象方法被调用时就会调用InvocationHandler.invoke()方法。CglibAopProxy在创建带理对象时也通过Enhancer对象注册了回调函数,这些回调函数如DynamicAdvisedInterceptor继承了MethodInterceptor接口,当代理对象的方法被调用时回执行DynamicAdvisedInterceptor.intercept()方法。

1、JdkDynamicAopProxy invoke()方法源码分析

final classJdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializable {
……
//AOP代理对象的回调方法
publicObject invoke(Object proxy, Method method, Object[] args) throws Throwable {
MethodInvocationinvocation;
ObjectoldProxy = null;
booleansetProxyContext = false;
//获取通知的目标源
TargetSourcetargetSource = this.advised.targetSource;
ClasstargetClass = null;
Objecttarget = null;
try{
//如果代理目标对象的接口中没有定义equals()方法,且当前调用的方法
//是equals()方法,即目标对象没有自己实现equals()方法
if(!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
returnequals(args[0]);
}
//如果代理目标对象的接口中没有定义hashCode()方法,且当前调用的方法
//是hashCode()方法,即目标对象没有自己实现hashCode()方法
if(!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
returnhashCode();
}
//如果AOP配置了通知,使用反射机制调用通知的同名方法
if(!this.advised.opaque && method.getDeclaringClass().isInterface()&&                                method.getDeclaringClass().isAssignableFrom(Advised.class)){
returnAopUtils.invokeJoinpointUsingReflection(this.advised, method, args);
}
ObjectretVal;
//如果当前通知暴露了代理,则将当前代理使用currentProxy()方法变为可用代理
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()) {
//没有配置通知,使用反射直接调用目标对象的方法,并获取方法返回值
retVal= AopUtils.invokeJoinpointUsingReflection(target, method, args);
}
//如果配置了通知
else{
//为目标对象创建方法回调对象,需要在调用通知之后才调用目标对象的方法
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;
}
returnretVal;
}
finally{
if(target != null && !targetSource.isStatic()) {
//释放目标对象
targetSource.releaseTarget(target);
}
if(setProxyContext) {
//存储代理对象
AopContext.setCurrentProxy(oldProxy);
}
}
}
……
}

2、DynamicAdvisedInterceptor intercept方法源码分析

//CGLIB回调AOP拦截器链
public Objectintercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy)throws Throwable {
ObjectoldProxy = null;
booleansetProxyContext = false;
ClasstargetClass = null;
Objecttarget = null;
try{
//如果通知器暴露了代理
if(this.advised.exposeProxy) {
//设置给定的代理对象为要被拦截的代理                                                                         oldProxy =AopContext.setCurrentProxy(proxy);
setProxyContext= true;
}
//获取目标对象
target= getTarget();
if(target != null) {
targetClass= target.getClass();
}
//获取AOP配置的通知
List<Object>chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method,targetClass);
ObjectretVal;
//如果没有配置通知
if(chain.isEmpty() && Modifier.isPublic(method.getModifiers())) {
//直接调用目标对象的方法
retVal= methodProxy.invoke(target, args);
}
//如果配置了通知
else{
//通过CglibMethodInvocation来启动配置的通知
retVal= new CglibMethodInvocation(proxy, target, method, args, targetClass, chain,methodProxy).proceed();
}
//获取目标对象对象方法的回调结果,如果有必要则封装为代理
retVal= massageReturnTypeIfNecessary(proxy, target, method, retVal);
returnretVal;
}
finally{
if(target != null) {
releaseTarget(target);
}
if(setProxyContext) {
//存储被回调的代理
AopContext.setCurrentProxy(oldProxy);
}
}
}

五、ReflectiveMethodInvocation处理通知器链

JdkDynamicAopProxy 和CglibAopProxy创建AOPProxy代理对象,以及对目标对象的通知器回调我们了解到,当目标对象配置了通知器时,在对目标对象方法调用前首先需要回调通知器链,JdkDynamicAopProxy和CglibAopProxy都是通过将目标对象方法、方法参数、和通知器链、代理对象等封装为ReflectiveMethodInvocation类,然后通过ReflectiveMethodInvocation.proceed()方法调用通知器链,proceed方法源码如下:

//通用通知器链
public Objectproceed() throws Throwable {
//如果拦截器链中通知已经调用完毕
if(this.currentInterceptorIndex ==this.interceptorsAndDynamicMethodMatchers.size() - 1) {
//这个方法调用AopUtils.invokeJoinpointUsingReflection方法,
//通过反射机制直接调用目标对象方法
returninvokeJoinpoint();
}
//获取拦截器链中的通知器或通知
ObjectinterceptorOrInterceptionAdvice=           this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
//如果获取的通知器或通知是动态匹配方法拦截器类型
if(interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher){
//动态匹配方法拦截器
InterceptorAndDynamicMethodMatcherdm =
    (InterceptorAndDynamicMethodMatcher)interceptorOrInterceptionAdvice;
if(dm.methodMatcher.matches(this.method, this.targetClass, this.arguments)) {
//如果匹配,调用拦截器的方法
returndm.interceptor.invoke(this);
}
else{
//如果不匹配,递归调用proceed()方法,知道拦截器链被全部调用为止
returnproceed();
}
}
else{
//如果不是动态匹配方法拦截器,则切入点在构造对象之前进行静态匹配,调用
//拦截器的方法
return((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
}
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值