Spring AOP 5种通知与java动态代理

接口,要求为每个方法前后添加日志 
 1 @Component("arithmeticCalculator")
 2 public class ArithmeticCalculatorImpl implements ArithmeticCalculator {
 3 
 4     @Override
 5     public int add(int i, int j) {
 6         int result = i + j;
 7         return result;
 8     }
 9 
10     @Override
11     public int sub(int i, int j) {
12         int result = i - j;
13         return result;
14     }
15 
16     @Override
17     public int mul(int i, int j) {
18         int result = i * j;
19         return result;
20     }
21 
22     @Override
23     public int div(int i, int j) {
24         int result = i / j;
25         return result;
26     }
27 
28 }
接口的实现类
 1 public class ArithmeticCalculatorLoggingImpl implements ArithmeticCalculator {
 2 
 3     
 4     @Override
 5     public int add(int i, int j) {
 6         System.out.println("The method add begins with [" + i + "," + j + "]");
 7         int result = i + j;
 8         System.out.println("The method add ends with " + result);
 9         return result;
10     }
11 
12     @Override
13     public int sub(int i, int j) {
14         System.out.println("The method sub begins with [" + i + "," + j + "]");
15         int result = i - j;
16         System.out.println("The method sub ends with " + result);
17         return result;
18     }
19 
20     @Override
21     public int mul(int i, int j) {
22         System.out.println("The method mul begins with [" + i + "," + j + "]");
23         int result = i * j;
24         System.out.println("The method mul ends with " + result);
25         return result;
26     }
27 
28     @Override
29     public int div(int i, int j) {
30         System.out.println("The method div begins with [" + i + "," + j + "]");
31         int result = i / j;
32         System.out.println("The method div ends with " + result);
33         return result;
34     }
35 
36 }
方法一:手动实现为方法添加日志
 1 public class ArithmeticCalculatorLoggingProxy {
 2     
 3     
 4     private ArithmeticCalculator target;
 5     
 6     public ArithmeticCalculatorLoggingProxy(ArithmeticCalculator target) {
 7         super();
 8         this.target = target;
 9     }
10 
11 
12     public ArithmeticCalculator getLoggingProxy(){
13         ArithmeticCalculator proxy = null;
14         
15         ClassLoader loader = target.getClass().getClassLoader();
16         Class [] interfaces = new Class[]{ArithmeticCalculator.class};
17         InvocationHandler h = new InvocationHandler() {
18             /*method 方法
19              *args 参数 
20              * */
21             @Override
22             public Object invoke(Object proxy, Method method, Object[] args)
23                     throws Throwable {
24                 String methodName = method.getName();
25                 
26                 //前置通知
27                 System.out.println("[before] The method " + methodName + " begins with " + Arrays.asList(args));
28                 
29                 Object result = null;
30                 try {
31                     
32                     result = method.invoke(target, args);//返回通知
33                     
34                 } catch (NullPointerException e) {
35                     e.printStackTrace();
36                     //异常通知
37                 }
38                 //后置通知
39                 System.out.println("[after] The method ends with " + result);
40                 
41                 return result;
42             }
43         };
44         
45         proxy = (ArithmeticCalculator) Proxy.newProxyInstance(loader, interfaces, h);
46         
47         return proxy;
48     }
49 }
方法二:利用动态代理模式实现为方法添加日志
 1 /**
 2  * AOP 
 3  * 1. 导入jar包
 4  * com.springsource.net.sf.cglib-2.2.0.jar
 5  * com.springsource.org.aopalliance-1.0.0.jar
 6  * com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar
 7  * spring-aspects-4.0.0.RELEASE.jar
 8  * 
 9  * 2. 在配置文件中加入AOP的命名空间
10  * xmlns:aop="http://www.springframework.org/schema/aop"
11  * 
12  * 3. 基于注解的方式
13  * <context:component-scan base-package="com.atguigu.spring.aop"></context:component-scan>
14  * <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
15  *  
16  * 4.把横切关注点的代码抽象到切面的类中
17  *   @Aspect
18  *     @Component
19  *     public class LoggingAspect {}
20  *
21  * 5.AspectJ支持5种类型的通知注解
22  *   @Before()前置通知,在方法开始前执行
23  *   @After()后置通知,在方法执行后执行,无论抛异常都会执行;不能访问方法执行的结果
24  *   @AfterRunning()返回通知,在方法返回结果后执行(即方法正常结束后才执行);可以得到方法执行的结果
25  *   @AfterThrowing()异常通知,在方法抛出异常时执行
26  *   @Around()环绕通知,围绕着方法执行
27  * 6.AspectJ表达式
28  *  execution(public int com.aop.beans.ArithmeticCalculator.*(int, int)) 
29  *  execution(* com.aop.beans.*.*(int, int))
30  *  
31  * 7.JoinPoint
32  * 通过他可以得到方法的信息
33  */
34 
35 //把这个类放入到IOC容器中@Component;再声明为一个切面@Aspect
36 @Aspect
37 @Component
38 public class LoggingAspect {
39     //该方法是一个前置通知,即在目标方法开始前执行@Before()
40     @Before("execution(public int com.aop.beans.ArithmeticCalculator.*(int, int))")
41     public void beforeMethod(JoinPoint joinPoint){
42         String methodName = joinPoint.getSignature().getName();//得到方法名
43         Object [] args = joinPoint.getArgs();//得到参数
44         
45         System.out.println("前置通知:The method " + methodName + " begins with " + Arrays.asList(args));
46     }
47     
48     @After("execution(* com.aop.beans.*.*(..))")//位置为这个包下的所有类、所有方法、不论参数是什么类型
49     public void afterMethod(JoinPoint joinPoint){
50         String methodName = joinPoint.getSignature().getName();
51         System.out.println("后置通知:The method " + methodName + " ends");
52     }
53     
54     
55     @AfterReturning(value="execution(public int com.aop.beans.ArithmeticCalculator.*(int, int))",
56             returning="result")
57     public void afterReturning(JoinPoint joinPoint, Object result){
58         String methodName = joinPoint.getSignature().getName();
59         System.out.println("返回通知:The method " + methodName + " ends with " + result);
60     }
61     
62 
63     @AfterThrowing(value="execution(public int com.aop.beans.ArithmeticCalculator.*(int, int))",
64             throwing="e")
65     public void afterThrowing(JoinPoint joinPoint, Exception e){
66         String methodName = joinPoint.getSignature().getName();
67         System.out.println("异常通知:The method " + methodName + " occurs excetion:" + e);
68     }
69     
70     /*
71      * 环绕通知功能相当于动态代理的全过程,需要有ProceedingJoinPoint 类型的参数;
72      * pjd 参数可以决定是否执行目标方法
73      * 环绕通知必须有返回值,返回值即为目标方法的返回值
74      * 
75      * 
76     @Around("execution(public int com.aop.beans.ArithmeticCalculator.*(int, int))")
77     public Object aroundMethod(ProceedingJoinPoint pjd){
78         
79         Object result = null;//返回值
80         String methodName = pjd.getSignature().getName();//得到方法名
81         
82         try {
83             //前置通知
84             System.out.println("The method " + methodName + " begins with " + Arrays.asList(pjd.getArgs()));
85             result = pjd.proceed();//执行方法 //返回通知
86             System.out.println("The method " + methodName + " ends with " + result);
87         } catch (Throwable e) {
88             //异常通知
89             System.out.println("The method " + methodName + " occurs exception:" + e);
90             throw new RuntimeException(e);
91         }
92         //后置通知
93         System.out.println("The method " + methodName + " ends");
94         
95         return result;
96     }
97     */
98     
99 }
方法三:利用Spring AOP AspectJ实现为方法添加日志
 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <beans xmlns="http://www.springframework.org/schema/beans"
 3     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
 4     xmlns:aop="http://www.springframework.org/schema/aop"
 5     xmlns:context="http://www.springframework.org/schema/context"
 6     xsi:schemaLocation="http://www.springframework.org/schema/beans 
 7         http://www.springframework.org/schema/beans/spring-beans.xsd
 8         http://www.springframework.org/schema/aop 
 9         http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
