Spring AOP的实现之一AOP相关概念

AOP是Aspect-Oriented Programming(面向方面编程或面向切面)的简称。

Aspect是一种新的模块化机制,用来描述分散在对象、类或函数中的横切关注点。从关注点中分离出横切关注点是面向切面的程序设计

的核心概念。分离关注点使解决特定问题的代码从业务逻辑中独立出来,业务逻辑的代码中不再含有针对特定领域问题代码的调用,业

务逻辑同特定领域问题的关系通过切面来封装、维护,这样原本分散在整个应用程序中的变动就可以很好地管理起来。


AOP实现的三个步骤:

      1.代理对象的生成。2.拦截器的使用。3.Aspect编织的实现,实现真正的拦截。


AOP的相关概念

一   Advice通知

      Advice(通知)定义在连接点做什么,为切面增强提供接口。在Spring AOP中,它主要描述Spring AOP围绕方法调用而注入的切面行为。

Advice是AOP联盟定义的一个接口。具体的接口定义在org.aopalliance.aop;

    package org.aopalliance.aop;

    public interface Advice {
    }
      在Spring AOP的实现中,使用了这个统一的接口,并通过这个接口为AOP切面增强的织入功能做了更多的扩展。比如提供了更具体的通

织类型,比如BeforeAdvice,AfterAdvice,ThrowsAdvice等。

      在BeforeAdvice继承关系中,BeforeAdvice继承了Advice,MethodBeforeAdvice继承了BeforeAdvice,MethodBeforeAdvice接口定义了

为待增强的目标方法设置的前置增强。

     

   package org.springframework.aop;

   import java.lang.reflect.Method;

   public interface MethodBeforeAdvice extends BeforeAdvice {
         /*
          *Method对象:目标方法的反射对象;Object[]对象数组,这个对象中包含目标方法的输入参数。
          */
         void before(Method method, Object[] args, Object target) throws Throwable;
   }
      作为回调函数,before函数的实现在Advic中被配置到目标方法后,会在调用目标方法时被调用。
     在AfterAdvice的继承关系中,有一系列对AfterReturing的实现和扩展,比如AfterReturningAdvice就是其中比较常用的一个。

    

    package org.springframework.aop;

    import java.lang.reflect.Method;
    public interface AfterReturningAdvice extends AfterAdvice {
	   void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable;

    }
     afterReturning方法也是一个回调函数,AOP应用需要在这个接口实现中提供切面增强的具体设计,在这个Advice通知被正确配置以后,在目标方法调用

结束并成功返回的时候,接口会被Spring AOP回调。

    还有一种通知是ThrowAdvice,并没有指定需要实现的接口方法,它在抛出异常时被回调,这个回调是AOP使用反射机制来完成的。

  public interface ThrowsAdvice extends AfterAdvice {

  }
 

二   PointCut切点

   PointCut(切点)决定Advice通知应该作用于哪个连接点,也就是说通过PiontCut切点来定义需要增强的方法的集合。

   在PointCut基本接口定义源码:

   

   public interface Pointcut {

	ClassFilter getClassFilter();
	MethodMatcher getMethodMatcher();
	Pointcut TRUE = TruePointcut.INSTANCE;
   }
   在接口定义中需要返回一个MethodMatcher。PointCut的匹配判断功能,具体是由这个返回的MethodMatcher来完成,也就是说由MethodMatcher来

判断是否需要对当前方法调用增强功能,或者是否需要对当前调用方法应用配置好的Advice通知。  

   package org.springframework.aop;
   import java.lang.reflect.Method;
   public interface MethodMatcher {
	boolean matches(Method method, Class<?> targetClass);
	boolean isRuntime();
	boolean matches(Method method, Class<?> targetClass, Object[] args);
	MethodMatcher TRUE = TrueMethodMatcher.INSTANCE;
   }

以JdkRegexpMethodPointcut的实现原理为例,来了解PointCut的工作原理。JdkRegexpMethodPointcut完成通过正则表达式来对方法名进行匹配。其继承关系如下

StaticmethodMatcher继承MethodMatcher,JdkRegexpMethodPointcut继承StaticmethodMatcher。

public abstract class StaticMethodMatcher implements MethodMatcher {

	@Override
	public final boolean isRuntime() {
		return false;
	}

	@Override
	public final boolean matches(Method method, Class<?> targetClass, Object[] args) {
		// should never be invoked because isRuntime() returns false
		throw new UnsupportedOperationException("Illegal MethodMatcher usage");
	}

}
public class JdkRegexpMethodPointcut extends AbstractRegexpMethodPointcut {

	private Pattern[] compiledPatterns = new Pattern[0];
	private Pattern[] compiledExclusionPatterns = new Pattern[0];

	@Override
	protected void initPatternRepresentation(String[] patterns) throws PatternSyntaxException {
		this.compiledPatterns = compilePatterns(patterns);
	}

	@Override
	protected void initExcludedPatternRepresentation(String[] excludedPatterns) throws PatternSyntaxException {
		this.compiledExclusionPatterns = compilePatterns(excludedPatterns);
	}

	@Override
	protected boolean matches(String pattern, int patternIndex) {
		Matcher matcher = this.compiledPatterns[patternIndex].matcher(pattern);
		return matcher.matches();
	}
        //这个matcher方法就是使用正则表达式对方法名进行匹配的地方
	@Override
	protected boolean matchesExclusion(String candidate, int patternIndex) {
		Matcher matcher = this.compiledExclusionPatterns[patternIndex].matcher(candidate);
		return matcher.matches();
	}
	private Pattern[] compilePatterns(String[] source) throws PatternSyntaxException {
		Pattern[] destination = new Pattern[source.length];
		for (int i = 0; i < source.length; i++) {
			destination[i] = Pattern.compile(source[i]);
		}
		return destination;
	}

}

其实AOP框架中对matches方法的调用,是在JdkDynamicAopProxy的invoke方法中触发的。这个在以后的分析进行叙述。


三 Advisor通知器

     完成对目标方法的切面增强设计(Advice)和关注点的设计(Pointcut)以后,需要一个对象将它们结合起来,完成这个作用的就是Advisor(通知器)。通过Advisor,可以定义应该使用哪个通知并在哪个关注点使用它,也就是通过Advisor,把Advisor和Pointcut结合起来,这个结合为IoC容器配置AOP应用提供了便利。

    以一个Advisor的实例(DefaultPointcutAdvisor)来了解Advisor的工作原理。

   

package org.springframework.aop.support;

import java.io.Serializable;

import org.aopalliance.aop.Advice;

import org.springframework.aop.Pointcut;
public class DefaultPointcutAdvisor extends AbstractGenericPointcutAdvisor implements Serializable {

	private Pointcut pointcut = Pointcut.TRUE;

        //DefaultPointcutAdvisor有两个属性,pointcut和advice,其中advice定义在其父类AbstractGenericPointcutAdvisor中 
        public DefaultPointcutAdvisor() {
	}
	public DefaultPointcutAdvisor(Advice advice) {
		this(Pointcut.TRUE, advice);
	}

	public DefaultPointcutAdvisor(Pointcut pointcut, Advice advice) {
		this.pointcut = pointcut;
		setAdvice(advice);
	}

	public void setPointcut(Pointcut pointcut) {
		this.pointcut = (pointcut != null ? pointcut : Pointcut.TRUE);
	}

	@Override
	public Pointcut getPointcut() {
		return this.pointcut;
	}


	@Override
	public String toString() {
		return getClass().getName() + ": pointcut [" + getPointcut() + "]; advice [" + getAdvice() + "]";
	}

}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值