spring中AOP的两种实现方式

本文详细介绍两种实现AOP(面向切面编程)的方法:通过XML配置和注解方式。包括定义接口与实现类,创建切面类,配置切点、前置、后置、环绕等通知类型,以及使用Spring框架进行AOP功能测试。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.方法一:注解实现

接口类

  1. public interface User {
  2. public void work();
  3. }

具体实现类

  1. public class IUser implements User {
  2. public void work() {
  3. System.out.println("-------工作ing----------");
  4. }
  5. }

切面类

  1. public void doBefore() {
  2. System.out.println("-------1.执行前通知--------");
  3. }
  4. public void doAfterReturning() {
  5. System.out.println("-------2.执行无异常后通知--------");
  6. }
  7. public Object Around(ProceedingJoinPoint p) throws Throwable {
  8. System.out.println("----------3.环绕通知前-------");
  9. Object proceed = p.proceed();
  10. System.out.println("----------3.环绕通知后--");
  11. return p;
  12. }
  13. public void AfterThrowing() {
  14. System.out.println("--------4.执行后出现异常通知+-----");
  15. }
  16. public void After() {
  17. System.out.println("-------5.执行方法后无论是否出现异常均执行----finally");
  18. }

注意执行环绕通知时 使用 ProceedingJoinPoint 获取执行的方法信息

配置文件

  1. <!-- 声明一个业务类既代理的对象 -->
  2. <bean id="IUser" class="AOP2.IUser"> </bean>
  3. <!-- 声明一个通知类既切面 -->
  4. <bean id="MyProxy" class="AOP2.MyProxy"></bean>
  5. <aop:config>
  6. <!--声明具体通知类的配置 -->
  7. <aop:aspect ref="MyProxy">
  8. <aop:pointcut expression="execution(* AOP2.IUser.*(..))" id="pointcut"/>
  9. <aop:before method="doBefore" pointcut-ref="pointcut"/>
  10. <aop:after method="After" pointcut-ref="pointcut"/>
  11. <aop:after-returning method="doAfterReturning" pointcut-ref="pointcut" returning="result"/>
  12. <aop:after-throwing method="AfterThrowing" pointcut-ref="pointcut" throwing="ex"/>
  13. <aop:around method="Around" pointcut-ref="pointcut"/>
  14. </aop:aspect>
  15. </aop:config>

测试类

  1. ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
  2. User user = (User) context.getBean("IUser"); //注意声明的类为接口
  3. user.work();//以JDK代理实现AOP功能

方法二:注解实现

切面类

  1. @Pointcut("execution(* AOP.IUser.*(..))")
  2. public void pointCut() {
  3. }
  4. @Before("pointCut()")
  5. public void doBefore() {
  6. System.out.println("-------1执行前通知--------");
  7. }
  8. @AfterReturning("pointCut()")
  9. public void doAfter() {
  10. System.out.println("-------2执行无异常后通知--------");
  11. }
  12. @After("pointCut()")
  13. public void doEnd() {
  14. System.out.println("---------3执行后最终通知--不管是否发生异常都执行-----");
  15. }
  16. @Around("pointCut()")
  17. public Object doAround(ProceedingJoinPoint p) throws Throwable {
  18. System.out.println("----------5.环绕通知开始---------");
  19. Object proceed = p.proceed();
  20. System.out.println("----------5.环绕通知结束----------");
  21. return p;
  22. }
  23. @AfterThrowing("pointCut()")
  24. public void doError() {
  25. System.out.println("------------4执行异常通知----------");
  26. }

注意使用@PointCut声明切点

测试类

  1. ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
  2. IUser user = (IUser) context.getBean("IUser");
  3. user.work();

注意:

  1. Target 目标对象既具体的业务类
  2. proxy 代理对象既 通知类或切面类
  3. pointcut 切点 业务类中某个方法进行拦截的方法
  4. jionpoint 连接点 业务类中所有方法
  5. 如果目标对象没有实现接口则使用CGLIB代理,有关设置为<aop:aspectj-autoproxy proxy-target-class="true">,实现接口则使用JDK代理,默认为JDK代理.
  6. 声明切点的方法可以为 execution(* AOP.IUser.*(..))      
  7.  execution()表明主题类  
  8. 第一个* 表示返回类型任意
  9. 包名
  10. 第一个. 代表此包 第二个.为此包下的所有子包 (这里没有写第二个.)
  11. *(..)代表所有类中所有方法
  12. (..)类中所有方法 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值