Spring-xml实现AOP
AOP相关概念
Spring的AOP实现底层就是对上面的动态代理进行了封装。
- Target(代理对象):代理的目标对象
- Proxy(代理):一个类被AOP织入增强后,就产生一个结果代理类
- Joinpoint(连接点):被拦截到的点(方法),spring只支持方法类型的连接点
- Pointcut(切入点):指对哪些Joinpoint进行拦截的定义
- Advice(通知/增强):拦截Joinpoint之后要做的事
- Aspect(切面):切入点和通知的结合
- Weaving(织入):指把增强应用到目标对象来创建新的代理对象的过程
xml实现AOP
1. 导入相关坐标
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.17</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.9</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.3.17</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
2. 创建目标接口和目标类(内部有切点)
package com.sjj.aop;
public interface TargetInterface {
public void print_hello();
}
package com.sjj.aop;
public class Target implements TargetInterface{
@Override
public void print_hello() {
System.out.println("HHHHHello");
}
}
3. 创建切面类(内部有增强方法)
package com.sjj.aop;
public class MyAspect {
public void before(){
System.out.println("=====前置增强=====");
}
}
4. 将目标类和切面类的对象创建权交给spring
<!--目标对象-->
<bean id="target" class="com.sjj.aop.Target"/>
<!--切面对象-->
<bean id="myAspect" class="com.sjj.aop.MyAspect"/>
5. 在appContext.xml中配置织入关系
<!--配置织入:增强方法-->
<aop:config>
<!--声明切片-->
<aop:aspect ref="myAspect">
<!--切点、通知-->
<aop:before method="before" pointcut="execution(public void com.sjj.aop.Target.print_hello())" />
</aop:aspect>
</aop:config>
6. 测试代码
package com.sjj.aop;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:appContext.xml")
public class AopTest {
@Autowired
private TargetInterface target;
@Test
public void test_aop01(){
target.print_hello();
}
}
配置解析
切点表达式
execution([修饰符] 返回值类型 包名.类名.方法名(参数))
- 访问修饰符可省略
- 返回值类型、包名、类名、方法名可用 * 表示任意
- 包名和类之间的 . 表示当前包下的类。两个点 .. 表示包及其子包下的类
- 参数列表可以使用 .. 表示任意个数任意类型的参数
所以你甚至可以这么写(bushi
execution(* *..*.*(..))
通知
<aop:通知类型 method="切面类中的方法名" pointcut="切点表达式"></aop:通知类型>
| 名称 | 标签 | 说明 |
|---|---|---|
| 前置 | <aop:before> | 切入点方法之前 |
| 后置 | <aop:after-returning> | 切入点方法之后 |
| 环绕 | <aop:around> | 切入点方法前后都执行 |
| 异常抛出 | <aop:throwing> | 出现异常时执行 |
| 最终 | <aop:after> | 最终通知,无论是否有异常都执行 |
浙公网安备 33010602011771号