spring aop 切面,aop切面编程三种实现方式,Spring AOP面向切面编程实现原理方法详解

spring aop 切面,aop切面编程三种实现方式,Spring AOP面向切面编程实现原理方法详解

本文主要介绍Spring AOP的面向方面编程原理和方法的详细讲解,通过实例代码详细介绍,对大家的学习或工作有一定的参考价值,有需要的朋友可以参考一下。

1. 什么是AOP

AOP (Aspect Oriented Programming)的意思是:面向方面编程(Aspect-oriented programming ),是一种通过预编译和运行时动态代理,在不修改源代码的情况下,动态统一地向程序添加功能的技术。可以理解为动态代理。它是Spring框架中的一个重要内容。AOP可以用来隔离业务逻辑的各个部分,降低业务逻辑各个部分之间的耦合度,提高程序的复用性,提高开发效率。

2.春季AOP

春季AOP的作用

提供声明性事务;允许用户自定义切面。

.AOP的基本概念

横切关注点:跨越应用程序多个模块的方法或功能。也就是说,它与我们的业务逻辑无关,但需要我们注意的部分是横切关注点。例如日志、安全性、缓存、事务等。

方面:横切关注点被模块化的特殊对象。它通常是一个可以定义切入点和通知的类。

编织:将方面连接到其他应用程序类型或对象,并创建一个通知对象。这些可以在编译时、类加载时和运行时完成。Spring和其他纯Java AOP框架一样,在运行时完成编织。

建议:AOP对特定切入点进行的增强处理是切入点必须完成的工作,也是类中的一个方法。

目标:被通知的对象。

AOP(Agent):AOP框架创建的对象,Agent是目标对象的增强。Spring中的AOP agent可以是JDK动态agent,也可以是CGLIB agent,前者基于接口,后者基于子类。

连接点:程序执行过程中的一个显式点,通常是方法的调用。

切入点:带有通知的连接点,以及匹配切入点的执行点。

使用Spring实现Aop

先决条件

使用AOP编织,您需要导入一个依赖包。

属国

groupIdorg.aspectj/groupId

artifactIdaspectjweaver/artifactId

版本1 . 9 . 5/版本

/依赖关系

实现Aop的三种方式

方式一:通过 Spring API 实现【主要是springAPI接口实现】

首先,编写业务接口和实现类。

公共接口用户服务{

public void add();

public void delete();

公共void update();

public void搜索();

}

公共类UserServiceImpl实现UserService{

公共void add() {

System.out.println('添加了用户');

}

公共void delete() {

System.out.println('删除了一个用户');

}

公共void更新(){

System.out.println(“更新了一个用户”);

}

公共void select() {

System.out.println('查询了用户');

}

}

然后写增强类,这里有两个:增强前的Log和增强后的AfterLog。

导入org . spring framework . AOP . method before advice;

导入Java . lang . reflect . method;

公共类日志实现MethodBeforeAdvice {

//方法:要执行的目标对象的方法。

//args: parameter

//target:目标对象

public void before(Method method,Object[] args,Object target)抛出Throwable {

system . out . println(' method . getname()' of target . getclass())。已执行“getname()”);

}

}

导入org . spring framework . AOP . afterreturningadvice;

导入Java . lang . reflect . method;

公共类AfterLog实现AfterReturningAdvice {

//returnValue;返回值

public void after returning(Object return value,Method method,Object[] args,Object target)抛出Throwable {

执行了system . out . println(' method . getname()'方法,返回结果为:' return value ');

}

}

最后在Spring的文件中注册(applicationContext.xml),并实现AOP切入,注意导入约束。

?xml版本='1.0 '编码='UTF-8 '?

beans xmlns=' http://www . spring framework . org/schema/beans '

xmlns:xsi=' http://www . w3 . org/2001/XML schema-instance '

xmlns:AOP=' http://www . spring framework . org/schema/AOP '

xsi:架构位置=' http://www。spring框架。组织/模式/bean

https://www.springframework.org/schema/beans/spring-beans.xsd

http://www.springframework.org/schema/aop

https://www.springframework.org/schema/aop/spring-aop.xsd'

!-注册豆子-

bean id=' userService ' class=' com。如果。服务。userserviceimpl '/

bean id=' log ' class=' com。如果。日志。日志'/

bean id=' after log ' class=' com。如果。日志。日志后'/

!-方式一:使用原生Spring API接口-

!-配置aop:需要导入面向切面编程(面向方面的编程的缩写)的约束-

aop:配置

!-切入点:表达式:表达式,执行(要执行的位置!* * * * *) -

AOP:pointcut id=' pointcut ' expression=' execution(* com。如果。服务。userserviceimpl。*(.))'/

!-执行环绕;建议-参考执行方法。切入点引用切入点-

aop:顾问建议-ref=' log '切入点-ref=' pointcut '/

aop:顾问建议-ref=' after log '切入点-ref='切入点'/

/aop:config

/豆子

进行测试:

导入com。如果。服务。用户服务;

导入org。朱尼特。测试;

导入org。spring框架。语境。应用程序上下文;

