Spring AOP学习笔记

保姆级教程:用Dify+DeepSeek API打造你的私人股票分析助手(附完整配置流程) 本文提供了一份详细的教程,指导用户如何利用Dify低代码平台和DeepSeek API构建一个私人股票分析助手。内容涵盖从环境准备、Dify部署、DeepSeek模型配置,到设计智能体工作流和编写高效提示词的完整流程,旨在帮助投资者和开发者快速打造专属的AI投资分析工具。 阅读详情

一、通过一个最基础的例子记录基于Schema方式的spring AOP实现。

    以下模拟一个业务处理类:

public class HelloWorldServiceImpl implements HelloWorldService {
	@Override
	public String sayHello(String param,People people) {
		System.out.println("People's name is " + people.getName());
		return "success";
	}
}


    以下模拟切面通知实现类,其他诸如环绕通知、后置异常通知就不一一列出了:

public class HelloWorldAspect {
	public void beforeAdvice(String pa,People arg) {
		System.out.println("=================前置通知!" + pa);
	}
	
	public void afterFinallyAdvice(String pa, People arg) {
		System.out.println("=================后置最终通知!" + arg.getName());
	}
	
	public void afterReturn(String pa,People arg,String value) {
		System.out.println("=================value = " + value);
	}
}


    以下是applicationContext.xml文件配置:

<bean id="helloWorldService" class="cn.com.enorth.service.impl.HelloWorldServiceImpl"/>
<bean id="aspect" class="cn.com.enorth.aop.HelloWorldAspect"/>

<aop:config>
	<aop:pointcut expression="execution(* cn.com.enorth..*.*(..)) and args(pa,arg)" id="pointcut"/>
	<aop:aspect ref="aspect">
		<aop:before pointcut-ref="pointcut" method="beforeAdvice"/>
		<aop:after pointcut-ref="pointcut" method="afterFinallyAdvice"/>
		<aop:after-returning pointcut-ref="pointcut" method="afterReturn" returning="value"/>
	</aop:aspect>
</aop:config>

    后置返回通知after-returning只有在目标方法成功执行后才会生效,而后置最终通知after无论目标方法成功执行还是抛出异常都会生效。


    以下是测试方法:

public class Test {
	public static void main(String[] args) {
		ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
		HelloWorldService service = ctx.getBean("helloWorldService",HelloWorldService.class);
		People people = new People();
		people.setName("Super Man");
		service.sayHello("Hello", people);
	}
}

    按照Spring的正常调用方式调用业务类的相应方法,如果该方法匹配AOP的切入点模式,就会自动调用切面实现类中的相应方法。

    如果通知方法中需要使用被匹配方法的参数,则要在匹配模式中加入"and args(参数列表)",参数名要与通知方法中的参数名一一对应。如果需要使用被匹配方法的返回值,则要在后置返回通知中定义return属性,其值与通知方法中的参数名一致。如上述配置中return=”value“与HelloWorldAspect类中afterReturn方法的第三个参数名”value“相一致。


    关于环绕通知:

    环绕通知十分强大,可以决定目标方法(被匹配到的方法)是否执行,什么时候执行,执行的时候是否替换参数,执行完毕是否替换返回值。环绕通知通过<aop:around>标签及其属性进行配置。

    环绕通知的第一个参数必须是org.aspectj.lang.ProceedingJoinPoint类型,在通知方法内部使用PorceedingJoinPoint的proceed()方法是目标方法执行。proceed()方法可选择是否传入Object[]数组替换目标方法执行时的参数。目标方法的返回值,将由通知方法的返回值取代。如果目标方法返回值类型为void,则在通知方法内执行proceed()方法返回null。而如果目标方法有返回值,通知方法为void类型,调用目标方法的程序也将获得null。


二、基于@AspectJ的AOP

1、Spring默认并不支持@AspectJ风格的切面声明,为了启用支持需要做如下配置:

