spring第三章

时间:2021-07-30
本文章向大家介绍spring第三章 ,主要包括spring第三章 使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

第三章 实现AOP
AOP:面向方面编程,AOP能够使您将所有模块共有的特性与应用程序的主要业务逻辑隔离开

一、AOP介绍
横切关注点:在Web应用程序中,有一些服务(如登录、安全和事务管理)不是应用程序的主要业务逻辑的一部分。但是,这些服务对于Web应用程序是必不可少的,需要在应用程序的每个模块中实现。因此,这些服务被认为是横切关注点,因为它们要横切应用程序的多个模块。
次要问题,因为他们不实现应用程序的核心功能。
1.定义
将代码分解成不同的模块,称为方面,切面支持对关注点进行模块化,比如跨多个类型和对象的事物管理、日志记录和安全性。
AOP的解决方案:不必从方法中调用所有方法,而是在类的方法中定义额外的关注点,比如维护日志等。
2.AOP中的概念与术语
方面:方面是跨多个类的企业应用程序关注点的类。Aspect可以是通过spring XML文件配置的普通类,也可以使用spring AspectJ集成。使用@Aspect将类定义为Aspect
连接点:连接点是应用程序中的一个特定点,比如方法的执行、异常处理等。在spring aop中,连接点总是方法的执行。
通知:通知是针对某个特定的连接点而采取的行动,相当于是在应用程序中到达某个具有匹配切入点的某个连接时候执行的方法。
分类标准:通知的执行方法,spring AOP中有5类通知
前通知:在连接点之前执行的通知,但是不能组织执行流继续到连接点(除非抛出异常)
返回后通知:通知将在连接点正常完成后执行
抛出后通知:如果方法通过抛出异常而退出,则执行通知
后通知:无论连接点以何种方式退出,都要执行通知
围绕通知:围绕连接点的通知,可以在方法调用之前和调用智慧执行自定义行为。它也负责选择是继续到连接点还是通过返回自身的返回值或者抛出一场来简化被建议的方法的执行。
切入点:切入点是与连接点匹配的表达式,以确定是否需要执行通知。(最终应用通知的所选连接点称为切入点)
目标对象Target Object:通知适用的对象。意思是运行时创建一个子类,其中覆盖目标方法,并更具其配置包含通知
AOP代理:Spring AOP实现通过适用JDK动态代理创建带有目标类和通知调用的代理类
织入:它是将方面与其他对象链接以创建已通知代理对象的过程

二、实现AOP
AOP的实现有三个主要的AOP框架提供
spring AOP Aspect J JBoss AOP
三种使用spring AOP的方法
通过使用spring API
使用Aspect J 注释风格
通过spring XML配置样式与spring一起工作
面向方面编程与spring一起工作
spring使用基于代理的机制,它创建了一个代理对象,该代理对象包裹原始对象。并讲接收与方法调用相关的通知。代理对象可以通过代理工厂bean创建,也可以通过XML文件中的自动代理配置创建并在执行完成时销毁。
1.spring Aspect J风格的AOP
通过使用Aspect J 提供的用于切入点解析和匹配的库。AOP运行时候仍然是纯粹的spring AOP,而且不依赖于Aspect J 编译器或者weaver
配置@Aspect J 支持:XML配置或者Java配置
note:两种都要有aspectjweaver.jar库位于应用程序的类路径中。
使用Java类配置启用
添加@EnableAspectJAutoproxy注释
@Configuration
@EnableAspectJAutoProxy
public class AppConfig{

}

spring AspectJ AOP提供了许多注释
@Aspect将类声明为aspect
@Pointcut声明切入点表达式
用于创建通知的注释
@Before 声明前通知 在调用实际方法之前应用它
@After 声明后通知。在调用实际方法之后和返回结果之前应用。
@AfterReturning 声明返回后通知。 在调用实际方法和返回结果之前应用,但是可以在通知中获取结果值。
@Around 声明了围绕通知。 在调用实际方法之前和之后应用
@AfterTrowing 声明了抛出后通知。 如果实际方法抛出应用,则调用该方法。
声明方面
启用@Aspect J 支持后,在应用程序上下文中定义的带有@Aspect J 的方面类的任何bean都会呗spring 自动检测并用于配置Spring AOP。
应用程序上下文中的 一个常规bean定义,指向一个带有@Aspect注释的bean类
声明切入点
spring AOP只执行spring bean的方法执行连接点,将切入点看作匹配spring bean上方法的执行。
切入点声明:签名(由名称和任何参数组成) 切入点表达式(准确确定我们意向的方法执行)
分别由一个常规方法定义提供 和 @Pointcut注释表示
NOTE:作为切入点签名的方法必须有一个void返回类型
Example:
区分切入点签名和切入点表达式
@Pointcut ("excution(*transfer(...))") //the pointcut expression
private void anyOldtransfer(){ } //the pointcut signature

