cglib示例分享

欣喜 Java经验 发布时间:2025-03-24 10:50:47 阅读数:11496 1
下文笔者讲述CGLIB的示例分享,如下所示

CGLIB简介

CGLIB(Code Generation Library)是一个强大的代码生成库
  用于在运行时动态生成类的子类或实现接口的代理类。
    CGLIB 常用于 AOP(面向切面编程)框架中

CGLIB主要特点
1.动态代理:
   - 生成类的子类,实现方法拦截。
   - 适用于没有实现接口的类。

2.高性能:
   - 相比 JDK 动态代理,CGLIB 通常具有更高的性能,
    特别是在方法调用频繁的场景中。

3.灵活性:
   - 可以生成类的子类或实现接口的代理类。
   - 支持方法拦截和回调

CGLIB示例

 
1.添加CGLIB 依赖
   项目中包含CGLIB依赖
     可在`pom.xml`中添加
	  以下依赖:
 
<dependency>
    <groupId>cglib</groupId>
    <artifactId>cglib</artifactId>
    <version>3.3.0</version>
</dependency>
 
使用Gradle
 可在`build.gradle`中
  添加以下依赖:

```groovy
dependencies {
    implementation 'cglib:cglib:3.3.0'
}
 
2.定义目标类

定义一个简单类
  `HelloService`
  其中包含一个方法 `sayHello`
 
public class HelloService {
    public void sayHello(String name) {
        System.out.println("Hello, " + name + "!");
    }
}
 
3.创建方法拦截器

创建一个方法拦截器 `HelloInterceptor`
用于在方法调用前后添加日志记录
 
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

public class HelloInterceptor implements 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;
    }
}
 
4.使用 CGLIB 生成代理类

创建一个类 `CglibProxyExample`
用于生成 `HelloService`代理类并调用其方法

import net.sf.cglib.proxy.Enhancer;

public class CglibProxyExample {
    public static void main(String[] args) {
        // 创建 Enhancer 实例
        Enhancer enhancer = new Enhancer();

        // 设置目标类
        enhancer.setSuperclass(HelloService.class);

        // 设置方法拦截器
        enhancer.setCallback(new HelloInterceptor());

        // 生成代理类
        HelloService proxy = (HelloService) enhancer.create();

        // 调用代理类的方法
        proxy.sayHello("Alice");
    }
}
 

代码详解

1.定义目标类`HelloService`:

    public class HelloService {
        public void sayHello(String name) {
            System.out.println("Hello, " + name + "!");
        }
    }
    - `HelloService`:一个简单的类,包含一个 `sayHello` 方法。

2.创建方法拦截器`HelloInterceptor`:
    import net.sf.cglib.proxy.MethodInterceptor;
    import net.sf.cglib.proxy.MethodProxy;

    import java.lang.reflect.Method;

    public class HelloInterceptor implements 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;
        }
    }
    - `HelloInterceptor`:实现 `MethodInterceptor` 接口,用于拦截方法调用。
    - `intercept` 方法:在方法调用前后添加日志记录。

3.使用 CGLIB 生成代理类`CglibProxyExample`
    import net.sf.cglib.proxy.Enhancer;

    public class CglibProxyExample {
        public static void main(String[] args) {
            // 创建 Enhancer 实例
            Enhancer enhancer = new Enhancer();

            // 设置目标类
            enhancer.setSuperclass(HelloService.class);

            // 设置方法拦截器
            enhancer.setCallback(new HelloInterceptor());

            // 生成代理类
            HelloService proxy = (HelloService) enhancer.create();

            // 调用代理类的方法
            proxy.sayHello("Alice");
        }
    }
    - Enhancer:CGLIB 的核心类,用于生成代理类。
    - setSuperclass:设置目标类。
    - setCallback:设置方法拦截器。
    - create:生成代理类的实例。
    - 调用方法:通过代理类调用`sayHello`方法,
	    触发拦截器中的逻辑。

代码运行输出以下信息

 
    javac -cp .:cglib-3.3.0.jar HelloService.java HelloInterceptor.java CglibProxyExample.java
    java -cp .:cglib-3.3.0.jar CglibProxyExample
 
 输出示例
 
Before method: sayHello
Hello, Alice!
After method: sayHello

1.定义多个方法目标类 `HelloService`

public class HelloService {
    public void sayHello(String name) {
        System.out.println("Hello, " + name + "!");
    }

    public void sayGoodbye(String name) {
        System.out.println("Goodbye, " + name + "!");
    }
}

2.创建方法拦截器`HelloInterceptor`
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

public class HelloInterceptor implements 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;
    }
}

3.使用CGLIB生成代理类`CglibProxyExample`

import net.sf.cglib.proxy.Enhancer;

public class CglibProxyExample {
    public static void main(String[] args) {
        // 创建 Enhancer 实例
        Enhancer enhancer = new Enhancer();

        // 设置目标类
        enhancer.setSuperclass(HelloService.class);

        // 设置方法拦截器
        enhancer.setCallback(new HelloInterceptor());

        // 生成代理类
        HelloService proxy = (HelloService) enhancer.create();

        // 调用代理类的方法
        proxy.sayHello("Alice");
        proxy.sayGoodbye("Bob");
    }
}

===代码输出以下信息=====

Before method: sayHello
Hello, Alice!
After method: sayHello
Before method: sayGoodbye
Goodbye, Bob!
After method: sayGoodbye
 
===相关说明=====
-Before method: sayHello:
   在调用 `sayHello` 方法之前,拦截器记录了方法调用前的日志。
-Hello, Alice!:
   目标类 `HelloService` 的 `sayHello` 方法被调用。
-After method: sayHello:
   在调用 `sayHello` 方法之后,拦截器记录了方法调用后的日志。
-Before method: sayGoodbye:
   在调用 `sayGoodbye` 方法之前,拦截器记录了方法调用前的日志。
-Goodbye, Bob!:
   目标类 `HelloService` 的 `sayGoodbye` 方法被调用。
-After method: sayGoodbye:
   在调用 `sayGoodbye` 方法之后,拦截器记录了方法调用后的日志。

使用 CGLIB 进行方法拦截

CGLIB还支持更细粒度的方法拦截
  可通过 `CallbackFilter` 来选择性地拦截不同方法。

1.定义目标类`HelloService`
public class HelloService {
    public void sayHello(String name) {
        System.out.println("Hello, " + name + "!");
    }

    public void sayGoodbye(String name) {
        System.out.println("Goodbye, " + name + "!");
    }

    public void greet(String name) {
        System.out.println("Greet, " + name + "!");
    }
}

2.创建多个拦截器
 
创建两个拦截器`HelloInterceptor` 
   和 `GoodbyeInterceptor` 
   
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

public class HelloInterceptor implements MethodInterceptor {
    @Override
    public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
        // 方法调用前的日志记录
        System.out.println("HelloInterceptor: Before method: " + method.getName());

        // 调用目标方法
        Object result = proxy.invokeSuper(obj, args);

        // 方法调用后的日志记录
        System.out.println("HelloInterceptor: After method: " + method.getName());

        return result;
    }
}
 
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

public class GoodbyeInterceptor implements MethodInterceptor {
    @Override
    public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
        // 方法调用前的日志记录
        System.out.println("GoodbyeInterceptor: Before method: " + method.getName());

        // 调用目标方法
        Object result = proxy.invokeSuper(obj, args);

        // 方法调用后的日志记录
        System.out.println("GoodbyeInterceptor: After method: " + method.getName());

        return result;
    }
}
 
3.创建`CallbackFilter`

创建一个`CallbackFilter`
  用于选择性地拦截不同方法
 
import net.sf.cglib.proxy.Callback;
import net.sf.cglib.proxy.CallbackFilter;

import java.lang.reflect.Method;

public class HelloCallbackFilter implements CallbackFilter {
    @Override
    public int accept(Method method) {
        if (method.getName().equals("sayHello")) {
            return 0; // 使用 HelloInterceptor
        } else if (method.getName().equals("sayGoodbye")) {
            return 1; // 使用 GoodbyeInterceptor
        } else {
            return 2; // 不拦截
        }
    }
}
 
4.使用CGLIB生成代理类 `CglibProxyExample`

import net.sf.cglib.proxy.Callback;
import net.sf.cglib.proxy.Enhancer;

public class CglibProxyExample {
    public static void main(String[] args) {
        // 创建 Enhancer 实例
        Enhancer enhancer = new Enhancer();

        // 设置目标类
        enhancer.setSuperclass(HelloService.class);

        // 设置回调数组
        Callback[] callbacks = new Callback[]{
            new HelloInterceptor(),
            new GoodbyeInterceptor(),
            net.sf.cglib.proxy.NoOp.INSTANCE // 不拦截
        };

        // 设置回调过滤器
        enhancer.setCallbackFilter(new HelloCallbackFilter());

        // 设置回调数组
        enhancer.setCallbacks(callbacks);

        // 生成代理类
        HelloService proxy = (HelloService) enhancer.create();

        // 调用代理类的方法
        proxy.sayHello("Alice");
        proxy.sayGoodbye("Bob");
        proxy.greet("Charlie");
    }
}

====输出以下信息===== 

HelloInterceptor: Before method: sayHello
Hello, Alice!
HelloInterceptor: After method: sayHello
GoodbyeInterceptor: Before method: sayGoodbye
Goodbye, Bob!
GoodbyeInterceptor: After method: sayGoodbye
Greet, Charlie!
 
====输出 

-HelloInterceptor:
  - sayHello:
      在调用 `sayHello` 方法前后
	    `HelloInterceptor` 记录日志。
- GoodbyeInterceptor:
  - sayGoodbye:
      在调用`sayGoodbye`方法前后
	    `GoodbyeInterceptor`记录日志
- greet:
  - greet未被拦截
      直接调用目标方法
版权声明

本文仅代表作者观点,不代表本站立场。
本文系作者授权发表,未经许可,不得转载。

本文链接: https://www.Java265.com/JavaJingYan/202503/17427868188395.html

最近发表

热门文章

好文推荐

Java265.com

https://www.java265.com

站长统计|粤ICP备14097017号-3

Powered By Java265.com信息维护小组

使用手机扫描二维码

关注我们看更多资讯

java爱好者