案例之前,我们先了解一下spring的几个术语

1、切面(aspect):切面类,里面包含通知方法。

2、切点(pointcut):又名切点表达式,目标:找到符合条件的方法。

3、目标(target):被织入的类,目标类。

4、连接点(join point):目标方法。

5、通知(advice):切面类的before或其它方法。

6、aop代理(aopProxy):spring aop的实现就是靠代理来做到的,默认利用jdk代理和cglib代理。

7、织入(weaving):动词:将切面类的方法和目标类的连接点糅合在一起的过程就叫织入。

导入需要的依赖:pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>spring-test-taskFour</artifactId>
        <groupId>com.lw</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
<artifactId>mybatis-spring-aop2</artifactId>

<dependencies>
    <!--切面需要的依赖-->
    <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjweaver</artifactId>
    </dependency>
    <!--spring依赖-->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
    </dependency>
    <!--测试依赖-->
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
    </dependency>
</dependencies>
</project>

切面类:

package com.aspect;

public class LogImpl {
    //通知
    public void beforeInsert(){
        System.out.println("beforeInsert as LogImpl");
    }
}

目标类:

package com.target;

public class StudentDaoImpl {
    //此类没有实现接口,所以使用cglib代理的方法创建出aop代理
    //实现接口会使用jdk代理方法创建aop代理

    //连接点方法若是加了final修饰符的话,无法创建aop代理
    //连接点
    public void insert(){
        System.out.println("insert as StudentDaoImpl");
    }
}

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 https://www.springframework.org/schema/aop/spring-aop.xsd">
    <!--先把bean创建出来-->
    <bean id="log" class="com.aspect.LogImpl"></bean>
    <bean id="studentDao" class="com.target.StudentDaoImpl"></bean>
    <!--以aop:config开始配置-->
    <aop:config>
        <!--配置目标类,expression是切点表达式,这里的意思是匹配com.target包
的StudentDaoImpl类的所有方法,第一个*号的意思是所有方法返回值,包括void-->
        <aop:pointcut id="studentPointcut" expression="execution(* com.target.StudentDaoImpl.*())"/>
        <!--配置切点类-->
        <aop:aspect id="logAspect" ref="log">
            <!--配置连接点,和目标-->
            <aop:before method="beforeInsert" pointcut-ref="studentPointcut"/>
        </aop:aspect>
    </aop:config>
</beans>

测试类:

package com.test;

import com.target.StudentDaoImpl;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class TestAspect {

    @Test
    public void test_Aspect(){
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        StudentDaoImpl studentDao = context.getBean("studentDao",StudentDaoImpl.class);
        studentDao.insert();
    }
}

测试结果:

BeforeInsert as LogImpl

insert as StudentDaoImpl

可以看到我们的连接点方法成功切入了目标类。

01-10 09:28