类定义与依赖注入
- @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。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| 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; }
|
1
| public <T> T createCglibProxy(Class<T> targetClass, String beanName) {
|
泛型方法声明:<T> 表示这是一个泛型方法,返回类型为 T。
参数:
- targetClass: 目标类的 Class 对象,用于指定要代理的类。
- beanName: 字符串类型的参数,代表目标 Bean 的名称(虽然在这个方法中没有直接使用)。
1
| Enhancer enhancer = new Enhancer();
|
- 创建 CGLIB 的 Enhancer 实例:Enhancer 是 CGLIB 中用来生成子类或代理类的核心类。
1
| enhancer.setSuperclass(targetClass);
|
- 设置父类:告诉 Enhancer 使用 targetClass 作为代理类的父类。这意味着代理类将继承 targetClass 的所有非私有方法。
1 2 3 4 5 6 7 8 9
| 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) 调用了原始类的方法实现。
- 返回结果:将原始方法的结果返回给调用者。
1
| T proxyInstance = (T) enhancer.create();
|
- 创建代理实例:enhancer.create() 方法根据配置创建并返回一个新的代理实例。这里强制转换为 T 类型,确保返回值与输入参数 targetClass 的类型一致。
1
| autowireCapableBeanFactory.autowireBean(proxyInstance);
|
- 自动装配依赖:使用 Spring 的 AutowireCapableBeanFactory 对代理实例进行自动装配,这一步骤使得代理对象能够像普通的 Spring Bean 一样获得依赖注入。
- 返回代理对象:最终返回创建好的代理对象,供调用方使用。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112
| 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;
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) { DeviceMessageInterface instance = applicationContext.getBean(className, DeviceMessageInterface.class); DeviceMessageInterface proxyInstance = createCglibProxy(instance.getClass(), className); proxyInstance.sendMessage(taskvo); }
public void invokeAllSendMessages(SendMessage taskvo) { try { Map<String, DeviceMessageInterface> beans = applicationContext.getBeansOfType(DeviceMessageInterface.class);
for (Map.Entry<String, DeviceMessageInterface> entry : beans.entrySet()) { String beanName = entry.getKey(); DeviceMessageInterface instance = entry.getValue(); DeviceMessageInterface proxyInstance = createCglibProxy(instance.getClass(), beanName); proxyInstance.sendMessage(taskvo); } } catch (Exception e) { e.printStackTrace(); } }
public JSONObject invokeReceiveMessage(String className, ReceiveMessage taskvo) { try { Map<String, DeviceMessageInterface> beans = applicationContext.getBeansOfType(DeviceMessageInterface.class);
for (Map.Entry<String, DeviceMessageInterface> entry : beans.entrySet()) { String beanName = entry.getKey(); DeviceMessageInterface instance = entry.getValue();
DeviceMessageInterface proxyInstance = createCglibProxy(instance.getClass(), beanName);
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; }
}
|