03-spring框架—— AOP 面向切面编程
Posted tpf386
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了03-spring框架—— AOP 面向切面编程相关的知识,希望对你有一定的参考价值。
3.1 动态代理
动态代理是指,程序在整个运行过程中根本就不存在目标类的代理类,目标对象的代理
对象只是由代理生成工具(不是真实定义的类)在程序运行时由 JVM 根据反射等机制动态
生成的。代理对象与目标对象的代理关系在程序运行时才确立。
3.1.1 JDK
动态代理的实现方式常用的有两种:使用 JDK 的 Proxy,与通过 CGLIB 生成代理。
Jdk 的动态要求目标对象必须实现接口,这是 java 设计上的要求。
从 jdk1.3 以来,java 语言通过 java.lang.reflect 包提供三个类支持代理模式 Proxy, Method 和
InovcationHandler。
3.1.2 CGLIB 动态代理( 了解)
CGLIB(Code Generation Library)是一个开源项目。是一个强大的,高性能,高质量的 Code
生成类库,它可以在运行期扩展 Java 类与实现 Java 接口。它广泛的被许多 AOP 的框架
使用,例如 Spring AOP。
使用 JDK 的 Proxy 实现代理,要求目标类与代理类实现相同的接口。若目标类不存在
接口,则无法使用该方式实现。但对于无接口的类,要为其创建动态代理,就要使用 CGLIB
来实现。
CGLIB 代理的生成原理是生成目标类的子类,而子类是增强过的,这个子类对象就是代
理对象。所以,使用 CGLIB 生成动态代理,要求目标类必须能够被继承,即不能是 final 的
类。
CGLIB 经常被应用在框架中,例如 Spring ,Hibernate 等。cglib 的代理效率高于 Jdk。
项目中直接使用动态代理的地方不多。一般都使用框架提供的功能。
3.2 不使用 AOP 的开发方式 (理解)
Step1: 项目 aop_leadin1
先定义好接口与一个实现类,该实现类中除了要实现接口中的方法外,还要再写两个非
业务方法。非业务方法也称为交叉业务逻辑:
? doTransaction():用于事务处理
? doLog():用于日志处理
然后,再使接口方法调用它们。接口方法也称为主业务逻辑。
Step2: 项目 aop_leadin2
当然,也可以有另一种解决方案:将这些交叉业务逻辑代码放到专门的工具类或处理类
中,由主业务逻辑调用。
Step3: 项目 aop_leadin3
以上的解决方案,还是存在弊端:交叉业务与主业务深度耦合在一起。当交叉业务逻辑
较多时,在主业务代码中会出现大量的交叉业务逻辑代码调用语句,大大影响了主业务逻辑
的可读性,降低了代码的可维护性,同时也增加了开发难度。
所以,可以采用动态代理方式。在不修改主业务逻辑的前提下,扩展和增强其功能。
功能增强:
package com.bjpowernode.proxy; import com.bjpowernode.utils.ServiceTools; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; /** * Author: 动力节点 * 2019/5/10 */ public class MyInvocationHandler implements InvocationHandler private Object target; public MyInvocationHandler() public MyInvocationHandler(Object target) this.target = target; /** * 实现业务方法的功能增强。 加入日志,事务功能 * @param proxy 生成的代理对象 * @param method 业务方法 * @param args 业务方法的参数 * @return Object 业务方法的返回值 * @throws Throwable */ @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable Object result = null; String mname = method.getName(); if( "doSome".equals(mname)) //在目标方法调用之前加入日志 ServiceTools.doLog(); //执行目标方法 result = method.invoke(target, args); //doSome //在目标方法调用之后加入事务 ServiceTools.doTrans(); else //doOther //执行目标方法 result = method.invoke(target, args); //目标方法的执行结果 return result;
代码第二部分
package com.bjpowernode; import com.bjpowernode.proxy.MyInvocationHandler; import com.bjpowernode.service.SomeService; import com.bjpowernode.service.SomeServiceImpl; import java.lang.reflect.Proxy; /** * Hello world! * */ public class App /*public static void main( String[] args ) System.out.println( "Hello World!" ); SomeService service = new SomeServiceImpl(); service.doSome(); System.out.println("===================="); service.doOther(); */ public static void main( String[] args ) System.out.println( "Hello World!" ); //目标对象 SomeService target = new SomeServiceImpl(); //创建InvocationHandler的实现类对象 MyInvocationHandler handler = new MyInvocationHandler(target); //创建代理对象 SomeService proxy = (SomeService) Proxy.newProxyInstance( target.getClass().getClassLoader(), target.getClass().getInterfaces(), handler); //com.sun.proxy.$Proxy0 jdk的动态代理类型 System.out.println("proxy:"+proxy.getClass().getName()); //通过代理对象执行业务方法,实现功能的增强 proxy.doSome(); System.out.println("-----------------------------"); proxy.doOther();
3.3 AOP 概述
3.4 AOP
AOP(Aspect Orient Programming),面向切面编程。面向切面编程是从动态角度考虑程
序运行过程。
AOP 底层,就是采用动态代理模式实现的。采用了两种代理:JDK 的动态代理,与 CGLIB
的动态代理。
以上是关于03-spring框架—— AOP 面向切面编程的主要内容,如果未能解决你的问题,请参考以下文章