本章接上一章讲,所需jar包和xml的命名引用已经弄好:
https://blog.csdn.net/qq_34598667/article/details/83417459
本章我们讲解xml的方式实现aop
Spring使用AspectJ进行AOP的开发:XML的方式
学习本章需要先知道这些内容:
通知类型
前置通知:在目标方法执行之前执行.
后置通知:在目标方法执行之后执行
环绕通知:在目标方法执行前和执行后执行
异常抛出通知:在目标方法执行出现异常的时候执行
最终通知:无论目标方法是否出现异常最终通知都会执行.
切入点语法表达式
语法:execution(表达式)
表达式语法:[方法访问修饰符] 方法返回值包名.类名.方法名(方法的参数)
-
例1:
execution (* com.oak.service.impl.UserServiceImpl.*(…)) :匹配UserServiceImpl类中声明的所有方法。
第一个 * :代表任意修饰符及任意返回值类型
第二个 * :代表任意方法,
… :匹配任意数量任意类型的参数,若目标类与该切面在同一个包中,可以省略包名。 -
例2:execution public double cn.itcast.service.impl.PersonServiceImpl.*(…):匹配PersonServiceImpl类中返回值类型为double类型的所有公有方法。
下面开始我们的案例:
1)导入jar包和引入xml命名空间
上一章已经写好
2)编写目标类
1)创建接口UserService
public interface UserService {
void save();
void update();
void delete();
void find();
}
2)编写实现类
public class UserServiceImpl implements UserService{
@Override
public void save() {
System.out.println("I am the method for save ");
}
@Override
public void update() {
System.out.println("I am the method for update ");
}
@Override
public void delete() {
System.out.println("I am the method for delete ");
}
@Override
public void find() {
System.out.println("I am the method for find ");
}
}
3)在xml中配置目标类
<!--配置目标类 -->
<bean id="userService" class="com.oak.service.UserServiceImpl"></bean>
4)编写一个切面类
public class MyAspect {
public void doBeforeCheck() {
System.out.println("前置通知");
}
public void doAfterReturning() {
System.out.println("后置通知");
}
public void doAfter() {
System.out.println("最终通知");
}
public void doAfterThrowing() {
System.out.println("异常通知");
}
public Object doBasicProfiling(ProceedingJoinPoint pjp) throws Throwable {
System.out.println("进入方法");
Object result = pjp.proceed();
System.out.println("退出方法");
return result;
}
}
5)在xml配置文件中完成通知(增强)配置
从上可知MyAspect不过就是一个普通的JavaBean。现在要使用Spring配置文件实现AOP,使它变成为一个切面:
<!--配置切面类-->
<bean id="myAspect" class="com.oak.aop.MyAspect"></bean>
<!--进行aop的配置-->
<aop:config>
<!--配置切入点表达式:哪些类的哪些方法需要进行增强 这里给UserService的save方法进行增强 -->
<aop:pointcut expression="execution(* com.oak.service.UserService.save(..))" id="pointcut1"/>
<!--配置切面-->
<aop:aspect ref="myAspect">
<!-- 指定before前置通知的方式是切面中的doAccessCheck方法 -->
<aop:before method="doBeforeCheck" pointcut-ref="pointcut1"/>
</aop:aspect>
</aop:config>
6)测试
在com.oak.test中新建SpringAOPTest,新建aopXmlTest为:
@Test
public void aopXmlTest(){
ApplicationContext cxt =
new ClassPathXmlApplicationContext
("applicationContext.xml");
UserService userService=cxt.getBean("userService",UserService.class);
userService.save();
}
控制台结果为:
前置通知
I am the method for save
在执行目标类的save方法前执行了代理了的前置通知。
7)其他通知(增强)的配置
修改xml,给UserService中的所有方法添加通知
<!--进行aop的配置-->
<aop:config>
<!--配置切入点表达式:哪些类的哪些方法需要进行增强 这里给UserService的save方法进行增强 -->
<aop:pointcut expression="execution(* com.oak.service.UserService.save(..))" id="pointcut1"/>
<!-- 给所有的方法增强 -->
<aop:pointcut expression="execution(* com.oak.service.UserService.*(..))" id="pointcut2"/>
<!--配置切面-->
<aop:aspect ref="myAspect">
<!-- 指定before前置通知的方式是切面中的doAccessCheck方法 -->
<aop:before method="doBeforeCheck" pointcut-ref="pointcut1"/>
<!-- 指定after-returning后置通知的方式是切面中的doAfterReturning方法 -->
<aop:after-returning method="doAfterReturning" pointcut-ref="pointcut2"/>
<!-- 异常通知 -->
<aop:after-throwing method="doAfterThrowing" pointcut-ref="pointcut2"/>
<!-- 最终通知 -->
<aop:after method="doAfter" pointcut-ref="pointcut2"/>
</aop:aspect>
</aop:config>
修改测试类:
@Test
public void aopXmlTest(){
ApplicationContext cxt =
new ClassPathXmlApplicationContext
("applicationContext.xml");
UserService userService=cxt.getBean("userService",UserService.class);
userService.save();
userService.delete();
}
控制台结果为:
前置通知
I am the method for save
后置通知
最终通知
I am the method for delete
后置通知
最终通知