首页 > 编程语言 > 详细

springAOP

时间:2020-08-26 13:55:36      阅读:83      评论:0      收藏:0      [点我收藏+]
SpringAOP
spring-aop.jar包还依赖于:aopalliance-1.0,aspectj-1.7.3,aspectjweaver-1.7.4,cglib-nodep-2.1_3(动态代理)
  1. AOP:aspect oriented programming  面向切面编程,这个以oop为基础,oop侧重对象的封装,aop侧重某个共同逻辑的提取。可以把共通的逻辑和传统的逻辑隔离,封装成独立组件,通过aop配置建立作用,降低业务之间的耦合度。
  2. aop相关概念
##关注点:如安全 缓存 日志
 
(2)JointPoint(连接点):所谓连接点是指那些被拦截到的点。在 spring 中,这些点指的是方法,因为 spring 只支持方法类型的连接点。
(4)Pointcut(切入点):对哪些JoinPoint进行拦截的定义,在程序中主要体现为书写切入点表达式
(3)Advice(通知):指拦截到 Joinpoint 之后所要做的事情,有before,after,afterReturning,afterThrowing,around
(4)Weaving(织入)是指把增强应用到目标对象来创建新的代理对象的过程。spring 采用动态代理织入,而 AspectJ 采用编译期织入和类装载期织入
(1)Aspect(切面):通常是一个类,是切入点和通知(引介)的结合。
(5)AOP代理:AOP框架创建的对象,代理就是目标对象的加强。Spring中的AOP代理可以使JDK动态代理,也可以是CGLIB代理,前者基于接口,后者基于子类
 
Try{
前置通知:@Before
目标方法:
后置通知:@AfterReturning
}catch{
异常通知:@AfterThrowing
}finally{
最终通知: @After
}
环绕通知:==前置通知+后置通知 @Around
##切入点 pointcut
指定目标组件和方法,spring提供了几种切入点表达式
###方法限定表达式 
execution([修饰符] 返回值类型 包名.类名.方法名(参数))
 
修饰符可以不写,
返回值可以使用*号,表示任意返回值
包名可以使用*号,表示任意包,但是有几级包,需要写几个*  比如  * *.*.*.*.AccountServiceImpl.saveAccount(com.zy.Acount)
使用..来表示当前包,及其子包    * com..AccountServiceImpl.saveAccount(com.itheima.domain.Account)
类名、方法名可以使用*号,表示任意类,参数列表可以使用*,表示参数可以是任意数据类型,但是必须有参数   * com..*.saveAccount(*)
参数列表可以使用..表示有无参数均可, * com..*.saveAccount(..)
 
 
 
  1. 基于springAOP实现。
2.1基于XML配置实现
编程步骤:编写aop组件类后,把aop组件和目标代理装载到spring容器中,这不管是扫描还是配bean都可以,最后在spring配置文件中配置aop
##导包aop的jar包,写AOP组件类,
 
//所有方法都可以添加一个参数JoinPoint,表示连接点的方法,这样可以获取被代理类的方法的名字,参数等信息
public class MyAspect{
public void businessService(){} //声明一个切点,方法为空
public void doBeforeTask(){ ... }  
public void doAfterTask(){ ... }
public void doAfterReturnningTask(Object retVal){  }   //必须添加reVal参数,这是被代理方法的返回值。
public void doAfterThrowingTask(Exception ex){  } //默认遇到runtimeexception和error的异常才执行aop,可以指定想要的exception,这样遇到它和它的子类就会执行。
public Object doAroundTask(ProceedingJoinPoint pj){
//aop前置通知
 Object result =pj.proceed();//必须穿一个ProceedingJoinPoint,这是连接点的调用,//表示执行目标组件方法,它的返回值是执行被代理方法的返回值,
//aop后置通知
return result; //必须有一个返回值,表示被代理方法的返回值
 } 
}
 
##在spring。Xml中配置
 