<aop:aspectj-autoproxy />

2、声明切面

    使用@Aspect注解进行声明

@Aspect
public class NewAspect {}

    然后将该切面在配置文件中声明为bean,Spring就能自动识别并进行AOP方面的配置:

<bean id="aspect" class="....NewAspect"/>

    切入点以及各类通知都可以在该类中定义,见下文。

3、一个@AspectJ风格的AOP实现如下:

    以下模拟业务处理类:

public class NewServiceImpl implements NewService {
	@Override
	public void newSay(People people) {
		System.out.println(people.getName());
	}
}

    以下模拟一个切面处理类:

public class NewAspect {
	@Pointcut(value="execution(* cn.com.enorth..*.new*(..)) && args(people)")
	public void pointCut(People people){}
	
	/*
	 * value取值可以是命名切入点“pointCut(people)”
	 * 也可以是新的切入点表达式“execution(* cn.com.enorth..*.*(..)) && args(people)”
	 */
	@Before(value="pointCut(people)")
	public void befort(People people){
		System.out.println("===============" + people.getName());
	}
	
	@AfterReturning(value="pointCut(people)",returning="value")
	public void afertReturning(People people,Object value){
		System.out.println("===============" + value);
	}
}

    以下是applicationContext.xml中需要注册的bean:

<bean id="newService" class="cn.com.enorth.service.impl.NewServiceImpl"/>
<bean id="newAspect" class="cn.com.enorth.aop.NewAspect"/>

    以下是测试代码:

public class Test {
	public static void main(String[] args) {
		ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
		NewService service = ctx.getBean("newService",NewService.class);
		People people = new People();
		people.setName("Super Man");
		service.newSay(people);
	}
}

    对照Schema风格的AOP实现,@AspectJ风格也就很好理解了。差异比较大的一点是,@AspectJ风格中可引用的切入点是通过单独定义的一个方法实现的,在上下文中通过方法名以及参数列表引用,即:

@Pointcut(value="execution(* cn.com.enorth..*.new*(..)) && args(people)")
public void pointCut(People people){}

    而在Schema风格中,这是通过<aop:pointcut>标签实现的,在上下文中通过切入点的id引用,即:

<aop:pointcut expression="execution(* cn.com.enorth..*.*(..)) and args(pa,arg)" id="pointcut"/>

    另外,@AspectJ风格中的&&、||、!在Schema风格中分别用and、or、not表示。


三、参数传递

    上面的介绍中已经通过在定义切入点的时候,使用“args(参数列表)”匹配模式的方式传递被匹配方法的参数到通知方法中。下面介绍在通知方法中使用JoinPoint接口类型获取更多信息。

    任何通知方法的第一个参数都可以是JoinPoint类型,例外的是环绕方法的第一个参数必须是ProceedingJoinPoint,它是JoinPoint的子类。第一个参数也可以是JoinPoint.StaticPart,它只包含连接点的静态信息。

1、JoinPoint接口方法说明

String toString(); //连接点所在位置的相关信息

String toShortString(); //简短相关信息

String toLongString(); //详细相关信息

Object getThis(); //返回AOP代理对象

Object getTarget(); //返回目标对象

Object[] getArgs(); //返回被通知方法的参数列表

Signature getSignature(); //返回当前连接点签名

SourceLocation getSourceLocation(); //返回连接点方法所在类文件中的位置

String getKind(); //返回连接点类型

StaticPart getStaticPart(); //返回连接点静态部分

2、ProceedingJoinPoint接口定义:用于环绕通知,使用proceed方法执行目标方法。

public interface ProceedingJoinPoint extends JoinPoint {
    public Object proceed() throws Throwable;
    public Object proceed(Object[] args) throws Throwable;
}
3、JoinPoint.StaticPart:提供连接点的静态信息部分

