顾乔芝士网

持续更新的前后端开发技术栈

Spring Boot中AOP介绍(一)原来AOP是这么回事

今天聊一聊Spring Boot中AOP的原理。AOP是Aspect-Oriented Programming的缩写,意为面向切面编程,可以方便地实现不同模块之间的代码重用,同时也是Spring Boot中解耦、事务支持等重要的功能实现方式之一。它是一种可以在程序运行时动态横向扩展加强代码功能的方法。它使得开发人员可以更加关注业务逻辑的实现,而不用一遍又一遍地编写样板代码。

那么,Spring Boot是如何实现AOP的呢?它主要依赖于AspectJ框架。

AspectJ是什么?
AspectJ是一种基于Java语言的AOP(Aspect-Oriented Programming,面向切面编程)框架,它可以在编译器级别或运行时为Java应用程序提供横向切面支持。AspectJ通过切面(Aspect)的概念进行描述和实现,提供更为优秀、直观的面向切面编程方法,是AOP的重要实现方式之一。

Spring Boot与AspectJ
在Spring Boot中,AspectJ通常用于实现切面(Aspect),它提供了丰富的注解和语法用于描述和定义切面。Spring Boot的AOP实现就是基于AspectJ Framework的AOP。

在使用AspectJ框架时,我们需要添加AspectJ weaver依赖,例如:

<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjweaver</artifactId>
    <version>1.9.4</version>
</dependency>

动态代理机制

AOP的原理是通过动态代理机制来实现的,Spring Boot通过JDK动态代理和CGLIB动态代理两种方式来实现AOP。

1.JDK动态代理

JDK动态代理是通过代理对象实现目标对象的增强行为,我们需要为目标对象定义一个代理类,在代理类中实现目标对象的接口并添加切面逻辑,Spring Boot通过Proxy类实现JDK动态代理。例如:

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 call...");
        Object result = method.invoke(target, args);
        System.out.println("After method call...");
        return result;
    }
}

public interface MyService {
    void doSomething();
}

public class MyServiceImpl implements MyService {
    @Override
    public void doSomething() {
        System.out.println("Doing something...");
    }
}

public static void main(String[] args) {
    MyService target = new MyServiceImpl();
    MyInvocationHandler invocationHandler = new MyInvocationHandler(target);
    MyService proxy = (MyService) Proxy.newProxyInstance(MyService.class.getClassLoader(),
                                                         new Class<?>[]{MyService.class},
                                                         invocationHandler);
    proxy.doSomething();
}

以上代码中,我们定义了一个目标接口MyService和它的实现类MyServiceImpl。通过MyInvocationHandler实现了前置和后置增强逻辑,最后使用JDK动态代理生成代理对象进行方法调用。

2.CGLIB动态代理

CGLIB是一种基于字节码生成的动态代理方式,可以对Class进行动态生成增强子类来解决接口无法代理的问题,Spring Boot通过Enhancer类实现CGLIB动态代理。例如:

public class MyMethodInterceptor implements MethodInterceptor {
    @Override
    public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
        System.out.println("Before method call...");
        Object result = proxy.invokeSuper(obj, args);
        System.out.println("After method call...");
        return result;
    }
}

public class MyServiceImpl {
    public void doSomething() {
        System.out.println("Doing something...");
    }
}

public static void main(String[] args) {
    Enhancer enhancer = new Enhancer();
    enhancer.setSuperclass(MyServiceImpl.class);
    enhancer.setCallback(new MyMethodInterceptor());
    MyServiceImpl proxy = (MyServiceImpl) enhancer.create();
    proxy.doSomething();
}

以上代码中,我们定义了一个目标类MyServiceImpl,并通过MyMethodInterceptor实现了前置和后置增强逻辑,使用CGLIB动态代理生成代理对象进行方法调用。

通过以上两种动态代理方式,Spring Boot可以在运行期动态修改目标对象的行为,实现AOP的目的。当然,对于一些关键业务逻辑,建议不要过于频繁使用AOP,以免增加难以维护的代码复杂性。

控制面板
您好,欢迎到访网站!
  查看权限
网站分类
最新留言