专业的编程技术博客社区

网站首页 > 博客文章 正文

Spring Boot中如何使用CGLIB实现动态代理?

baijin 2024-09-04 02:02:59 博客文章 7 ℃ 0 评论

在Spring框架中,CGLIB(Code Generation Library)通常用于实现动态代理,便于在运行时生成类的子类可以在不修改原始类代码的情况下增强类的功能。常用的场景如下所示。

  • 动态代理:可以为某个类创建代理对象,这样可以方便在调用方法的时候添加一些额外的操作行为例如日志记录、事务管理、权限检查等操作。
  • 字节码生成:可以在程序运行的时候动态的生成新的类和方法,可以提高系统的性能以及灵活性。
  • AOP(面向切面编程):实现切面功能,在方法调用前后执行额外的逻辑。

在Spring Boot中,CGLIB主要用于AOP代理,下面我们就来看看如何在SpringBoot中手动使用CGLIB功能。

添加依赖

在pom.xml中添加CGLIB的依赖,如下所示。

<dependency>
    <groupId>cglib</groupId>
    <artifactId>cglib</artifactId>
    <version>3.3.0</version>
</dependency>

目标类和代理类

假设我们有一个目标类PersonService,它有一个方法sayHello,如下所示。

public class PersonService {
    public void sayHello() {
        System.out.println("Hello, World!");
    }
}

我们可以使用CGLIB为这个类创建一个代理,在调用sayHello方法之前和之后添加一些日志,如下所示,使用CGLIB创建代理。

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

public class CglibProxyDemo {
    public static void main(String[] args) {
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(PersonService.class);
        enhancer.setCallback(new MethodInterceptor() {
            @Override
            public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
                System.out.println("Before method: " + method.getName());
                Object result = proxy.invokeSuper(obj, args);
                System.out.println("After method: " + method.getName());
                return result;
            }
        });

        PersonService proxy = (PersonService) enhancer.create();
        proxy.sayHello();
    }
}

在Spring Boot中使用CGLIB

Spring AOP已经内置了CGLIB的使用,如果需要在配置中明确指定使用CGLIB代理,可以在配置类中设置,如下所示,提供了一个配置类示例。

import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;

@Configuration
@EnableAspectJAutoProxy(proxyTargetClass = true) // 设置proxyTargetClass = true以使用CGLIB代理
public class AppConfig {
}

定义切面类

import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class LoggingAspect {
    @Before("execution(* com.example.demo.PersonService.sayHello(..))")
    public void logBefore() {
        System.out.println("Before method: sayHello");
    }

    @After("execution(* com.example.demo.PersonService.sayHello(..))")
    public void logAfter() {
        System.out.println("After method: sayHello");
    }
}

总结

启动应用后,确保Spring Boot应用启动类正确配置扫描组件,这个时候应用就会调用PersonService的sayHello方法,并且在其对应的切面中会有日志自动进行输出。

通过CGLIB,你可以动态地为类创建代理,并在方法调用前后添加自定义逻辑。而在Spring Boot中,AOP已经内置了CGLIB的使用,你只需要配置切面即可实现复杂的业务需求。

Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表