Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/361.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angularjs/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何拥有具有2个接口的Spring动态代理?_Java_Spring_Proxy_Dynamic Proxy - Fatal编程技术网

Java 如何拥有具有2个接口的Spring动态代理?

Java 如何拥有具有2个接口的Spring动态代理?,java,spring,proxy,dynamic-proxy,Java,Spring,Proxy,Dynamic Proxy,我有一个对象被Spring注入到我的类中(如果你介意的话) 它实现了5个接口,我关心其中两个(ItemReader、ItemStream)。如果我将我的类编码为一个或另一个,spring动态代理将被正确注入,并且我可以调用它的方法 private ItemReader blah; public void setItemReader( blah ) { this.blah = blah }; 很酷,这是意料之中的事。如果我想基于ItemStream接口执行某些操作,我还可以将其强制转换为Item

我有一个对象被Spring注入到我的类中(如果你介意的话)

它实现了5个接口,我关心其中两个(ItemReader、ItemStream)。如果我将我的类编码为一个或另一个,spring动态代理将被正确注入,并且我可以调用它的方法

private ItemReader blah;
public void setItemReader( blah ) { this.blah = blah };
很酷,这是意料之中的事。如果我想基于ItemStream接口执行某些操作,我还可以将其强制转换为ItemStream:

((ItemStream))blah.close();
很酷,这让我可以访问这两个类的方法。然而,我不是一个铸造迷,并且知道哪里有更好的春天魔术的方式来做它。我想到的方法是制作一个结合了以下两者的界面:

public interface IStreamingItemReader<T> extends ItemReader<T>, ItemStream {
}
公共接口IStreamingItemReader扩展ItemReader,ItemStream{
}
这让我的代码可以同时使用。。。但可以预见,代理注入失败了

无法转换的属性值 类型[$Proxy0] org.springframework.beans.factory.InitializingBean,org.springframework.batch.item.ItemReader,org.springframework.batch.ItemStream,org.springframework.aop.scope.ScopedObject,org.springframework.AopInfrastructureBean,org.springframework.aop.SpringProxy,org.springframework.aop.framework.com.Advised] 到所需类型 [blah.IStreamingItemReader]用于 属性“itemReader”;嵌套 例外是 java.lang.IllegalArgumentException: 无法转换类型为[$Proxy0]的值 实施 org.springframework.beans.factory.InitializingBean,org.springframework.batch.item.ItemReader,org.springframework.batch.ItemStream,org.springframework.aop.scope.ScopedObject,org.springframework.AopInfrastructureBean,org.springframework.aop.SpringProxy,org.springframework.aop.framework.com.Advised] 到所需类型 [blah.IStreamingItemReader]用于 属性“itemReader”:不匹配 找到编辑器或转换策略

吸引我眼球的部分是 未找到匹配的编辑器或转换策略

当Spring看到一个JdbcCursorItemReader时,有没有一种方法可以教它生成一个IStreamingItemReader的代理


我意识到我可以用CGLib和基于类的代理来解决这个问题。。。但如果我能将其作为一个动态接口代理,我会更高兴…

简单的方法:如果可能,让您的实现类实现您的联合接口,而不是两个单独的接口

不太清晰,但不引入附加类(需要泛型):

公共接口A{}
公共接口B{}
公共类C实现A,B{}
D类公共服务{
私人A;
私人B,;
公共无效设置对象(TO){
这个a=o;
这个b=o;
}
公共静态void main(字符串[]args){
D=新的D();
d、 setObject(新的C());
}
}
选项1

private ItemReader blah;
private ItemStream blubb;
public void setItemReader( blah ) { this.blah = blah };
public void setItemStream( blubb ) { this.blubb = blubb };
选择2

class ItemAccessor {
 private ItemReader reader;
 private ItemStream stream;
 // Setter & co ...
}
然后:


还有一个泛型选项(主要作为理论练习)不需要重复字段,但需要holder对象:

class ReaderStreamHolder<T extends ItemReader & ItemStream> {
    private final T target;
    public ReaderStreamHolder(T target) {
        this.target = target;
    }
    public T get() {
        return target;
    }
}
private ItemAccessor accessor;

accessor.getReader().read();
accessor.getStream().stream();
class ReaderStreamHolder<T extends ItemReader & ItemStream> {
    private final T target;
    public ReaderStreamHolder(T target) {
        this.target = target;
    }
    public T get() {
        return target;
    }
}
private ReaderStreamHolder<?> blah; 
public <T extends ItemReader & ItemStream> void setItemReader(T target) { 
    this.blah = new ReaderStreamHolder<T>(target)
};
blah.get().close();