Spring 源码粘贴6 AOP

来源:互联网 发布:怎么拍下淘宝里的货 编辑:程序博客网 时间:2024/06/05 09:27

AOP

记得导入AspectJ的jar包

        <dependency>            <groupId>org.aspectj</groupId>            <artifactId>aspectjrt</artifactId>            <version>1.8.9</version>        </dependency>        <dependency>            <groupId>org.aspectj</groupId>            <artifactId>aspectjweaver</artifactId>            <version>1.7.4</version>        </dependency>

Advice通知

BeforeAdvice


MethodBeforeAdvice 方法前置通知. 在方法调用前的增强接口.内部就一个方法

public interface MethodBeforeAdvice extends BeforeAdvice {/** * Callback before a given method is invoked. * @param method method being invoked * @param args arguments to the method * @param target target of the method invocation. May be {@code null}. * @throws Throwable if this object wishes to abort the call. * Any exception thrown will be returned to the caller if it's * allowed by the method signature. Otherwise the exception * will be wrapped as a runtime exception. */void before(Method method, Object[] args, Object target) throws Throwable;}

当Advice配置到方法上后,作为回调函数,在方法被调用前执行.

对应还有AfterAdvice

继承关系多些


常用这个AfterReturningAdvice

/** * After returning advice is invoked only on normal method return, not if an * exception is thrown. Such advice can see the return value, but cannot change it. * * @author Rod Johnson * @see MethodBeforeAdvice * @see ThrowsAdvice */public interface AfterReturningAdvice extends AfterAdvice {/** * Callback after a given method successfully returned. * @param returnValue the value returned by the method, if any * @param method method being invoked * @param args arguments to the method * @param target target of the method invocation. May be {@code null}. * @throws Throwable if this object wishes to abort the call. * Any exception thrown will be returned to the caller if it's * allowed by the method signature. Otherwise the exception * will be wrapped as a runtime exception. */void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable;}

ThrowsAdvice 接口内并没有待实现的方法.在方法抛出异常时执行.

/** * Tag interface for throws advice. * * <p>There are not any methods on this interface, as methods are invoked by * reflection. Implementing classes must implement methods of the form: * * <pre class="code">void afterThrowing([Method, args, target], ThrowableSubclass);</pre> * * <p>Some examples of valid methods would be: * * <pre class="code">public void afterThrowing(Exception ex)</pre> * <pre class="code">public void afterThrowing(RemoteException)</pre> * <pre class="code">public void afterThrowing(Method method, Object[] args, Object target, Exception ex)</pre> * <pre class="code">public void afterThrowing(Method method, Object[] args, Object target, ServletException ex)</pre> * * The first three arguments are optional, and only useful if we want further * information about the joinpoint, as in AspectJ <b>after-throwing</b> advice. * * <p><b>Note:</b> If a throws-advice method throws an exception itself, it will * override the original exception (i.e. change the exception thrown to the user). * The overriding exception will typically be a RuntimeException; this is compatible * with any method signature. However, if a throws-advice method throws a checked * exception, it will have to match the declared exceptions of the target method * and is hence to some degree coupled to specific target method signatures. * <b>Do not throw an undeclared checked exception that is incompatible with * the target method's signature!</b> * * @author Rod Johnson * @author Juergen Hoeller * @see AfterReturningAdvice * @see MethodBeforeAdvice */public interface ThrowsAdvice extends AfterAdvice {}
直接通过反射来调用对应的方法.方法参数中必须含有一个异常的子类.

Pointcut切入点

决定Advice通知在何处发挥作用


/** * Core Spring pointcut abstraction. * * <p>A pointcut is composed of a {@link ClassFilter} and a {@link MethodMatcher}. * Both these basic terms and a Pointcut itself can be combined to build up combinations * (e.g. through {@link org.springframework.aop.support.ComposablePointcut}). * * @author Rod Johnson * @see ClassFilter * @see MethodMatcher * @see org.springframework.aop.support.Pointcuts * @see org.springframework.aop.support.ClassFilters * @see org.springframework.aop.support.MethodMatchers */public interface Pointcut {/** * Return the ClassFilter for this pointcut. * @return the ClassFilter (never {@code null}) */ClassFilter getClassFilter();/** * Return the MethodMatcher for this pointcut. * @return the MethodMatcher (never {@code null}) */MethodMatcher getMethodMatcher();/** * Canonical Pointcut instance that always matches. */Pointcut TRUE = TruePointcut.INSTANCE;}
我们通过这个MethodMather对象来判断处理是否匹配切入点.

