article/java/spring aop.md
2022-08-28 14:37:13 +08:00

4.9 KiB
Raw Blame History

spring aop 面向切面编程

连接点

泛指类中的方法

切入点

被抽取了共同代码的逻辑方法

切入点一定是连接点 连接点不一定是切入点

通知

被抽取出来的 共同代码 可以认定为是一个方法

通知 按照被抽取的代码位置 分为

  1. 前置通知(Before advice) 在逻辑代码前面执行
  2. 后置通知(After (finally) advice) 在逻辑代码后面执行,不管逻辑代码是否正常执行
  3. 返回通知(After returning advice) 在逻辑代码,正常完成后执行的通知
  4. 异常通知(After throwing advice) 抛出异常后通知
  5. 环绕通知(Around Advice) 在逻辑代码前后都执行(执行两次)

引入

泛指 类中的共同的成员变量 多个通知要使用

引入 机制可以增加额外的变量

引入机制是在类的编译器 或者类加载期完成

目标对象

原始的对象抽离出共同代码后的对象

缺少完整逻辑代码的对象

代理对象

Spring 为目标对象注入通知 成为一个可以正常执行的对象

织入

将目标对象代理并注入通知的过程

切面

切面是一个设计概念,指切入点与通知的匹配模式

程序设计视可以设置多个切面,用来描述切入点与通知之间的关系。

代码

pom 文件

<properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>


        <spring.version>5.2.8.RELEASE</spring.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.11</version>
            <scope>test</scope>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.springframework/spring-aop -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aspects</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjrt</artifactId>
            <version>1.6.11</version>
        </dependency>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.6.11</version>
        </dependency>


    </dependencies>

applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
    <aop:config>
        <aop:aspect ref="advice">
            <aop:before method="printOne" pointcut="execution(public void org.example.TargetObject.print2())"/>
        </aop:aspect>
    </aop:config>
    <bean id="target" class="org.example.TargetObject"></bean>
    <bean id="advice" class="org.example.Advice"></bean>
</beans>

目标对象


package org.example;

/**
 * @author by xKing
 * @create on 2020/10/30 21:21
 */
public class TargetObject {
    public void print2() {
        System.out.println("我是目标对象");
        System.out.println("3");
    }


    public void print3() {
        System.out.println("2");
        System.out.println("3");
    }

}

### 通知对象

package org.example;

/**
 * @author by xKing
 * @create on 2020/10/30 21:22
 */
public class Advice {
    public void printOne() {
        System.out.println("我是通知");
    }
}

测试类


package org.example;

import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * Hello world!
 */
public class App {
    public static void main(String[] args) {
        ClassPathXmlApplicationContext cat = new ClassPathXmlApplicationContext("applicationContext.xml");
        Object target = cat.getBean("target");
        ((TargetObject) target).print2();
        System.out.println("Hello World!");
    }
}


输出结果

1
2
3
Hello World!

Process finished with exit code 0