10         http://www.springframework.org/schema/context 
11         http://www.springframework.org/schema/context/spring-context-4.0.xsd">
12 
13     <!-- 自动扫描的包;  扫描@注解,添加到IOC容器中,让Spring管理-->
14     <context:component-scan base-package="com.aop.beans"></context:component-scan>
15 
16     <!-- 使 AspectJ 的注解起作用 ; autoproxy自动代理-->
17     <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
18 
19 </beans>
beans-aop.xml
 1 public class Main {
 2     
 3     public static void main(String[] args) {
 4         /*代理模式实现添加日志功能
 5         ArithmeticCalculator arithmeticCalculator = new ArithmeticCalculatorImpl();        
 6         arithmeticCalculator = new ArithmeticCalculatorLoggingProxy(arithmeticCalculator).getLoggingProxy();        
 7         int result = arithmeticCalculator.add(11, 12);
 8         System.out.println("result:" + result);
 9         result = arithmeticCalculator.div(21, 3);
10         System.out.println("result:" + result);
11         */
12 
13         //AOP实现添加日志功能
14         ApplicationContext ctx = new ClassPathXmlApplicationContext("com/aop/beans/beans-aop.xml");
15         ArithmeticCalculator arithmeticCalculator = (ArithmeticCalculator) ctx.getBean("arithmeticCalculator");
16         
17         System.out.println(arithmeticCalculator.getClass().getName());
18         
19         int result = arithmeticCalculator.add(11, 12);
20         System.out.println("result:" + result);
21         result = arithmeticCalculator.div(21, 2);
22         System.out.println("result:" + result);
23         
24     }
25     
26 }
测试类

 