<!--配置那个aop通过哪种面向哪个切入点-->
<aop:config> <aop:aspect id="aspect" ref="myAspect">
<aop:pointcut id="businessService" expression="execution(* com.xyz.myapp.service.*.*(..))"/>
<aop:before pointcut-ref="businessService" method="doBeforeTask"/>
<aop:after pointcut-ref="businessService" method="doAfterTask"/>
<aop:after-returning pointcut-ref="businessService" returning="retVal" method="doAfterReturnningTask"/>
<aop:after-throwing pointcut-ref="businessService" throwing="ex" method="doAfterThrowingTask"/>
<aop:around pointcut-ref="businessService" method="doAroundTask"/>
... </aop:aspect> </aop:config> <bean id="myAspect" class="..."> ... </bean>
 
2.2基于注解的aop
编程步骤:
导包aop的jar包
<!-- aop的配置,开启组件扫描,把aop组件扫描到spring中 -->
<context:component-scan base-package="cn.tedu.cloudnote.aop"/>
<!-- 开启aop注解扫描 ,支持切面,通知,切入点注解,后面代表代理目标是类,为了选择不同的代理方式-->
        <aop:aspectj-autoproxy proxy-target-class=”true”/>
 //加入spring容器中,在aop组件类上添加组件扫描注解,把这个组件扫描到spring中,        如加上@Component
@Component,把这个组件扫描到spring中, 
@Aspect//表示这个类组件是切面
 
步骤:
  1.在切面类(为切点服务的类)前用@Aspect注释修饰,声明为一个切面类。
  2.用@Pointcut注释声明一个切点,目的是为了告诉切面,谁是它的服务对象。这个可以不写,但是切入点可能会被对个通知重用,就这样写(此注释修饰的方法的方法体为空,不需要写具体功能,比如 public void say(){};
  3.在对应的方法前用对应的通知类型注释修饰,将对应的方法声明称一个切面功能,为了切点而服务
  4.在spring配置文件中开启aop注释自动代理。如:<aop:aspectj-autoproxy/>,如果不是用xml配置方式,在配置类上使用@EnableAspectJAutoProxy
@Configuration
@ComponentScan(basePackages="com.itheima")
@EnableAspectJAutoProxy
public class SpringConfiguration {
}
 
 
//所有方法都可以添加一个参数JoinPoint,表示连接点的方法,这样可以获取被代理类的方法的名字,参数等信息
可以使用 @Order 注解指定切面的优先级, 值越小优先级越高,因为一个连接点上可能有多个切面。 
@Order(2)
@aspect
public class MyAspect{
@pointcout("execution(* *.saying(..))") 
public void businessService(){} //声明一个切点,方法为空
 
@Before("businessService()")
 public void doBeforeTask(){ ... }  
 
@After("businessService()") 
public void doAfterTask(){ ... }
 
@AfterReturning(pointcut = "businessService()", returning="retVal")
 public void doAfterReturnningTask(Object retVal){  }   //必须添加reVal参数,这是被代理方法的返回值。
 
@AfterThrowing(pointcut = "businessService()", throwing="ex")
 public void doAfterThrowingTask(Exception ex){  } //默认遇到runtimeexception和error的异常才执行aop,可以指定想要的exception,这样遇到它和它的子类就会执行。
 
@Around("businessService()")
 public Object doAroundTask(ProceedingJoinPoint pj){ pj.proceed(); } //必须穿一个ProceedingJoinPoint,这是连接点的调用,//表示执行目标组件方法,它的返回值是执行被代理方法的返回值,
}
 
 
# 组件作用到所有controller上这样可以在不修改原代码,增加组件的新功能
  1. AOP实现原理
Spring AOP采用动态代理设计模式实现的,使用AOP之后,spring容器会根据目标组件动态生成一个新的组件类型,该类被称为‘动态代理类’,这个类重写了原有目标组件的业务方法,在重写方法中调用切面功能和原组件功能。
Spring动态代理技术有两种:
#采用JDK自带的java.reflect.Proxy实现
默认适用有接口的组件
#采用CGLIB技术生成
默认适用没有接口的组件

springAOP

原文:https://www.cnblogs.com/zhouyanger/p/13564449.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!