public interface StaticPart{
    Signature getSignature(); // 返回当前连接点签名
    String getKind(); //返回连接点类型
    int getId(); //返回连接点的唯一标识
    String toString(); //同上
    String toShortString(); //同上
    String toLongString(); //同上
}

四、通知执行顺序

1、同一个切面中通知的执行顺序

①前置通知 / 环绕通知proceed方法执行之前的部分 //这两者的先后顺序不确定

②被通知方法

③后置通知 / 环绕通知proceed方法执行之后的部分 //这两者的执行顺序不确定

2、不同切面中通知的执行顺序

    当定义在不同切面的同类型的通知(比如都是前置通知),需要在用一个连接点执行时,如果没有指定切面的执行顺序,那么这两个通知的执行顺序是未知的。

    如果有必要确定执行顺序,需要执行切面执行的优先级。可以通过实现org.springframework.core.Ordered接口或者使用注解@Order指定切面优先级。Order.getValue()返回值越小优先级越高。不推荐使用接口方法指定优先级,两种风格下配置优先级的方式如下:

@Aspect
@Order(2)
public class OrderAspect2{}

<aop:aspect ref="..." order="1">...</aop:aspect>

五、切面对象的作用范围

    1. singleton。单例模式,即每个切面只有一个实例,是Spring AOP默认的作用域。

    2. perthis。每个切入点表达式匹配的连接点对应的AOP对象都会创建一个新的切面实例。使用@Aspect(perthis(“切入点表达式”))指定切入点。

    3. pertarget。每个表切入点达式匹配的连接点对应的目标对象都会创建一个新的切面实例。使用@Aspect(pertarget("切入点表达式"))指定切入点。

    注意:Schema风格的配置只支持默认的singleton作用域。在进行切面定义的时候还必须将切面bean的作用域(scope)定义为“prototype",否则将不能为每个匹配连接点表达式的AOP代理对象或目标对象创建一个切面实例。


六、Spring AOP代理机制

    1. JDK动态代理。java.long.reflect.Proxy动态代理实现。即提取目标对象的接口然后对接口创建AOP代理对象。

    2. CGLIB代理。CGLIB不仅能进行接口代理,也能进行类代理。但是CGLIB不能代理final方法,因为CGLIB通过生成子类创建代理,而final方法不能被覆盖。另外CGLIB会调用两次构造器,一次是目标类的构造器,一次是代理累的构造器,如果使用该方式,请确保两次构造器调用不会影响应用功能。

    默认情况下Spring使用JDK动态代理,如果目标对象没有实现任何接口将使用CGLIB代理。如果要强制使用CGLIB代理,可以采用如下方法指定:

    ①schema风格配置

<aop:config proxy-target-class="true">...</aop:config>

    ②@Aspect风格使用如下方式指定采用CGLIB代理方式

<aop:aspectj-autoproxy proxy-target-class="true"/>



macOS安装Cplex+yalmip 阅读详情

相关推荐

沉降预测算法-指数曲线法

沉降预测的指数曲线法原理和代码实现

yh523的博客 986

SpringAOP初识——初学者向

有需要的小伙伴可以自行跳转。下面,我们今天来一起学习下SpringAOP相关的知识点。SpringAOP的英文全称是——(Aspect-Oriented Programming)面向切片编程,切片的理解大家可以想象一下切片面包,一个面包整体就是我们的项目,而把面包从业务的角度切成一片一片的,这些切片就是我们的业务。...

Lee_92的博客 5619

WIN10系统下VS2019编译CloudCompare2.12.4

CloudCompare2.12.4

点云侠的博客 3117

aop切面中 joinPoint.proceed()的一个小认识

自己写项目东西的时候,写过一个aop来做日志,在环绕通知@Around里,他的返回值是Object,当时心里想的是,这个环绕通知也没什么东西需要调用的,就把它改成void了,后面运行代码正常业务拿不到返回值了。还是自己对aop认识不够深入,里面会有一句逻辑,一般是写成。其实这句代码的意思就是正常去执行我们的业务,而我们最后返回的那个返回值就是我们的result,也就是我自己亲自吧返回值写成了void所以正常业务肯定拿不到返回值,确实是自己学艺不精出现的失误发出来与大家共勉。