转载于:https://www.cnblogs.com/wwzyy/p/5151471.html

保姆级避坑指南:在Ubuntu 18.04上搞定速腾Helios雷达驱动fast-LIO2的完整配置流程 本文提供了一份详细的速腾Helios雷达fast-LIO2在Ubuntu 18.04上的配置避坑指南,涵盖驱动安装、数据格式转换到建图全流程。特别针对常见编译错误和数据转换问题提供了解决方案,帮助开发者高效完成环境搭建建图任务。 阅读详情

相关推荐

详细解读经典跨模态对齐技术Q-Former代码

介绍BLIP2的博客层出不穷,介绍Q-Former的博客也不少,但是详细解读Q-Former代码的博客很少。这篇博客希望以代码为基础,讲明白Q-Former的原理和核心思想,并详细解读一些值得注意的细节。希望读者们能从这一经典技术中朝花夕拾,得到启发。

沉迷单车的追风少年 2411

JAVA动态代理Spring AOP 4种通知的简单实现

转自 https://my.oschina.net/u/1444899/blog/217739 摘要: JAVA动态代理Spring AOP 4种通知的简单实现 学习Spring AOP 之前,先要了解下JAVA动态代理。如果不清楚动态代理的概念就百度一下吧。废话不多说,直接上代码。 我们模拟一个简单的登录 首先我们创建一个用户登录的接口 package com.proxy

u012799221的博客 2015

模型实战(32)之 yolo26 实现对全身关键点数据集 的训练关键点检测

模型实战(32)之 yolo26 实现对全身关键点数据集 的训练关键点检测

yohnyang的博客 74

MySQL I/O性能优化实战:从故障排查到系统调优

数据库I/O性能是影响系统稳定性的关键因素,特别是在高并发场景下。MySQL作为最流行的关系型数据库,其I/O机制通过缓冲池、日志系统和存储引擎协同工作。当出现I/O瓶颈时,通常表现为高等待时间、系统负载激增和查询性能下降。通过合理配置innodb_io_capacity等参数、优化查询语句和索引设计,可以显著提升吞吐量。在电商、金融等对数据一致性要求高的场景中,还需要结合监控工具进行全链路分析。本文通过一个真实案例,展示了如何从临时表优化、参数调整到架构改进的多维度解决方案,最终使I/O等待从98%降至1

weixin_34391445的博客 484

spring中的动态代理aop的自定义通知

目录 1.spring中的动态代理 2.aop的自定义通知和配置(before,after,afterReturning,afterThrowing,around) 1.spring中的动态代理 UserService.java: package com.sikiedu.service; public interface UserService { void sa...

747

spring aop代理通知java动态代理

1java动态代理 1.1建立一个接口 public interface IPreson { //吃 public void eat(); } 1.2创建一个实现类 public class XiaoMing implements IPreson { @Override public void eat() { System.out.println("hahah"); } } 1.3创建代理实现接口(InvocationHandler...

qq_41740369的博客 242

Spring AOP

原文文章地址:http://www.189works.com/article-48505-1.html Spring默认使用J2SE动态代理来作为AOP代理。这样只有实现接口的类才能使用AOP。   Spring也支持CGLIB代理,对于需要代理类而不是代理接口的时候,就会使用CGLIB代理。   如果一个类实现了某个接口,并且它有额外的其他方法,那么这些接口中没有

xing_sky的专栏 674

AOP(Aspect Oriented Programming)

文章目录1.动态代理1. 实现方式:2. 动态代理的作用:2.AOP1. what‘s AOP?2. AOP相关的术语3.AOP的实现4.AspectJ的介绍(1) 5通知注解:(2) 切入点表达式5.AspectJ的使用(以@Before为例)1.新建maven项目2.加入相关依赖3.创建目标类4.创建切面类5.创建spring的配置文件6.创建测试类6.AspectJ的其他通知后置通知@AfterReturning环绕通知@Around@AfterThrowing 异常通知最终通知@After@Poi

爱吃小香葱的博客 234

很难出错的spring5(七)—— spring实现面向切面编程AOP

业务逻辑写好不能动了,但是可以从切入点切进去,大概就这么个意思。在上面那个例子中,一旦我们切入log操作,那么所有的方法(增、删、改、查)都要切入log操作。但是用spring实现,可以用expression表达式指定只切入修改方法。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的。

qq_44886213的博客 267

手工实现AOP核心源码之aop1.0版

目录 环境准备 核心代码实现 测试 总结 环境准备 spring源码版本5.0.2 jdk1.8 ide idea 在源码中创建子模块 友情提示: 我们1.0版本只需要实现前置,后置通知即可。由于ioc源码需要依赖spring 本身的,所以spring ioc源码有些地方需要改造...

lvjingang的博客 458

Spring5系列学习文章分享---第三篇(AOP概念+原理+动态代理+术语+Aspect+操作案例(注解配置方式))

在这个博客中,我们将深入研究 Spring 框架的AOP概念+原理+动态代理+术语+Aspect+操作案例(注解配置方式)。在这篇文章中,我们探索了Spring5的((AOP概念+原理+动态代理+术语+Aspect+操作案例(注解配置方式))在第四篇中,我们将深入研究Spring 5的JdbcTemplate,为您分享我学习的Spring5的收获,请继续关注我的系列。业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。第二参数,增强方法所在的类,这个类实现的接口,支持多个接口。

私聊前往站内信:https://i.csdn.net/#/msg/chat/weixin_44976692 3万+

spring aop源码解析

参考文档 1.https://blog.csdn.net/u012890095/article/details/80229721 2.

厚积薄发的博客 153

5.Spring AOP动态代理

1. Spring AOP简介 1.1 什么是AOP AOP的全称是Aspect-Oriented Programming,即面向切面编程(也称面向方面编程)。它是面向对象编程(OOP)的一种补充,目前已成为一种比较成熟的编程方式。 在传统的业务处理代码中,通常都会进行事务处理、日志记录等操作。虽然使用OOP可以通过组合或者继承的方式来达到代码的重用,但如果要实现某个功能(如日志记录),同样的代码...

一介书生 9278

Java外功精要(5)——Spring AOP

是一种编程范式,旨在将从业务逻辑中分离出来,通过模块化的方式增强代码的可维护性和复用性。核心思想是通过“切面”定义通用功能,并在运行时动态织入到目标代码中指的是在系统中"横向"跨越多个模块、多个层次的功能需求,它们无法很好地被封装在单个类或模块中。

2401_89167985的博客 9488

Spring高手之路19——Spring AOP注解指南

在本文中,我们将深入探索Spring AOP(面向切面编程)的核心概念及其在现代Spring应用中的实际应用。从基本的注解使用到复杂的切面配置,本文将一步步指导你如何利用Spring AOP提升代码的模块化,帮助你在Spring开发路上更进一步。

卓越无关环境,保持空杯心态——靡不有初,鲜克有终 1万+

JAVA 进阶】Spring AOP核心原理:JDKCGLib动态代理实战解析

本文深入解析Spring AOP的核心实现技术——JDK动态代理CGLib动态代理。首先从AOP的概念入手,阐述其解决代码复用痛点的原理,并详细介绍了切面、通知、切入点等核心概念。然后重点剖析JDK动态代理的实现机制,包括InvocationHandler接口和Proxy类的关键作用,通过日志代理的实战案例演示了代理对象的创建过程。文章还对比了两种代理方式的适用场景,帮助开发者理解Spring AOP的整体执行流程和技术选型依据。全文兼顾理论实战,为掌握Spring AOP提供了全面的技术指南。

CodeSuc 的技术博客 2746

Spring AOP原理详解:动态代理实际应用

Spring AOP中,可以使用注解或XML配置来定义切面和通知

逆流的小鱼 3951

JAVA 进阶】深入探索Spring AOP:从原理到实战

本文深入解析了Spring AOP的核心概念实现原理。AOP(面向切面编程)通过将横切关注点(如日志、事务等)从核心业务逻辑中分离,实现代码解耦。Spring AOP基于动态代理机制,主要包含切面(Aspect)、切点(Pointcut)、通知(Advice)等核心组件。文章详细介绍了JDK动态代理的实现方式,通过Proxy和InvocationHandler在运行时为目标对象创建代理,实现方法增强。Spring AOP作为OOP的补充,能有效提升代码的可维护性和扩展性。

CodeSuc 的技术博客 2775

Spring AOP的—绍和5通知类型的使用(详解)

java Spring AOP介绍使用 1、Aop的概念 AOP的核心概念及术语 切面(Aspect): 指关注点模块化,这个关注点可能会横切多个对象。事务管理是企业级Java应用中有关横切关注点的例子。 在Spring AOP中,切面可以使用通用类基于模式的方式(schema-based approach)或者在普通类中以@Aspect注解(@AspectJ 注解方式)来实现。 连接点(Join point): 在程序执行过程中某个特定的点,例如某个方法调用的时间点或者处理异常的时间点。在Spring

江哈哈的博客 6419

SpringAOP底层原理(动态代理)-》 AOP概念及术语 -》 AOP实现

AOP —— 面向切面编程,通过预编译方式和运行期间动态代理实现程序功能的统一维护的一种技术。 是Spring框架中的一个重要内容。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。

ebb29bbe的博客 1951

SpringBoot核心特性—AOP(详解AOP通知类型:环绕通知、前置通知等,以及AOP的连接点、通知、切入点、切面、目标对象以及通知顺序)

SpringBoot核心特性—AOP(详解AOP通知类型:环绕通知、前置通知等,以及AOP的连接点AOP英文全称:Aspect Oriented Programming(面向切面编程、面向方面编程),面向切面编程就是面向特定方法编程。减少重复代码提高开发效率维护方便面向这样的指定的一个或多个方法进行编程,我们就称之为 面向切面编程。AOP面向方法编程,就可以做到在不改动这些原始方法的基础上,针对特定的方法进行功能的增强。AOP的作用:在程序运行期间在不修改源代码的基础上对已有方法进行增强(无侵入性: 解耦)

Java技术加油站的博客 1729
上一篇: java操作数据库增删改查的小工具1--TxQueryRunner
下一篇: android细节之禁用activity的系统的默认切换效果
weixin_30652879
博客等级 码龄11年 87粉丝 0原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值