spring aop 切面,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。如果。服务。用户服务。添加()

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

增加了一个用户

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

环绕后

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

spring aop 切面,aop切面编程三种实现方式