12.21 Spring AOP
本章内容
什么是
SpringAOP?
为什么使用
SpringAOP
AOP术语
什么是SpringAOP?
AOP全称Aspect Oriented Programming面向切面编程。和OOP一样,是一种编程思想
AOP的特点:
- 
采用动态代理机制取代传统的继承机制。减少重复性代码 
- 
分离功能性需求和非功能性需求,增强代码的可读性和可维护性 
保证开发者在不修改源代码的前提下,为系统中的业务组件添加通用功能。AOP就是代理模式的典型应用
目前最流行的AOP框架
Spring AOP,它有两种实现方式
基于接口的
JDK动态代理
基于继承的
CGLB动态代理
AspectJ
Spring JDK动态代理
实现方法:
实现InvocationHandler接口,重写invoke方法,客户端使用Java.lang.reflect.Proxy类产生动态代理类的对象。
代码实现:
agency包:
package com.web.agency;
/**
 * @description:aop切面的两个增强方法
 * @data: 2021/12/21 14:55
 * @author: Lucifer
 */
public class MyAspect {
    public void myBefore(){
        System.out.println("方法执行前!");
    }
    public void myAfter(){
        System.out.println("方法执行后!");
    }
}
dynamic包:
package com.web.dynamic;
import com.web.agency.MyAspect;
import com.web.service.UserManager;
import com.web.service.impl.UserManagerImpl;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
 * @description:aop的动态代理类,实现invocationHandler接口
 * @data: 2021/12/21 15:03
 * @author: Lucifer
 */
public class JdkProxy implements InvocationHandler {
    private Object target; // 需要代理的目标对象
    final MyAspect myAspect = new MyAspect();
    /* 重写拦截方法 */
    
service包:
package com.web.service;
/**
 * @description:spring的aop练习,位于service层
 * @data: 2021/12/21 14:48
 * @author: Lucifer
 */
public interface UserManager {
    /* CURD操作 */
    // 新增用户
    void addUser(String userName, String password);
    // 删除用户
    void delUser(String userName);
}
service.impl包:
package com.web.service.impl;
import com.web.service.UserManager;
/**
 * @description:spring的aop练习,位于service层接口的实现类
 * @data: 2021/12/21 14:49
 * @author: Lucifer
 */
public class UserManagerImpl implements UserManager {
    
Spring CGLIB动态代理
特点:
不需要实现接口(Spring核心包当中已经集成了CGLIB所需要的包)
具体实现:(其他的地方大致和上面的JDK动态代理一致,下面只记有区别的类)
package com.web.dynamic;
import com.web.agency.MyAspect;
import com.web.service.UserManager;
import com.web.service.impl.UserManagerImpl;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
/**
 * @description:aop的另外一种代理方式:cglib
 * @description:实现methodinterceptor接口位于cglib包下
 * @data: 2021/12/21 16:51
 * @author: Lucifer
 */
public class CglibProxy implements MethodInterceptor {
    private Object target; // 需要代理的目标
    final MyAspect myAspect = new MyAspect();
    // 重写拦截方法
    
两个动态代理的区别
JDK动态代理特点
- 
代理对象必须实现一个或多个接口 
- 
以接口的形式接收代理实例,而不是代理类 
CGLIB动态代理特点
- 
代理对象不能被 final 修饰 
- 
以类或接口形式接收代理实例 
JDK与CGLIB动态代理的性能比较
生成代理实例性能:JDK > CGLIB 代理实例运行性能:JDK > CGLIB
特点:
- 
JDK 动态代理是利用反射机制生成一个实现代理接口的匿名类,在调用具体方法前调用 InvokeHandler 来处理。 
- 
CGLIB 动态代理是利用 ASM 开源包,加载代理对象类的 class 文件,通过修改其字节码生成子类来处理。 
- 
JDK 动态代理只能对实现了接口的类生成代理,而不能针对类。 
- 
CGLIB 是针对类实现代理,主要是对指定的类生成一个子类,覆盖其中的方法。因为是继承,所以该类或方法不能声明成 final 类型。 
为什么使用AOP
AOP的好处:
- 
提供了一种可插入的方式,可在实现逻辑之前、之后、周围添加其他关注点 
举例:
class A{ 
    public void m1(){...} 
    public void m2(){...} 
    public void m3(){...} 
    public void m4(){...} 
    public void m5(){...} 
    public void n1(){...} 
    public void n2(){...} 
    public void p1(){...} 
    public void p2(){...} 
    public void p3(){...} 
}
如果需要不同字母开头的方法执行传统的做法:分别修改方法的内容
如果使用AOP,则不用在方法内调用发送通知的方法,只需要在类的方法中定义切入点,然后在XML文件中调用。如果需要删除或修改此功能,那么只需要在XML文件中进行更改。使用AOP可以增强代码的可维护性。--->个人理解其作用是改变这种继承调用的方式。同时减少代码量
AOP术语
这些术语适用于其他AOP框架:
| 名称 | 说明 | 
|---|---|
| Joinpoint(连接点) | 指那些被拦截到的点,在 Spring 中,指可以被动态代理拦截目标类的方法。 | 
| Pointcut(切入点) | 指要对哪些 Joinpoint 进行拦截,即被拦截的连接点。 | 
| Advice(通知) | 指拦截到 Joinpoint 之后要做的事情,即对切入点增强的内容。 | 
| Target(目标) | 指代理的目标对象。 | 
| Weaving(植入) | 指把增强代码应用到目标上,生成代理对象的过程。 | 
| Proxy(代理) | 指生成的代理对象。 | 
| Aspect(切面) | 切入点和通知的结合。 | 
增强处理:
| 通知 | 说明 | 
|---|---|
| before(前置通知) | 通知方法在目标方法调用之前执行 | 
| after(后置通知) | 通知方法在目标方法返回或异常后调用 | 
| after-returning(返回后通知) | 通知方法会在目标方法返回后调用 | 
| after-throwing(抛出异常通知) | 通知方法会在目标方法抛出异常后调用 | 
| around(环绕通知) | 通知方法会将目标方法封装起来 | 
AOP的好处:
- 
AOP是Spring的核心之一,在Spring中经常会使用AOP来简化编程。
- 
提供声明式企业服务,服务是声明式事务管理。 
- 
允许用户实现自定义切面。在某些不适合用 OOP编程的场景中,采用AOP来补充。
- 
可以对业务逻辑的各个部分进行隔离,使业务逻辑各部分之间的耦合度降低,提高程序的可重用性,提高开发效率。 
- 
 
                    
                     
                    
                 
                    
                
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号