导入组织。spring框架。语境。支持。classpathmlaplicationcontext

公共类我的测试{

@测试

公共无效测试(){

application context context=new ClassPathXmlApplicationContext(' application context。XML’);

用户服务用户服务1=(用户服务)上下文。获取bean(“用户服务”);

用户服务UserService=(UserService)上下文。获取bean(' user service ');

用户服务。add();

}

}

运行结果:

com.lf.service.UserServiceImpl的增加被执行了

增加了一个用户

执行了增加方法,返回结果为:空

方式二:自定义类实现AOP【主要是切面定义】

目标业务类不变,还是方式一中的用户服务冲动

写入一个切入类

公共类DIY切入点{

之前的公共空的

System.out.println('========方法执行前=========');

}

(){

System.out.println('========方法执行后=========');

}

}

在春天中配置(应用程序上下文。xml)

?可扩展标记语言版本='1.0 '编码='UTF八号'?

豆子xmlns=' http://www。spring框架。'组织/架构/bean '

xmlns:xsi=' http://。w3。' org/2001/XML架构-实例'

xmlns:AOP=' http://。spring框架。'组织/架构/AOP '

xsi:架构位置=' http://www。spring框架。组织/模式/bean

https://www.springframework.org/schema/beans/spring-beans.xsd

http://www.springframework.org/schema/aop

https://www.springframework.org/schema/aop/spring-aop.xsd'

!-注册豆子-

bean id=' userService ' class=' com。如果。服务。userserviceimpl '/

bean id=' log ' class=' com。如果。日志。日志'/

bean id=' after log ' class=' com。如果。日志。日志后'/

!-方式二:自定义类-

bean id=' DIY ' class=' com。如果。DIY。DIY切入点'/

aop:配置

!-自定义切面,参考要引用的类-

aop:aspect ref='diy '

!-切入点-

AOP:切入点id=' point '表达式=' execution(* com。如果。服务。userserviceimpl。*(.))'/

!-通知-

AOP:before method=' before ' pointcut-ref=' point '/

AOP:after method=' after ' pointcut-ref=' point '/

/aop:方面

/aop:config

/豆子

在上面的MyTest.java中测试,得到结果:

========方法执行前=========

增加了一个用户

========方法执行后=========

方式三:使用注解实现【多用】

编写一个注解实现的增强类

包com。如果。DIY

导入org。AspectJ。郎。proceedingjoinpoint

导入org。AspectJ。郎。签名;

导入org。AspectJ。郎。注释。之后;

导入org。AspectJ。郎。注释。周围;

导入org。AspectJ。郎。注释。方面;

导入org。AspectJ。郎。注释。之前;

@Aspect //标注这个类是一个切面

公共类注释切入点{

@ Before('执行(* com。如果。服务。userserviceimpl。*(.))')

之前的公共空的

System.out.println('=====方法执行前======');

}

@ After('执行(* com。如果。服务。userserviceimpl。*(.))')

(){

System.out.println('=====方法执行后======');

}

//在环绕增强中,我们可以给定一个参数,代表我们要获取处理切入的点;

@ Around('执行(* com。如果。服务。userserviceimpl。*(.))')

公共void around(proceeding join point jp)Throwable {

System.out.println('环绕前');

签名签名=jp。获取签名();//获得签名

System.out.println('签名:'签名');

对象进行=jp。proceed();//执行方法

System.out.println('环绕后');

System.out.println(继续);

}

}

在春天配置文件中,注册豆子,并增加支持注解的配置

?可扩展标记语言版本='1.0 '编码='UTF八号'?

豆子xmlns=' http://www。spring框架。'组织/架构/bean '

xmlns:xsi=' http://。w3。' org/2001/XML架构-实例'

xmlns:AOP=' http://。spring框架。'组织/架构/AOP '

xsi:架构位置=' http://www。spring框架。组织/模式/bean

https://www.springframework.org/schema/beans/spring-beans.xsd

http://www.springframework.org/schema/aop

https://www.springframework.org/schema/aop/spring-aop.xsd'

!-注册豆子-

bean id=' userService ' class=' com。如果。服务。userserviceimpl '/

bean id=' log ' class=' com。如果。日志。日志'/

bean id=' after log ' class=' com。如果。日志。日志后'/

!-方式三-

bean id=' annotationPointCut ' class=' com。如果。DIY。annotationPointCut '/

!-开启注解支持!JDK(默认proxy-target-class=' false ')cglib(proxy-target-class=' true ')-

aop:aspectj-autoproxy/

/豆子

在MyTest.java中测试

导入com。如果。服务。用户服务;

导入org。朱尼特。测试;

导入org。spring框架。语境。应用程序上下文;

导入组织。spring框架。语境。支持。classpathmlaplicationcontext

公共类我的测试{

@测试

公共无效测试(){

application context context=new ClassPathXmlApplicationContext(' application context。XML’);

用户服务UserService=(UserService)上下文。获取bean(' user service ');

用户服务。add();

}

}

得到结果:

环绕前

签名:void com。如果。服务。用户服务。添加()

=====方法执行前======

增加了一个用户

=====方法执行后======

环绕后

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: