二、Spring-AOP

代理模式

概述:为某个对象提供代理类,用来控制对这个对象的访问,委托类与代理类有一个共同的父类或父接口,代理类会对请求做预处理、过滤,将请求分配给指定对象。

代理三要素
  1. 有共同的行为
  2. 目标角色
  3. 代理角色
静态代理
特点
  1. 目标角色固定
  2. 应用程序执行前获得目标角色
  3. 代理对象会增强目标角色的行为
  4. 多个代理会出现类爆炸

实现

  1. 定义父类接口
  2. 委托类是是实现父接口
  3. 代理类实现父接口,并其中含有委托类对象属性
  4. 代理在重写的方法中加入增强行为同时调用委托类的方法
动态代理

概述:动态代理类的字节码是在程序运行期间,通过反射动态生成的,可以根据需要动态生成代理对象。可以同时代理多个方法,在满足生产需要的同时又达到代码通用的目的。

特点:

  • 目标角色不固定
  • 应用程序执行时动态创建目标对象
  • 代理对象可以增强目标对象

实现方式:

  1. JDK动态代理(接口实现)
  2. CGLIB动态代理(继承思想)

JDK动态代理

使用Proxy类的newProxyInstance(),是专门完成代理的操作类,可以为一个或多个接口生成实现类,

newProxyInstance(ClassLoder loader,Class<?>[]interface,InvocationHandler h)专门用于生成代理对象

参数解释:

  • ClassLoader:指定为那个类生成代理对象
  • Class<?>[] interface:接口数组,表示需要代理对象的接口,让代理类也是先这个接口
  • InvocationHandler h:表示代理实例的调用处理程序实现的接

实现过程:

  1. 实现InvocationHandler接口
  2. 定义目标对象,并生成构造器
  3. 重新给invoke()方法,其中是增强方法
  4. 获取代理对象,通过Proxy.newProxyInstance()

CGLIB动态代理:

概述:有些类不能实现接口,想要实现代理则必须要使用CGLIB动态代理,对指定的目标生成一个子类,并覆盖其中的方法实现增强。

使用方式:

  1. 添加相关依赖,cglib
  2. 定义生成动态代理的类,定义代理的目标角色,并为其生成构造器
  3. 生成代理对象,通过Enhancer类生成代理类,首先是生成一个类,设置其父类(目标角色),设置拦截器,通过create()方法生成一个代理类对象
  4. 实现MethodInterceptor接口,重写interceptor(Object object, Method method, Object[] objects, MethodProxy methodProxy)方法其中含有增强行为,参数含义
    • object:CGLIB代理对象
    • method:共同的父类
    • objects:参数列表
    • methodProxy:生成的代理对象对方法进行代理

JDK动态代理与CGLIB动态代理的区别:

  • JDK动态代理依赖接口实现,CGLIB动态代理依赖继承
  • JDK动态代理比CGLIB动态代理效率要高
  • 委托类含有接口实现,则使用JDK动态代理;不含有接口实现,使用CGLIB动态代理

SPring-AOP

作用:日志记录,性能统计,安全控制等重复使用的功能。

特点:

  1. 高内聚低耦合
  2. 提高了代码的复用性
  3. 增强了系统的可扩展性
  4. 同时可以在不影响系统原有功能的前提下,为类添加新的方法或属性

底层实现:动态代理JDK以及CGLIB

基本概念:

  1. JoinPoint连接点:被拦截的每个方法
  2. Pointcute:切入点,拦截规则
  3. advice
    • 前置通知
    • 返回通知
    • 异常抛出通知
    • 最终通知
    • 环绕通知
  4. Aspect:切面
  5. target:目标角色
  6. weave:织入,切面应用到目标对象并生成代理对象的过程
  7. Introduction:不修改原应用程序的基础上,为类动态的添加方法或者属性(在程序运行期间)