yyswit的博客 9056

Spring零散知识

对于一些积累的问题总结

weixin_45931856的博客 1493

Spring-AOP

AOP快速上手使用,AOP执行流程,切入点表达式书写说明,五种通知类型使用说明,通知方法获取切入点的签名信息,参数,返回值和异常等信息。

maohe的博客 1144

SpringAOP进阶-JoinPointProceedingJoinPoint详解

Spring AOP中,JoinPointProceedingJoinPoint都是关键的接口,用于在切面中获取方法的相关信息以及控制方法的执行。它们的主要区别在于它们在AOP通知中的使用方式和功能。Joinpoint是面向切面编程(AOP)中的一个重要概念,指的是在应用程序执行过程中可以被拦截的特定点。在AOP中,Joinpoint代表了程序执行的某个具体位置,比如方法的调用、异常的抛出等。AOP框架通过拦截这些Joinpoint来插入额外的逻辑,实现横切关注点的功能。

云泽野の编程日记 1万+

spring aop 学习笔记

spring aop 学习笔记

congine_mcfeng的专栏 131

Spring AOP之AspectJ学习笔记

Spring AOP之AspectJ学习笔记 AspectJ 简介 AspectJ是一个基于Java语言的AOP框架 Spring2.0以后新增了对AspectJ切点表达式支持 @AspectJ是AspectJ1.5新增功能,通过JDK5注解技术,允许直接在Bean类中定义切面 新版本Spring框架,建议使用AspectJ方式开发AOP 使用AspectJ需要导入Spring AOP和Aspe...

weixin_39610830的博客 220

Spring AOP 学习笔记

注:该篇文章会与我的个人博客同步更新。欢迎移步https://cqh-i.github.io/体验更好的阅读效果。 什么是AOP   全称面向切面编程(Aspect Oriented Programming), 通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。

锦瑟年华,逐梦之人 1958

Spring学习笔记——IOC、AOP

Spring概述 作者Rod Johnson,是一款免费开源的框架,方便解耦,简化开发 (高内聚低耦合) 2002年发布的 interface 21 是Spring最早的雏形 2004年Spring框架1.0发布 Spring是一个轻量级的,非入侵式框架 Spring的核心是控制反转(IOC)和面向切面编程(AOP),IOC的一种实现方法是依赖注入(DI) 目的:解决企业应用开发的复杂性 控制反转(IOC) 思想的转变:从程序猿需要向程序中主动new创建对象,到程序被动的接收对象(通过set方法),比

qq_43651045的博客 276

spring 03 aop学习笔记

AOP是一种面向切面编程的编程的范式。与传统面向对象编程不一样,AOP关注的是横跨多个模块的横切逻辑,在事务处理,日志记录,安全控制等操作中被广泛使用。Spring AOPSpring 框架对 AOP 编程范式的具体实现,它基于动态代理机制,允许开发者在不修改原有业务代码的基础上,将横切逻辑织入到目标方法执行的各个阶段,从而实现代码的解耦和复用。

2401_84040384的博客 1699

spring AOP学习笔记

文章目录1,AOP简介1.1 什么是AOP?1.2 AOP作用1.3 AOP核心概念2,AOP入门案例2.1 需求分析2.2 思路分析2.3 环境准备2.4 AOP实现步骤步骤1:添加依赖步骤2:定义接口与实现类步骤3:定义通知类和通知步骤4:定义切入点步骤5:制作切面步骤6:将通知类配给容器并标识其为切面类步骤7:开启注解格式AOP功能步骤8:运行程序知识点1:@EnableAspectJAutoProxy知识点2:@Aspect知识点3:@Pointcut知识点4:@Before3,AOP工作流程3.1

