cglib示例分享
下文笔者讲述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未被拦截
直接调用目标方法
版权声明
本文仅代表作者观点,不代表本站立场。
本文系作者授权发表,未经许可,不得转载。


