2

我有一个由 Spring 注入到我的类中的对象(如果你关心的话,是JdbcCursorItemReader )。

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

private ItemReader blah;
public void setItemReader( blah ) { this.blah = blah };

酷,按预期工作。如果我想基于 ItemStream 接口做一些事情,我也可以将它转换为 ItemStream:

((ItemStream))blah.close();

很酷,这让我可以访问这两个类的方法。但是,我不喜欢选角,并且知道哪里有更好的 Spring Magic 方法来做到这一点。我想到的方法是制作一个结合了两者的接口:

public interface IStreamingItemReader<T> extends ItemReader<T>, ItemStream {
}

这让我的代码可以同时使用这两者……但代理注入可以预见地失败了。

无法转换类型 [$Proxy0 实现 org.springframework.beans.factory.InitializingBean,org.springframework.batch.item.ItemReader,org.springframework.batch.item.ItemStream,org.springframework.aop.scope.ScopedObject 的属性值,org.springframework.aop.framework.AopInfrastructureBean,org.springframework.aop.SpringProxy,org.springframework.aop.framework.Advised] 为属性“itemReader”所需的类型 [blah.IStreamingItemReader];嵌套异常是 java.lang.IllegalArgumentException:无法转换类型的值 [$Proxy0 实现 org.springframework.beans.factory.InitializingBean,org.springframework.batch.item.ItemReader,org.springframework.batch.item.ItemStream,org. springframework.aop.scope.ScopedObject,org.springframework.aop.framework.AopInfrastructureBean,org.springframework.aop.SpringProxy,org.

引起我注意的部分是 找不到匹配的编辑器或转换策略

有没有办法在看到JdbcCursorItemReader时教 Spring来制作 IStreamingItemReader 的代理

我意识到我可以用 CGLib 和基于类的代理来解决这个问题......但如果我能把它作为一个动态接口代理,我会更开心......

4

3 回答 3

3

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

不太清楚的方式,但不引入额外的类(需要泛型):

public interface A { }

public interface B { }

public class C implements A, B { }

public class D {
    private A a;
    private B b;

    public <T extends A & B> void setObject(T o) {
        this.a = o;
        this.b = o;
    }

    public static void main(String[] args) {
        D d = new D();
        d.setObject(new C());
    }
}
于 2010-11-18T20:39:05.127 回答
1

选项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 ...
}

然后:

private ItemAccessor accessor;

accessor.getReader().read();
accessor.getStream().stream();
于 2010-11-18T20:46:36.330 回答
1

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

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(); 
于 2010-11-18T20:50:39.183 回答