ZgaoYi的博客 593

SpringAOP学习笔记

文章目录1. 什么是Spring框架1.1 什么是IoC:Inverse Of Control 反转的是Bean的创建权1.2 什么是AOP:A 1. 什么是Spring框架 官方:Spring是分层的JavaSE/EE应用的full-stack轻量级开源框架,以IoC和AOP为内核 可见要理解Spring框架,其一是要学会Spring在开发中的使用,其二是要理解IoC和AoP两个概念, 1.1 什么是IoC:Inverse Of Control 反转的是Bean的创建权 参考了这篇大神的文章:https:

自学菜鸡CyanLiuCY的博客 330

【SSM】Spring学习笔记4:SpringAOP编程

定义一个类,类中定义一个方法,该方法的方法体就是额外执行的操作。这个类需要加上@Component注解以配置成一个为Spring管理的bean;加上@Aspect注解将这个类标记为进行AOP操作配置的类。@Component //通知类必须配置成Spring管理的bean@Aspect //设置当前类为切面类类。

2301_76391858的博客 915

Spring AOP 学习笔记之 常用注解

要在springboot中启用AOP,需要引入spring-boot-starter-aop依赖。

freeRoad 1245

spring 学习笔记 使用aspectj开发aop

1.添加类库:aspectjrt.jar和aspectjweaver.jar com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar com.springsource.org.aspectj.tools-1.6.6.RELEASE.jar org.aspectj aspectjweaver 1.7.1 org.aspectj as

Ace_Yu的专栏 1558

JionPoint

JoinPoint JoinPoint对象封装了SpringAop中切面方法的信息,在切面方法中添加JoinPoint参数,就可以获取到封装了该方法信息的JoinPoint对象. 常用API: Object getTarget() :获取连接点所在的目标对象(也就是被代理的对象); 例如:我的项目中需要获得当前用户访问的类: // 2.访问的类 Class clazz = jp.get...

lameraaa的博客 517

spring aop调用joinPoint.proceed方法执行了两次的原因

通过DeBug模式追查问题和问了度娘之后,整理解决方法如下: 1、多余地使用了invoke调用方法 在方法中调用 joinPoint.proceed() 方法时,会执行两次。因为除开你在本方法中执行的一次之外,spring会在方法也会执行一次.所以应该改用@XXXReturning等方法,如@After改成@AfterReturning: @AfterReturning(value = "...

zoujiawei6的博客 3万+

阅读Spring官网总结Aop用法

前置通知 使用切入点表达式 @Before("execution(* com.xyz.myapp.dao.*.*(..))") public void doAccessCheck() { // ... } 返回后通知 @AfterReturning( pointcut="com.xyz.myapp.CommonPointcuts.dataAccessOperation()", returning="retVal.

持续学习,共同进步 984

05|Spring AOP 常见错误(上)

通过 ReflectionFactory.newConstructorForSerialization().newInstance() 实例化类则。

weixin_56666956的博客 1119

Spring 常用注解

Spring 常用注解 组件注解 @Component @Controller @Service @Repository

dfgakldsjkl的博客 710

C#零基础学习笔记和工程.zip

C#零基础学习笔记和工程,适合入门(PS: 内含联系方式,可联系获取--教学视频。)

现代信息光学与MATLAB

本书系统介绍现代信息光学的核心理论与技术,涵盖傅里叶光学、光学图像处理、数字全息及计算机生成全息等内容。突出非相干光学系统与最新数字全息进展,并结合MATLAB实现光学现象的建模与可视化。每章配有习题,适合作为工程与应用物理专业高年级本科生及研究生教材,也适合从事光学信息处理的研究人员参考。中英双语版本合订,便于中外读者学习与技术交流。

上一篇: Spring学习笔记
下一篇: js学习笔记(一)
Augus6
博客等级 码龄14年 4粉丝 25原创
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值