AOP底层动态代理的实现我们昨天测试过了,那么理解的具体就是给我们原来的目标对象提供一个增强或者是通知,让它的执行更符合我们需要的功能业务的需求,不过那些复杂的底层原理代码spring框架会给我们封装使用,目前可以使用xml文件配置以及注解的方式实现AOP开发。
基于xml文件配置的AOP开发步骤测试
① 导入 AOP 相关坐标
② 创建目标接口和目标类(内部有切点)
③ 创建切面类(内部有增强方法)
④ 将目标类和切面类的对象创建权交给 spring
⑤ 在 applicationContext.xml 中配置织入关系
⑥ 测试代码
1、在pom文件导入AOP相关坐标
<!-- 配置AOP开发的坐标-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.16</version>
</dependency>
<!-- spring不排除任何优秀的框架,aspectj框架在AOP开发方面更轻,spring集成它给我们使用-->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.8</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.3.16</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
2、创建目标对象的接口与实现接口类(内部含有切入点(可增强的方法又称为切入点,目标对象的方法我们成为连接点))
public interface targetInterface {
void save();
void delete();
}
public class target implements targetInterface {
@Override
public void save() {
System.out.println("目标对象的功能save执行.....");
}
@Override
public void delete() {
System.out.println("目标对象的功能delete执行.....");
}
}
3、创建切面类(内部含有增强方法)
public class myAspect {
public void before(){
System.out.println("前置增强....");
}
public void after(){
System.out.println("后置增强....");
}
public void bye(){
System.out.println("增强结束....");
}
public Object around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
System.out.println("环绕保护进程....");
Object proceed = proceedingJoinPoint.proceed();
System.out.println("运行完毕!保护结束....");
return proceed;
}
}
4、javabean的配置(xml配置)
<!--配置目标对象与切面对象bean-->
<bean id="target" class="com.hlc.aop.target"/>
<bean id="aspect" class="com.hlc.aop.myAspect"/>
5、配置织入关系(xml配置)
<!--配置织入:告诉框架目标对象的哪些方法需要哪些增强?(前置增强、后置增强等)-->
<aop:config>
<!--声明切面-->
<aop:aspect ref="aspect">
<!--切点加通知连接起来-->
<!--这个标签的含义就是前置增强方法是id为aspect的bean的一个before方法,切点表达式execution(public void com.hlc.aop.target.save())的含义:增强的切入点是公开类target的save方法-->
<aop:before method="before" pointcut = "execution(public void com.hlc.aop.target.save())"></aop:before>
</aop:aspect>
</aop:config>
6、测试类
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:spring-aop.xml")
public class aopTest {
@Autowired
private targetInterface target;
@Test
public void test1(){
target.save();
}
@Test
public void test2(){
target.delete();
}
}
7、测试结果:
切点表达式:
表达式语法:execution([修饰符] 返回值类型 包名.类名.方法名(参数))
- 访问修饰符可以省略
- 返回值类型、包名、类名、方法名可以使用星号* 代表任意
- 包名与类名之间一个点 . 代表当前包下的类,两个点 .. 表示当前包及其子包下的类
- 参数列表可以使用两个点 .. 表示任意个数,任意类型的参数列表
通知或者增强的标签语法:
通知的配置语法:<aop:通知类型 method=“切面类中方法名” pointcut=“切点表达式"/>
- 前置通知 <aop:before>: 用于配置前置通知。指定增强的方法在切入点方法之前执行
- 后置通知 <aop:after-returning>: 用于配置后置通知。指定增强的方法在切入点方法之后执行
- 环绕通知 <aop:around>:用于配置环绕通知。指定增强的方法在切入点方法之前和之后都执行
- 异常抛出通知 <aop:throwing>: 用于配置异常抛出通知。指定增强的方法在出现异常时执行
- 最终通知 <aop:after> :用于配置最终通知。无论增强方式执行是否有异常都会执行