看这个类 JdkRegexpMethodPointcut 

public class JdkRegexpMethodPointcut extends AbstractRegexpMethodPointcut {private Pattern[] compiledPatterns = new Pattern[0];private Pattern[] compiledExclusionPatterns = new Pattern[0];@Overrideprotected void initPatternRepresentation(String[] patterns) throws PatternSyntaxException {this.compiledPatterns = compilePatterns(patterns);}@Overrideprotected void initExcludedPatternRepresentation(String[] excludedPatterns) throws PatternSyntaxException {this.compiledExclusionPatterns = compilePatterns(excludedPatterns);}@Overrideprotected boolean matches(String pattern, int patternIndex) {Matcher matcher = this.compiledPatterns[patternIndex].matcher(pattern);return matcher.matches();}@Overrideprotected 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;}}
这个类的方法都是和匹配相关的,而getMethodMatch()在基类中实现了


public abstract class StaticMethodMatcherPointcut extends StaticMethodMatcher implements Pointcut {private ClassFilter classFilter = ClassFilter.TRUE;public void setClassFilter(ClassFilter classFilter) {this.classFilter = classFilter;}@Overridepublic ClassFilter getClassFilter() {return this.classFilter;}@Overridepublic final MethodMatcher getMethodMatcher() {return this;}}

而且这个基类还继承了自实现MethodMatch接口的类


NameMatchPointcut匹配方法名是否相同

public boolean matches(Method method, Class<?> targetClass) {for (String mappedName : this.mappedNames) {if (mappedName.equals(method.getName()) || isMatch(method.getName(), mappedName)) {return true;}}return false;}


Advisor通知器 将Advice和Pointcut粘起来,在切入点将通知埋好,使得通知到正确的时候触发.

DefaultPointcutAdvisor

public class DefaultPointcutAdvisor extends AbstractGenericPointcutAdvisor implements Serializable {private Pointcut pointcut = Pointcut.TRUE;/** * Create an empty DefaultPointcutAdvisor. * <p>Advice must be set before use using setter methods. * Pointcut will normally be set also, but defaults to {@code Pointcut.TRUE}. */public DefaultPointcutAdvisor() {}/** * Create a DefaultPointcutAdvisor that matches all methods. * <p>{@code Pointcut.TRUE} will be used as Pointcut. * @param advice the Advice to use */public DefaultPointcutAdvisor(Advice advice) {this(Pointcut.TRUE, advice);}/** * Create a DefaultPointcutAdvisor, specifying Pointcut and Advice. * @param pointcut the Pointcut targeting the Advice * @param advice the Advice to run when Pointcut matches */public DefaultPointcutAdvisor(Pointcut pointcut, Advice advice) {this.pointcut = pointcut;setAdvice(advice);}/** * Specify the pointcut targeting the advice. * <p>Default is {@code Pointcut.TRUE}. * @see #setAdvice */public void setPointcut(Pointcut pointcut) {this.pointcut = (pointcut != null ? pointcut : Pointcut.TRUE);}@Overridepublic Pointcut getPointcut() {return this.pointcut;}@Overridepublic String toString() {return getClass().getName() + ": pointcut [" + getPointcut() + "]; advice [" + getAdvice() + "]";}}
Pointcut TRUE = TruePointcut.INSTANCE;
返回的是一个单例

class TruePointcut implements Pointcut, Serializable {public static final TruePointcut INSTANCE = new TruePointcut();/** * Enforce Singleton pattern. */private TruePointcut() {}@Overridepublic ClassFilter getClassFilter() {return ClassFilter.TRUE;}@Overridepublic MethodMatcher getMethodMatcher() {return MethodMatcher.TRUE;}/** * Required to support serialization. Replaces with canonical * instance on deserialization, protecting Singleton pattern. * Alternative to overriding {@code equals()}. */private Object readResolve() {return INSTANCE;}@Overridepublic String toString() {return "Pointcut.TRUE";}}
进去看看,最后
MethodMatcher TRUE = TrueMethodMatcher.INSTANCE;
class TrueMethodMatcher implements MethodMatcher, Serializable {public static final TrueMethodMatcher INSTANCE = new TrueMethodMatcher();@Overridepublic boolean matches(Method method, Class<?> targetClass) {return true;}}
ClassFilter TRUE = TrueClassFilter.INSTANCE;
class TrueClassFilter implements ClassFilter, Serializable {@Overridepublic boolean matches(Class<?> clazz) {return true;}}
就是全部都匹配的意思









原创粉丝点击