注解实现
  1. 添加坐标依赖aspectjweaver
  2. 添加spring.xml配置
  3. 定义切面类,类上添加@Aspect 声明当前类为一个切面
  4. 定义切入点(切入规则)@Pointcut("匹配规则")
    • 执行任意公共方法:execution(public *(..))
    • 执行任意set方法:execution(* set*(..))
    • 执行任意包下的任意类的任意方法:execution(* com.xx.service.*.*(..))
    • 执行指定包下的任意类的任意子包的任意方法:execution(* com.xxxx.service..*.*(..))
  5. 通知注解:
    • 前置通知:@Before(value="")
    • 返回通知:@AfterReturning(value="")
    • 最终通知:@After(value="")
    • 异常抛出通知:@AfterThrowing(value="",throwing="e")
    • 环绕通知:@Around(value="")
  6. 配置文件配置AOP代理:<aop:aspectj-autoproxy/>
XML实现

实现步骤上同:

但是注入是在XML配置文件中完成的:

<asp:config>
	<asp:aspect ref="切面类名">
 	定义切入规则
     各种通知配置
 </asp:aspect>
</asp:config>

拓展:SpringTask

作用是:进行固定时间执行指定任务,优点是功能强大,使用简单

使用方式:

XML配置使用:

  1. 定义定时工作类,加上@Component注解

  2. XML文件中设置,

    <!--添加的xmlns-->
    xmlns:task="http://www.springframework.org/schema/task"
    
    http://www.springframework.org/schema/task
    http://www.springframework.org/schema/task/spring-task.xsd
    
    <!--设置自动扫描注解-->
    <context:component-scan base-package="包名"></context:component-scan>
    <!--注入定时执行事件-->
    <task:scheduled-tasks>
    	<!--每隔2秒执行一次-->
        <task:scheduled ref="定时任务id" method="定时任务(方法)" cron="(0/2 * * * * ?)"></task:scheduled> 
    </task:scheduled-tasks>
    

    调用中测试(注意要在main方法中测试):

代理模式

概述:为某个对象提供代理类,用来控制对这个对象的访问,委托类与代理类有一个共同的父类或父接口,代理类会对请求做预处理、过滤,将请求分配给指定对象。

代理三要素
  1. 有共同的行为
  2. 目标角色
  3. 代理角色
静态代理
特点
  1. 目标角色固定
  2. 应用程序执行前获得目标角色
  3. 代理对象会增强目标角色的行为
  4. 多个代理会出现类爆炸

实现

  1. 定义父类接口
  2. 委托类是是实现父接口
  3. 代理类实现父接口,并其中含有委托类对象属性
  4. 代理在重写的方法中加入增强行为同时调用委托类的方法
动态代理

概述:动态代理类的字节码是在程序运行期间,通过反射动态生成的,可以根据需要动态生成代理对象。可以同时代理多个方法,在满足生产需要的同时又达到代码通用的目的。

特点:

  • 目标角色不固定
  • 应用程序执行时动态创建目标对象
  • 代理对象可以增强目标对象

实现方式:

  1. JDK动态代理(接口实现)
  2. CGLIB动态代理(继承思想)

JDK动态代理

使用Proxy类的newProxyInstance(),是专门完成代理的操作类,可以为一个或多个接口生成实现类,

newProxyInstance(ClassLoder loader,Class<?>[]interface,InvocationHandler h)专门用于生成代理对象

参数解释:

  • ClassLoader:指定为那个类生成代理对象
  • Class<?>[] interface:接口数组,表示需要代理对象的接口,让代理类也是先这个接口
  • InvocationHandler h:表示代理实例的调用处理程序实现的接

实现过程:

  1. 实现InvocationHandler接口
  2. 定义目标对象,并生成构造器
  3. 重新给invoke()方法,其中是增强方法
  4. 获取代理对象,通过Proxy.newProxyInstance()

CGLIB动态代理:

概述:有些类不能实现接口,想要实现代理则必须要使用CGLIB动态代理,对指定的目标生成一个子类,并覆盖其中的方法实现增强。

