Java 动态注册的第三方Bean上类似Spring的后处理器钩子
我在动态注册的第三方bean上使用什么Spring框架钩子 我有一个用于动态扫描类路径并实例化多个第三方bean(gRPCJava 动态注册的第三方Bean上类似Spring的后处理器钩子,java,spring,grpc,spring-bean,grpc-java,Java,Spring,Grpc,Spring Bean,Grpc Java,我在动态注册的第三方bean上使用什么Spring框架钩子 我有一个用于动态扫描类路径并实例化多个第三方bean(gRPCAbstractStub实例)的类路径。我需要在存根上注册,这样增强的AbstractStub就可以进行应用程序处理了。我使用动态创建的*Stub@Bean来消除所有@Bean样板文件,并确保一致的通道配置 约束条件 AbstractStub实现是gRPC生成的类。我的类扩展了AbstractStub 首选的静态工厂方法是:;这是在手动编译@Bean声明时使用的 每个存根都
AbstractStub
实例)的类路径。我需要在存根上注册,这样增强的AbstractStub
就可以进行应用程序处理了。我使用动态创建的*Stub
@Bean
来消除所有@Bean
样板文件,并确保一致的通道配置
约束条件
实现是gRPC生成的类。我的类扩展了AbstractStub
AbstractStub
- 首选的静态工厂方法是:;这是在手动编译
声明时使用的@Bean
- 每个存根都需要一个
通道作为依赖项。有多个
频道
@bean
BeanDefinitionBuilder
+供应商
功能
不允许注入通道
依赖项
void registerBeanDefintion(final Class<S> clazz, final BeanDefinitionRegistry registry) {
Supplier<S> stubSupplier = () -> {
clazz.getConstructor({Channel.class});
return BeanUtils.instantiateClass(constructor, null); // fails here; no Channel
}
BeanDefinitionBuilder builder =
BeanDefinitionBuilder.genericBeanDefinition(clazz, stubSupplier);
builder.addDependsOn(MANAGED_CHANNEL_BEAN_NAME);
builder.addConstructorArgReference(MANAGED_CHANNEL_BEAN_NAME);
registry.registerBeanDefinition(clazz.getName(), builder.getBeanDefinition());
方法3:后处理BeanFactory()
postprocesseBeanFactory
不会对实例化的bean进行操作,因此依赖关系不会预先解析
public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
Iterator<String> iterator = configurableListableBeanFactory.getBeanNamesIterator();
while (iterator.hasNext()) {
String beanName = iterator.next();
if (beanName.endsWith("Stub")) {
AbstractStub stub = (AbstractStub) configurableListableBeanFactory.getBean(beanName); //fails
stub.withInterceptors(newClientInterceptor()); // never gets executed
}
}
}
public void后处理BeanFactory(ConfigurableListableBeanFactoryConfigurableListableBeanFactory)抛出BeanException{
迭代器迭代器=configurableListableBeanFactory.GetBeanName迭代器();
while(iterator.hasNext()){
String beanName=iterator.next();
if(beanName.endsWith(“存根”)){
AbstractStub=(AbstractStub)configurableListableBeanFactory.getBean(beanName);//失败
stub.withInterceptors(newClientInterceptor());//永远不会执行
}
}
}
由于我有一些单独的模块,我把它复杂化了一点:解决方案是使用一个简单的BeanPostProcessor
并调用withInterceptors()
仅用于AbstractStub
实例:
@Override
public Object postProcessAfterInitialization(final Object bean, final String beanName) throws BeansException {
if (bean instanceof AbstractStub) {
AbstractStub stub = (AbstractStub) bean;
log.debug("modify bean '{}': add timeout client interceptor", beanName);
ClientInterceptor timeoutClientInterceptor = this.newTimeoutClientInterceptor(stub);
AbstractStub result = stub.withInterceptors(timeoutClientInterceptor);
return result;
}
return bean;
}
ClientInterceptor newTimeoutClientInterceptor(final AbstractStub stub) {
final Deadline deadline = this.getDeadlineTimeout(stub);
return new ClientInterceptor() {
@Override
public <ReqT, RespT> ClientCall<ReqT, RespT> interceptCall(MethodDescriptor<ReqT, RespT> method, CallOptions callOptions, Channel next) {
final ClientCall<ReqT, RespT> clientCall = next.newCall(method, callOptions.withDeadline(deadline));
return new ClientInterceptors.CheckedForwardingClientCall<ReqT, RespT>(clientCall) {
@Override
protected void checkedStart(Listener<RespT> listener, Metadata metadata) {
log.debug("execute call with deadline {}", deadline);
delegate().start(listener, metadata);
}
};
}
};
}
@覆盖
公共对象后处理AfterInitialization(最终对象bean,最终字符串beanName)抛出BeanException{
if(抽象存根的bean实例){
AbstractStub=(AbstractStub)bean;
debug(“修改bean“{}”:添加超时客户端拦截器”,beanName);
ClientInterceptor timeoutClientInterceptor=此.newTimeoutClientInterceptor(存根);
AbstractStub result=stub.withInterceptors(timeoutClientInterceptor);
返回结果;
}
返回豆;
}
ClientInterceptor newTimeoutClientInterceptor(最终摘要存根){
最终截止日期=此.getDeadlineTimeout(存根);
返回新的ClientInterceptor(){
@凌驾
public ClientCall interceptCall(MethodDescriptor方法、CallOptions CallOptions、Channel next){
final ClientCall ClientCall=next.newCall(方法,callOptions.withDeadline(deadline));
返回新的ClientInterceptors.CheckedForwardingClientCall(clientCall){
@凌驾
受保护的void checkedStart(侦听器侦听器、元数据){
debug(“使用截止日期{}执行调用”,截止日期);
委托().start(侦听器、元数据);
}
};
}
};
}
在if块中,您有BeanDefinition BeanDefinition=并且它没有分配给任何对象?那是一辆汽车吗pasto@zee是的,复制意大利面。更新,thx
@Override
public Object postProcessAfterInitialization(final Object bean, final String beanName) throws BeansException {
if (bean instanceof AbstractStub) {
AbstractStub stub = (AbstractStub) bean;
log.debug("modify bean '{}': add timeout client interceptor", beanName);
ClientInterceptor timeoutClientInterceptor = this.newTimeoutClientInterceptor(stub);
AbstractStub result = stub.withInterceptors(timeoutClientInterceptor);
return result;
}
return bean;
}
ClientInterceptor newTimeoutClientInterceptor(final AbstractStub stub) {
final Deadline deadline = this.getDeadlineTimeout(stub);
return new ClientInterceptor() {
@Override
public <ReqT, RespT> ClientCall<ReqT, RespT> interceptCall(MethodDescriptor<ReqT, RespT> method, CallOptions callOptions, Channel next) {
final ClientCall<ReqT, RespT> clientCall = next.newCall(method, callOptions.withDeadline(deadline));
return new ClientInterceptors.CheckedForwardingClientCall<ReqT, RespT>(clientCall) {
@Override
protected void checkedStart(Listener<RespT> listener, Metadata metadata) {
log.debug("execute call with deadline {}", deadline);
delegate().start(listener, metadata);
}
};
}
};
}