IT@程序员猿媛

【Spring 笔记】AOP 基础相关整理

2020-02-11  本文已影响0人  58bc06151329

文前说明

作为码农中的一员,需要不断的学习,我工作之余将一些分析总结和学习笔记写成博客与大家一起交流,也希望采用这种方式记录自己的学习之旅。

本文仅供学习交流使用,侵权必删。
不用于商业目的,转载请注明出处。

1. 概述

2. 原理

2.1 Joinpoint(连接点)

// TestService.java
public interface TestService {

    void save(String name);

    void update(String name);

    void delete(String name);

    String findOne(String name);

    List<String> findAll();
}

// TestServiceImpl.java
public class TestServiceImpl implements TestService {

    public void save(String name) {// 连接点
    }

    public void update(String name) {// 连接点
    }

    public void delete(String name) {// 连接点
    }

    public String findOne(String name) {// 连接点
        System.out.println("TestServiceImpl`s findOne");
        return "";
    }

    public List<String> findAll() {// 连接点
        System.out.println("TestServiceImpl`s findAll");
        return new ArrayList<String>();
    }
}
// Joinpoint.java
public interface Joinpoint {

    // 用于执行拦截器链中的下一个拦截器逻辑
    Object proceed() throws Throwable;

    Object getThis();

    AccessibleObject getStaticPart();

}
// Invocation.java
public interface Invocation extends Joinpoint {
    Object[] getArguments();
}

// MethodInvocation.java
public interface MethodInvocation extends Invocation {
    Method getMethod();
}

2.2 Pointcut(切点)

// Pointcut.java
public interface Pointcut {

    // 返回一个类型过滤器
    ClassFilter getClassFilter();

    // 返回一个方法匹配器
    MethodMatcher getMethodMatcher();

    Pointcut TRUE = TruePointcut.INSTANCE;
}
// ClassFilter.java
public interface ClassFilter {
    boolean matches(Class<?> clazz);
    ClassFilter TRUE = TrueClassFilter.INSTANCE;

}

// MethodMatcher.java
public interface MethodMatcher {
    boolean matches(Method method, Class<?> targetClass);
    boolean matches(Method method, Class<?> targetClass, Object... args);
    boolean isRuntime();
    MethodMatcher TRUE = TrueMethodMatcher.INSTANCE;
}
AspectJExpressionPointcut 体系

2.3 Advice(通知)

通知类型 何时调用
前置通知(Before advice) 在目标方便调用前执行通知。
后置通知(After advice) 在目标方法完成后执行通知。
返回通知(After returning advice) 在目标方法执行成功后,调用通知。
异常通知(After throwing advice) 在目标方法抛出异常后,执行通知。
环绕通知(Around advice) 在目标方法调用前后均可执行自定义逻辑。
// Advice.java
public interface Advice {
}

// BeforeAdvice.java
public interface BeforeAdvice extends Advice {

}

// MethodBeforeAdvice.java
public interface MethodBeforeAdvice extends BeforeAdvice {

    void before(Method method, Object[] args, Object target) throws Throwable;
}

// AfterAdvice.java
public interface AfterAdvice extends Advice {

}

// AfterReturningAdvice.java
public interface AfterReturningAdvice extends AfterAdvice {

    void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable;
}
AspectJMethodBeforeAdvice 体系

2.4 Aspect(切面)

// Advisor.java
public interface Advisor {

    Advice getAdvice();
    boolean isPerInstance();
}
// PointcutAdvisor.java
public interface PointcutAdvisor extends Advisor {

    Pointcut getPointcut();
}
// TestService.java
public interface TestService {

    void save(String name);

    void update(String name);

    void delete(String name);

    String findOne(String name);

    List<String> findAll();
}

// TestServiceImpl.java
public class TestServiceImpl implements TestService {

    public void save(String name) {
    }

    public void update(String name) {
    }

    public void delete(String name) {
    }

    public String findOne(String name) {
        System.out.println("TestServiceImpl`s findOne");
        return "";
    }

    public List<String> findAll() {
        System.out.println("TestServiceImpl`s findAll");
        return new ArrayList<String>();
    }
}

// AopTest.java
public class AopTest {

    public void before() {
        System.out.println("AopTest`s before");
    }

    public void after() {
        System.out.println("AopTest`s after");
    }
}

// Test.java
public class Test {

    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
        TestService testService = (TestService) context.getBean("testServiceImpl");
        testService.findAll();
    }
}

/* print
AopTest`s before
TestServiceImpl`s findAll
AopTest`s after
*/
<!-- spring.xml -->
<aop:aspectj-autoproxy/>
<bean id="testServiceImpl" class="spring.test.aop.TestServiceImpl"/>
<bean id="aopTest" class="spring.test.aop.AopTest"/>
    <aop:config expose-proxy="true">
        <aop:aspect ref="aopTest">
            <!-- pointcut -->
            <aop:pointcut id="testPointcut" expression="execution(* spring.test.aop.*.find*(..))" />

            <!-- advoce -->
            <aop:before method="before" pointcut-ref="testPointcut"/>
            <aop:after method="after" pointcut-ref="testPointcut"/>
        </aop:aspect>
    </aop:config>
转换成两个 PointcutAdvisor

2.5 Weaving(织入)

上一篇 下一篇

猜你喜欢

热点阅读