【问题标题】:Java lazy instantation using inversion of control container使用控制容器反转的 Java 延迟实例化
【发布时间】:2013-12-27 10:30:07
【问题描述】:

我有这个容器:

public class DIContainer {
    protected static DIContainer instance;
    protected Hashtable<Class<?>, Class<?>> classMap;

    protected DIContainer(){
        this.classMap = new Hashtable<Class<?>, Class<?>>();
    }

    public static DIContainer getInstance(){
        if (DIContainer.instance == null)
            DIContainer.instance = new DIContainer();
        return DIContainer.instance;
    }

    public void regClass(Class<?> interf, Class<?> classToReg){
        this.classMap.put(interf, classToReg);
    }

    public Object create(Class<?> interf, boolean lazy) throws Exception{
        if(!this.classMap.containsKey(interf))
            throw new Exception("No such class registered with "+interf.getName()+" interface");
        else if(lazy == false)
            return this.classMap.get(interf).newInstance();
        else
            return this.classMap.get(interf);

    }
}

如果选择了延迟创建选项,我需要延迟创建一个对象(因此它会创建一些实现相同接口的子对象)。因此,当为该子对象调用第一个方法时,它将实例化“真实”对象。我怎么能这样做,因为我不知道将使用的确切方法?如何检查是否为该对象调用了任何方法?

现在我只是将其作为惰性创建来尝试,如您所见: return this.classMap.get(interf);

但它给了我一个错误:java.lang.ClassCastException 我是否需要其他方法来检查是否对该子对象进行了任何调用,因为在创建完成后,我将退出“创建”方法,何时调用方法我需要以某种方式检查它?

这是我的测试接口及其实现类:

public interface Interface1 {
    public String getName();
    public void setName(String name);
}

public class Class1 implements Interface1{
    String name;
    Class1(){}

    @Override
    public String getName() {
        return name;
    }

    @Override
    public void setName(String name) {
        this.name = name;
    }


}

这就是我测试它的方式:

public class Main {

    public static void main(String[] args) throws Exception{
        DIContainer dic = DIContainer.getInstance();
        dic.regClass(Interface1.class, Class1.class);
        Interface1 t1 = (Interface1) dic.create(Interface1.class, true);

附:如果我将惰性创建设置为 false,那么它可以工作。

【问题讨论】:

    标签: java dependency-injection lazy-loading containers ioc-container


    【解决方案1】:

    在您的情况下,return this.classMap.get(interf); 行返回一个 Class 对象,您之前使用 this.classMap.put(interf, classToReg) 行将其放入地图中。 Class 对象绝对不能强制转换为 Interface1 接口,因为它没有实现它,这会导致 ClassCastException

    您真正需要的是返回一种实现Interface1 接口并包装延迟实例化的类的包装器。当调用任何接口的方法时,包装器会实例化实际对象并委托调用。

    如果您想延迟初始化任意类,最直接的选择是使用 Java 的 dynamic proxy

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-08-20
      • 1970-01-01
      • 2012-09-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多