常见切入点的示例
任何公共方法的执行:
excution(public * *(...))
任何以"Xx"开头的方法的执行
excution(* xx*(...))
AccountService接口定义的任何方法的执行
excution(* com.xyz.service.AcountService.*(...))
任何服务包中定义的方法执行
excution(* com.xyz.service.*.*(..))
任何服务包或者子包定义的方法的执行
excution(* com.xyz. service.*. *(..))
服务包中的任何连接点
within(com.xyz.service.*)
声明通知
通知于切入点表达式关联,并在切入点匹配的方法执行之前、之后或者周围运行。切入点表达式可是对命名切入点的简单引用,也可以是在恰当位置声明的切入点表达式
import org.aspectj.lang.annotation.Aspect;

前通知
@Before("com.niit.myapp.SystemArchitecture.dataAccessOperation()")
返回后通知
@AfterReturning("com.xyz.myapp.SystemArchitecture.dataAccessOperation()")
NOTE:返回标记属性中使用的名称必须与通知方法中的参数相对应。return子句害将匹配现状为只匹配哪些返回指定类型值的方法的执行。
抛出后通知
@AfterThrowing("com.niit.myapp.SystemArchitecture.dataAccessOperation()")
使用抛出属性严格匹配,将抛出的异常绑定到一个通知参数
抛出属性中使用的名称必须与通知方法中的参数名称对应。当方法执行抛出异常而退出时,异常将作为相应的参数值传递给通知方法。
后通知
后通知运行时,匹配的方法执行退出。后通知必须住呢比阿红处理正常和异常返回条件,一般用于释放资源。
@After("com.niit.myapp.SystemArchitecture.dataAccessOperation()")

围绕通知
它在方法执行之前和之后执行工作,并确定何时、如何以及是否该方法实际执行。如果需要以线程安全的方式在方法执行之前和之后共享状态,则使用它。
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.ProceedingJoinPoint;

NOTE:最弱方式,即如果前通知可以做,就不要使用围绕通知。
@Around("com.niit.myapp.SystemArchitecture.dataAccessOperation()")

使用XML配置启用@AspectJ支持
<aop:aspectj-autoproxy/>

2.基于spring 模式的AOP(XML配置)
声明方面
使用模式支持,方面只是在spring应用程序上下文中定义为bean的常规Java对象。状态和行为在对象的字段和方法中捕获,切入点和通知信心在XML中捕获。
<aop:config>
<aop:aspect id="myAspect" ref="aBean"> //声明方面。后台Bean,使用ref属性引用
...
</aop:aspect>
</aop:config>

声明切入点
切入点是Spring AOP中的一种表达式语言,表示服务层中任何业务执行的切入点可以定义如下:
<aop:config>
<aop:pointcut id="bussinessService" expression="execution(* com.niit.myapp.service.*.*(..))"/>
</aop:config>

切入点表达式
应用于所有公共方法
<aop:pointcut expression=("execution(public * *(..))")>
应用于所有操作类的公共方法
<aop:pointcut expression=("execution(public Operation. *(..))")>
应用于操作类的所有方法
<aop:pointcut expression=("execution(Operation.*(..))")>
应用于所有员工类的公共setter方法
<aop:pointcut expression="execution(public Employee.set . *(..))")>
应用于所有操作类返回int 值的方法
<aop:pointcut expression="execution(int Operation.*(..))")>

声明通知
前通知
<aop:aspect id="beforeExample" ref="aBean">
<aop:before
pointcut-ref="dataAccessOperation" method="doAccessCheck"/>
</aop:aspect >

返回后通知
<aop:aspect id="afterReturningExample" ref="aBean">
<aop:after-returning
pointcut-ref="dataAccessOperation" method="doAccessCheck"
returning="retval"/>
</aop:aspect >

可以在通知主体中获得返回值,使用返回值标记属性来指定应该传递返回值的参数的名称。
新增一个returning 属性
doAccessCheck方法必须指明一个返回值的参数的名称,签名的方式可以是
public void doAccessCheck(Object reVal){...}

