Spring AOP

一、什么是AOP ?

  1. AOP是 Aspect Oriented Programming(面向切面编程) 的简称,和OOP(面向对象编程)一样是一种编程思想,是对OOP的一种补充。

  2. AOP旨在将横切关注点(crosscutting concern)从业务主体逻辑中进行剥离,实现关注点分离,以提高程序的模块化程度(及业务模块只需关注业务逻辑,无需关注日志、安全、事务等通用逻辑)

二、AOP常见概念

  1. 切面(Aspect):具有一定横切逻辑的类,用于封装特定的横切关注点,例如:事务、日志、安全等。

  2. 切点(Pointcut):表示横切关注点的位置,通常定义在方法粒度上,可以通过表达式或注解等方式进行定义。

  3. 通知(Advice):定义了特定的横切逻辑,包括前置通知、后置通知、环绕通知、异常通知等。

  4. 织入(Weaving):将切面的逻辑应用到目标对象中,目标对象可以是一个类或者一个方法,实现了横切逻辑和业务逻辑的分离。

  5. 引入(Introduction):一种特殊的通知形式,用于向目标对象引入新的方法或属性。

  6. 连接点(Join Point):在应用程序执行过程中能够进行拦截的具体点,例如:方法调用、属性访问、异常处理等。

  7. 切面顺序(Aspect Ordering):当多个切面对一个连接点进行拦截时,决定拦截顺序的规则。

  8. 目标对象( Target ):指被切面织入的对象

三、Spring AOP的动态代理模式

  1. JDK 动态代理

    概念:JDK 动态代理是 Java 语言本身提供的一种动态代理实现方式,通过反射机制动态地创建一个代理类,在代理对象中调用目标对象的方法,实现对目标对象的增强。JDK 动态代理要求代理的目标对象必须实现一个接口,在创建代理对象时需要传入一个 InvocationHandler 对象,该对象实现了对目标对象方法的增强逻辑。在使用 JDK 动态代理时,Spring AOP 可以通过配置文件或注解等方式进行配置和使用。

    1. 定义“目标对象”实现的业务接口。

      public interface UserService {
          void addUser();
      }
      
      public class UserServiceImpl implements UserService {
          @Override
          public void addUser() {
              System.out.println("Add user...");
          }
      }
    2. 通过定义一个 InvocationHandler 对象,包含目标对象和横切逻辑。

      public class MyInvocationHandler implements InvocationHandler {
          private Object target;
      
          public MyInvocationHandler(Object target) {
              this.target = target;
          }
      
          @Override
          public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
              System.out.println("Before method calling...");
              Object result = method.invoke(target, args);
              System.out.println("After method calling...");
              return result;
          }
      }
    3. 使用 Proxy 类的静态方法 newProxyInstance(ClassLoader, Class[], InvocationHandler) 动态创建一个代理对象,并指定代理对象和 InvocationHandler 对象。

      public class ProxyDemo {
          public static void main(String[] args) {
              UserService userService = new UserServiceImpl();
              InvocationHandler handler = new MyInvocationHandler(userService);
              UserService proxy = (UserService) Proxy.newProxyInstance(userService.getClass().getClassLoader(),
                      userService.getClass().getInterfaces(), handler);
              proxy.addUser();
          }
      }
    4. 代理对象调用方法时,会被转发到 InvocationHandler 对象处理,从而实现对目标对象的增强。

  2. CGLIB 动态代理

    概念:CGLIB 动态代理是一个基于字节码技术的动态代理实现方式,不需要目标对象实现接口,通过创建目标对象的子类来实现对目标对象的代理。CGLIB 动态代理使用 Enhancer 类生成目标对象的子类,并重写其中的方法,将增强逻辑插入到目标对象方法的前后,实现对目标对象的增强。CGLIB 动态代理通常被用于 AOP 框架中对没有接口的 Java 对象进行代理。在使用 CGLIB 动态代理时,Spring AOP 可以通过配置文件或注解等方式进行配置和使用。

    1. 在运行时,通过继承目标类生成一个代理类。

      public class UserService {
          public void addUser() {
              System.out.println("Add user...");
          }
      }

    2. 在代理类中重写目标类的非 final 方法,在方法中委托拦截器处理横切逻辑。

      public class MyMethodInterceptor implements MethodInterceptor {
          @Override
          public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
              System.out.println("Before method calling...");
              Object result = methodProxy.invokeSuper(o, args);
              System.out.println("After method calling...");
              return result;
          }
      }
    3. 通过创建代理类的实例,对目标对象进行代理。

      public class ProxyDemo {
          public static void main(String[] args) {
              Enhancer enhancer = new Enhancer();
              enhancer.setSuperclass(UserService.class);
              enhancer.setCallback(new MyMethodInterceptor());
              UserService userService = (UserService) enhancer.create();
              userService.addUser();
          }
      }

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值