基于XML的AOP开发
快速入门
- 导入AOP相关坐标
- 创建目标接口和目标类(内部有切点)
- 创建切面类(内部有增强方法)
- 将目标类和切面类的对象创建权交给spring
- 在applicationContext中配置织入关系
- 测试代码
pom.xml:
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.0.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.4</version>
</dependency>
<!-- spring集成junit-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.0.5.RELEASE</version>
</dependency>
</dependencies>
目标类Target:
package com.example.aop;
public class Target implements TargetInterface {
@Override
public void save() {
System.out.println("save running....");
}
}
切面类MyAspect:
package com.example.aop;
public class MyAspect {
public void before() {
System.out.println("前置增强......");
}
}
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">
<!-- 目标对象 -->
<bean id="target" class="com.example.aop.Target"></bean>
<!-- 切面对象 -->
<bean id="myAspect" class="com.example.aop.MyAspect"></bean>
<!-- 配置织入:告诉spring框架 哪些方法(切点)需要进行哪些增强(前置、后置) -->
<aop:config>
<!--声明切面-->
<aop:aspect ref="myAspect">
<!-- 切面:切点+通知 -->
<aop:before method="before" pointcut="execution(public void com.example.aop.Target.save())"/>
</aop:aspect>
</aop:config>
</beans>
AopTest:
package com.example.test;
import com.example.aop.TargetInterface;
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:applicationContext.xml")
public class AopTest {
@Autowired
private TargetInterface target;
@Test
public void test1() {
target.save();
}
}
控制台输出:
前置增强......
save running....
XML配置AOP详解
切点表达式的写法
表达式语法:
execution([修饰符] 返回值类型 包名.类名.方法名(参数))
- 访问修饰符可以省略不写
- 返回值类型、包名、类名、方法名可以使用星号 * 代表任意
- 包名与类名之间一个点 . 代表当前包下的类;两个点 … 表示当前包及其子包下的类
- 参数列表可以使用两个点 … 表示任意个数、任意类型的参数列表
例如:
execution(public void com.example.aop.Target.save())
execution(void com.example.aop.Target.*(..))
execution(* com.example.aop.*.*(..))
execution(* com.example.aop..*.*(..))
execution(* *..*.*(..))
通知的类型
通知的配置语法:
<aop:通知类型 method="切面类中方法名" pointcut="切点表达时"/>
注意 环绕通知 的切面类MyAspect:
//ProceedingJoinPoint:正在执行的连接点===切点
public Object around(ProceedingJoinPoint pjp) throws Throwable {
System.out.println("环绕前增强......");
Object proceed = pjp.proceed();//切点方法
System.out.println("环绕后增强......");
return proceed;
}
切点表达时的抽取
抽取后使用pointcut-ref属性代替pointcut属性来引用抽取后的切点表达式。
<!-- 抽取切点表达式-->
<aop:pointcut id="myPointcut" expression="execution(* com.example.aop.*.*(..))"/>
<!-- 切面:切点+通知 -->
<aop:around method="around" pointcut-ref="myPointcut"></aop:around>