抛出后通知
当匹配的方法执行通过抛出异常结束时执行通知。
<aop:aspect id="afterThrowingExample" ref="aBean">
<aop:after-throwing
pointcut-ref="dataAccessOperation"
throwing ="dataAccessEx"
method="doAccessRecoveryActions"/>
</aop:aspect >

使用抛出标记属性指定异常一个传递到的参数名称
新增一个throwing属性,对应的方法必须声明一个对应的参数(同上)
后通知
在匹配的方法执行退出时执行
<aop:aspect id=afterExample" ref="aBean">
<aop:after
pointcut-ref="dataAccessOperation" method="doRelease"/>
</aop:aspect >

围绕通知
(表述和用注释配置相同)
围绕通知是使用aop:Around元素声明的,通知方法的第一个参数必须是ProceedingJoinPoint类型,在通知的主体中,对ProceedingJoinPoint调用proceed()将执行底层方法。
<aop:aspect id=afterExample" ref="aBean">
<aop:around
pointcut-ref="dataAccessOperation" method="doBasicProfiling"/>
</aop:aspect >

3.使用spring API的AOP
步骤:
创建通知——>定义切入点——>创建代理
创建代理
通知是方面在特定连接点上采取的操作。它是通过创建一个函数,来表示应用程序的辅助逻辑实现的。
一个应用程序可以有一个或者多个通知。
spring API aop中实现4种类型的通知
前通知在实际方法调用之前执行
后通知在实际的方法调用之后执行,如果方法返回值,则在返回值之后执行。
围绕通知在实际方法调用之前和之后执行。
抛出后通知,如果实际方法抛出异常,则执行该方法。

前通知:
它没有中断程序执行的能力,除非抛出异常。
导入org.springfrawork.aop.MethodBeforeAdvice 接口
在接口中定义before方法
public void before{
Method method,Object [] args,Object target
}throws Throwable
method:第一个参数,表示通知用到的方法
args:是对象类型的数组,该数组包含调用方法时传递给方法的参数
target:表示方法调用的目标

返回后:
这个通知再连接带你正常完成后执行
导入org.springframework.aop.AfterReturningAdvice接口
public void afterReturning(Object returnValue, Method method,Object[] arg,
Oject target)throws Throwable
四个参数
returnValue:保存从被调用的方法返回的值
其余三个参数同上

returnValue:保存从被调用的方法返回的值
抛出后
导入org.springframework.aop.ThrowsAdvice接口
public void afterThrowing (Throwable throwbale)
after-throwing()方法接收可抛出类型的一个参数,该参数指示应由通知处理的异常。

创建通知,spring提供的配置元素——
aop:config:定义其中所有AOP的配置,它可以包含定义切入点、通知和方面的元素
aop:aspect:用于声明一个方面,有一个ref标记属性,该属性引用spring配置文件中的定义的相应的方面bean
aop:before:用于定义连接点之前执行的一个方法
aop:after-returning:用于定义连接点之后执行的一个方法
aop:after-throwing:用于定义抛出时异常执行的一个方法
aop:around:用于定义连接点之前和之后执行的一个方法
定义切入点
定义切入点来说明通知要被应用的位置。
切入点的主要目的是选择一个通知应用的地方的方法。切入点在spring配置文件中定义。
要辨别可以应用通知的特定位置或方法,需要指定模式
此模式包含使用正则表达式调用的方法的名称,正则表达式为匹配文本字符串
使用正则表达式定义切入点:
org.springframework.aop.support.JdkRegexpMethodPointcut类
pattern属性,该属性的value标记属性用于指定调用方法的特定模式
使用通配符指定模式,星号*,表示任何类、方法、返回类型或者参数;或者零个或者多个参数的点字符(..)来指定切入点的模式
创建通知器 org.springframework.aop.support.DefaultPonitcutAdvisor,使用其再spring配置文件中定义一个advisor bean
Example:



创建代理
创建一个调用该advisor的地理
代理充当通知、目标对象、连接点、切入点和通知器之间的链接
代理在spring配置文件中作为bean创建,spring提供了org.springframework.aop.config.ProxyFactoryBean类
传递以下参数来创建一个代理
Target:指定您想代理代理的目标对象
interceptorName:代表类型的数组,字符串。指定在spring 配置文件中advisor bean名称列表
proxyInterfaces:代表类型的数组,字符串。指定定义应用程序主要逻辑的接口名称
Example:

mypointCutAdivice

原文地址:https://www.cnblogs.com/star-bloom-blog/p/15079392.html