使用方式:

  1. 添加相关依赖,cglib
  2. 定义生成动态代理的类,定义代理的目标角色,并为其生成构造器
  3. 生成代理对象,通过Enhancer类生成代理类,首先是生成一个类,设置其父类(目标角色),设置拦截器,通过create()方法生成一个代理类对象
  4. 实现MethodInterceptor接口,重写interceptor(Object object, Method method, Object[] objects, MethodProxy methodProxy)方法其中含有增强行为,参数含义
    • object:CGLIB代理对象
    • method:共同的父类
    • objects:参数列表
    • methodProxy:生成的代理对象对方法进行代理

JDK动态代理与CGLIB动态代理的区别:

  • JDK动态代理依赖接口实现,CGLIB动态代理依赖继承
  • JDK动态代理比CGLIB动态代理效率要高
  • 委托类含有接口实现,则使用JDK动态代理;不含有接口实现,使用CGLIB动态代理

SPring-AOP

作用:日志记录,性能统计,安全控制等重复使用的功能。

特点:

  1. 高内聚低耦合
  2. 提高了代码的复用性
  3. 增强了系统的可扩展性
  4. 同时可以在不影响系统原有功能的前提下,为类添加新的方法或属性

底层实现:动态代理JDK以及CGLIB

基本概念:

  1. JoinPoint连接点:被拦截的每个方法
  2. Pointcute:切入点,拦截规则
  3. advice
    • 前置通知
    • 返回通知
    • 异常抛出通知
    • 最终通知
    • 环绕通知
  4. Aspect:切面
  5. target:目标角色
  6. weave:织入,切面应用到目标对象并生成代理对象的过程
  7. Introduction:不修改原应用程序的基础上,为类动态的添加方法或者属性(在程序运行期间)
注解实现
  1. 添加坐标依赖aspectjweaver
  2. 添加spring.xml配置
  3. 定义切面类,类上添加@Aspect 声明当前类为一个切面
  4. 定义切入点(切入规则)@Pointcut("匹配规则")
    • 执行任意公共方法:execution(public *(..))
    • 执行任意set方法:execution(* set*(..))
    • 执行任意包下的任意类的任意方法:execution(* com.xx.service.*.*(..))
    • 执行指定包下的任意类的任意子包的任意方法:execution(* com.xxxx.service..*.*(..))
  5. 通知注解:
    • 前置通知:@Before(value="")
    • 返回通知:@AfterReturning(value="")
    • 最终通知:@After(value="")
    • 异常抛出通知:@AfterThrowing(value="",throwing="e")
    • 环绕通知:@Around(value="")
  6. 配置文件配置AOP代理:<aop:aspectj-autoproxy/>
XML实现

实现步骤上同:

但是注入是在XML配置文件中完成的:

<asp:config>
	<asp:aspect ref="切面类名">
 	定义切入规则
     各种通知配置
 </asp:aspect>
</asp:config>

拓展:SpringTask

作用是:进行固定时间执行指定任务,优点是功能强大,使用简单

使用方式:

XML配置使用:

  1. 定义定时工作类,加上@Component注解

  2. XML文件中设置,

    <!--添加的xmlns-->
    xmlns:task="http://www.springframework.org/schema/task"
    
    http://www.springframework.org/schema/task
    http://www.springframework.org/schema/task/spring-task.xsd
    
    <!--设置自动扫描注解-->
    <context:component-scan base-package="包名"></context:component-scan>
    <!--注入定时执行事件-->
    <task:scheduled-tasks>
    	<!--每隔2秒执行一次-->
        <task:scheduled ref="定时任务id" method="定时任务(方法)" cron="(0/2 * * * * ?)"></task:scheduled> 
    </task:scheduled-tasks>
    

    调用中测试(注意要在main方法中测试):

在这里插入图片描述

注解形式(推荐使用):

在定时任务上添加@Scheduled(cron="(0/2 * * * * ?)")注解,使用cron表达式规定定时任务执行时间。

同时在XML配置文件中加上:<task:annotation-driven/>配置定时任务驱动

注解形式(推荐使用):

在定时任务上添加@Scheduled(cron="(0/2 * * * * ?)")注解,使用cron表达式规定定时任务执行时间。

同时在XML配置文件中加上:<task:annotation-driven/>配置定时任务驱动

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值