文章目录
- 类定义与依赖注入
- 方法解析
- createCglibProxy
- 注意事项
- setApplicationContext 方法
- createCglibProxy 方法
类定义与依赖注入
- @Service: 标识这是一个 Spring 管理的服务类。
- ApplicationContextAware: 实现该接口允许你在类中获取 ApplicationContext 对象,从而可以访问 Spring 容器中的所有 Bean。
- @Autowired: 注入了 AutowireCapableBeanFactory,用于自动装配新创建的代理对象。
方法解析
- invokeSendMessage
- 此方法接收一个类名(对应于某个实现了 DeviceMessageInterface 的 Bean)和一个 SendMessage 对象作为参数。它首先通过 applicationContext.getBean() 获取目标 Bean 的实例,然后创建该实例的 CGLIB 代理,并调用代理的 sendMessage 方法。
- invokeAllSendMessages
- 遍历所有实现了 DeviceMessageInterface 接口的 Bean,并对每个 Bean 创建其 CGLIB 代理对象,随后调用代理的 sendMessage 方法。这使得你可以一次性对所有相关处理器发送消息。
- invokeReceiveMessage
- 类似于 invokeAllSendMessages,但它是为处理接收到的消息而设计的。它会尝试调用每个处理器的 receiveMessage 方法,并返回第一个非空的结果(如果有的话)。如果所有处理器都未能成功处理消息,则返回一个包含错误信息的 JSON 对象。
createCglibProxy
这是一个泛型方法,负责创建给定类的 CGLIB 代理。代理对象在调用任何方法时都会先打印出方法名称,执行完方法后再打印一次。此外,它还会使用 autowireCapableBeanFactory.autowireBean(proxyInstance) 来确保代理对象能够被正确地注入依赖。
注意事项
线程池未使用:虽然代码中注释掉了 ThreadPoolTaskExecutor taskExecutor,但如果你希望异步执行这些操作,可以考虑取消注释并利用线程池来并发处理任务。
异常处理:目前 invokeReceiveMessage 和 invokeAllSendMessages 中的异常只是简单地打印堆栈跟踪。根据你的需求,可能需要更复杂的错误处理逻辑。
CountDownLatch 未使用:你声明了 CountDownLatch countDownLatch 但没有实际使用它。如果你打算用于同步操作,请确保正确初始化并在适当的地方使用它。
JSON 异常处理:在构造返回的 JSON 对象时捕获了 JSONException,但实际上在这个上下文中不太可能发生此类异常,因为 put 方法不会抛出受检异常。
setApplicationContext 方法
setApplicationContext 方法实现了 ApplicationContextAware 接口中的方法,用于设置当前的 ApplicationContext。这个方法在 Spring 容器初始化时自动调用,允许你的类获取对整个应用上下文的访问权限。这对于需要直接与 Spring 容器交互或获取其他 Bean 的组件非常有用。
createCglibProxy 方法
createCglibProxy 方法使用了 CGLIB 库来创建一个给定类的代理对象,并且在方法调用前后打印日志信息。此外,它还使用了 Spring 的 AutowireCapableBeanFactory 来自动装配新创建的代理对象,确保它可以访问其他 Spring 管理的 Bean。
public <T> T createCglibProxy(Class<T> targetClass, String beanName) {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(targetClass);
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;
}
});
T proxyInstance = (T) enhancer.create();
autowireCapableBeanFactory.autowireBean(proxyInstance);
return proxyInstance;
}
public <T> T createCglibProxy(Class<T> targetClass, String beanName) {
泛型方法声明:<T>
表示这是一个泛型方法,返回类型为 T。
参数:
- targetClass: 目标类的 Class 对象,用于指定要代理的类。
- beanName: 字符串类型的参数,代表目标 Bean 的名称(虽然在这个方法中没有直接使用)。
Enhancer enhancer = new Enhancer();
- 创建 CGLIB 的 Enhancer 实例:Enhancer 是 CGLIB 中用来生成子类或代理类的核心类。
enhancer.setSuperclass(targetClass);
- 设置父类:告诉 Enhancer 使用 targetClass 作为代理类的父类。这意味着代理类将继承 targetClass 的所有非私有方法。
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;
}
});
- 设置回调接口:MethodInterceptor 是 CGLIB 提供的一个接口,允许你在方法调用时插入自定义逻辑。这里通过匿名内部类实现了该接口。
intercept 方法:- obj: 被代理的对象实例。
- method: 当前被拦截的方法。
- args: 方法参数列表。
- proxy: MethodProxy 对象,提供了对原始方法的访问。
- 日志记录:在调用实际方法之前和之后分别打印一条消息。
- 调用父类方法:proxy.invokeSuper(obj, args) 调用了原始类的方法实现。
- 返回结果:将原始方法的结果返回给调用者。
T proxyInstance = (T) enhancer.create();
- 创建代理实例:enhancer.create() 方法根据配置创建并返回一个新的代理实例。这里强制转换为 T 类型,确保返回值与输入参数 targetClass 的类型一致。
autowireCapableBeanFactory.autowireBean(proxyInstance);
- 自动装配依赖:使用 Spring 的 AutowireCapableBeanFactory 对代理实例进行自动装配,这一步骤使得代理对象能够像普通的 Spring Bean 一样获得依赖注入。
return proxyInstance;
- 返回代理对象:最终返回创建好的代理对象,供调用方使用。
import org.json.JSONException;
import org.json.JSONObject;
import org.nuobeifu.dataprocessing.devicemessage.DeviceMessageInterface;
import org.nuobeifu.dataprocessing.devicemessage.entity.ReceiveMessage;
import org.nuobeifu.dataprocessing.devicemessage.entity.SendMessage;
import org.nuobeifu.dataprocessing.entity.vo.SysDeviceMessageExecuteTaskVO;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;
import java.lang.reflect.Method;
import java.util.Map;
import java.util.concurrent.CountDownLatch;
@Service
public class CglibProxyService implements ApplicationContextAware {
private ApplicationContext applicationContext;
@Autowired
private AutowireCapableBeanFactory autowireCapableBeanFactory;
// @Autowired
// private ThreadPoolTaskExecutor taskExecutor;
private CountDownLatch countDownLatch;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
this.autowireCapableBeanFactory = applicationContext.getAutowireCapableBeanFactory();
}
public void invokeSendMessage(String className, SendMessage taskvo) {
// 获取 Bean 实例
DeviceMessageInterface instance = applicationContext.getBean(className, DeviceMessageInterface.class);
// 创建 CGLIB 代理对象
DeviceMessageInterface proxyInstance = createCglibProxy(instance.getClass(), className);
// 调用 sendMessage 方法
proxyInstance.sendMessage(taskvo);
}
public void invokeAllSendMessages(SendMessage taskvo) {
try {
// 获取所有实现 DeviceMessageInterface 的 Bean
Map<String, DeviceMessageInterface> beans = applicationContext.getBeansOfType(DeviceMessageInterface.class);
for (Map.Entry<String, DeviceMessageInterface> entry : beans.entrySet()) {
String beanName = entry.getKey();
DeviceMessageInterface instance = entry.getValue();
// 创建 CGLIB 代理对象
DeviceMessageInterface proxyInstance = createCglibProxy(instance.getClass(), beanName);
// 调用 sendMessage 方法
proxyInstance.sendMessage(taskvo);
}
} catch (Exception e) {
e.printStackTrace();
}
}
public JSONObject invokeReceiveMessage(String className, ReceiveMessage taskvo) {
try {
// 获取所有实现 DeviceMessageInterface 的 Bean
Map<String, DeviceMessageInterface> beans = applicationContext.getBeansOfType(DeviceMessageInterface.class);
for (Map.Entry<String, DeviceMessageInterface> entry : beans.entrySet()) {
String beanName = entry.getKey();
DeviceMessageInterface instance = entry.getValue();
// 创建 CGLIB 代理对象
DeviceMessageInterface proxyInstance = createCglibProxy(instance.getClass(), beanName);
// 调用 sendMessage 方法
JSONObject jsonObject = proxyInstance.receiveMessage(taskvo);
return jsonObject;
}
} catch (Exception e) {
e.printStackTrace();
}
JSONObject jsonObject = new JSONObject();
try{
jsonObject.put("msg", "信息异常");
}catch (JSONException ex){
}
return jsonObject;
}
public <T> T createCglibProxy(Class<T> targetClass, String beanName) {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(targetClass);
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;
}
});
T proxyInstance = (T) enhancer.create();
autowireCapableBeanFactory.autowireBean(proxyInstance);
return proxyInstance;
}
}