Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/303.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 如何在多个模块中使用公共库中的单例,而不使它们发生冲突?_Java_Jar_Intellij Idea_Singleton - Fatal编程技术网

Java 如何在多个模块中使用公共库中的单例,而不使它们发生冲突?

Java 如何在多个模块中使用公共库中的单例,而不使它们发生冲突?,java,jar,intellij-idea,singleton,Java,Jar,Intellij Idea,Singleton,我有一个singleton对象,它在公共库中实现一些基本功能。这比这要复杂得多,但是为了记录问题,下面是单例实现,除了一个内部属性/对象之外,其他所有属性/对象都被删除: package mystuff.lib.common public class CommonSingleton { public final static CommonSingleton INSTANCE = new CommonSingleton(); private Cache<String,

我有一个singleton对象,它在公共库中实现一些基本功能。这比这要复杂得多,但是为了记录问题,下面是单例实现,除了一个内部属性/对象之外,其他所有属性/对象都被删除:

package mystuff.lib.common

public class CommonSingleton {


    public final static CommonSingleton INSTANCE = new CommonSingleton();

    private Cache<String, Object> cache = null;

    private CommonSingleton() {
        // Exists only to defeat instantiation.
        Initialize();
    }

    private void Initialize() {
        cache = null;
    }

    public Cache<String, Object> getCache() {
        if (cache == null) {
            cache = new Cache<String, Object>();
        }
        return cache;
    }

    public void Reload() {
        Initialize();
    }

}
项目/模块#2:TestPluginTwo.JAR 然而,我发现,当我在两个模块中使用这个对象时(请注意,是单独的JAR文件),它们都在访问同一个单例。虽然这个带有缓存对象的特定示例可能并不表明存在任何问题,但我需要将这些对象视为单独的对象,原因有很多。有许多内部/私有成员变量需要包含不同的值,这取决于使用此单例的项目/模块/插件

我很困惑。当我在.NET中(例如)在单独的DLL中执行此操作时,每个DLL都维护它自己的公共对象的内部实例

如果不共享Singleton对象的实例,如何将此公共Singleton功能包含在公共库中的单独项目中


谢谢

/*这是一个多么纯粹的例子*/

我担心,只要同一个类试图由同一个类加载器加载,该类将只加载一次。无论涉及哪些jar:jar与DLL不同,只是文件系统的签名扩展

我能想象到的最简单的(关于所需的代码更改)是在每个插件中对您的单例子类化,以便使用单独的状态实例化一个单独的类


否则,您可以显式初始化实例或使用依赖项注入为您提供实例。

是。我同意,如果使用不当,单例可能是有害的,但是,当我需要确保只有一个对象实例(如日志记录或缓存机制)存在时,真的没有更好的方法。我最初没有将singleton子类化的原因是singleton没有默认构造函数,因此,我不能在子类中添加我自己的私有构造函数来初始化对象。解决方法是使类抽象并声明一个所有子类都必须实现的抽象方法来初始化自己,然后从抽象基类的私有构造函数调用该方法。但是,这也不起作用,因为公共静态成员变量实例不能在抽象类中初始化。我唯一的选择是手动为singleton创建子类,然后手动重写Initialize()方法,并确保调用super.Initialize()。这是混乱的、手动的,如果其他人决定在我们的另一个项目中实现相同的解决方案,则不会强制执行或自动处理。我不能对没有默认构造函数的类进行子类化。当然,我希望Java有一个类似于DLL的结构,所以我不必将所有这些代码复制到我使用它的每个项目中。呃……有没有其他方法可以在Java中创建一个公共函数库,从而在使用之间提供隔离?这看起来很可笑,我不能创建公共功能并从多个插件中重用它。几乎所有常用函数都会记录错误和/或向控制台发送需要引用插件名称的信息,以便操作员知道消息来自何处。我不想在公共库中的每个方法调用或对象创建中都传递一个插件实例。只是想知道,ThreadLocal在这里可以工作吗?A
ThreadLocal
?@vikingsteve我以前从未使用过ThreadLocal。我检查了一下,我认为这对我的情况并不适用。此外,我相信我们的插件运行的主机应用程序无论如何都是单线程的。当我只有一个插件启动时,这个架构工作得非常好。当第一次访问公共功能时,会传入对父插件对象的引用,以便公共库可以正常运行。我遇到的问题是,当涉及第二个模块(JAR)时,实际的公共对象是共享的,而不仅仅是实现。所以第二个插件传递了一个对自身的引用,覆盖了第一个插件的初始化。听起来你只需要咬紧牙关,使用两个不同的单例。是的。不过,这要复杂得多。公共库中定义的所有对象都使用公共单例及其所有对象。当插件启动时,我将插件的一个实例传递到公共单例中,然后从任何公共库函数引用该实例。现在我已经发现每个插件之间的公共单例实例之间没有隔离,我必须将插件对象的实例传递到几乎每个公共库函数和/或对象实例化中。你能说呕吐吗!?!
package mystuff.plugins.TestPluginOne;

import mystuff.lib.common.CommonSingleton;
import mystuff.lib.common.Objects.Cache;

public class TestClassOne {

    public TestClassOne() {
    }

    public Boolean SaveItemInCache(String key, String content) {
        return CommonSingleton.INSTANCE.getCache().add(key, content, 30);
    }

    public void Reload() {
        CommonSingleton.INSTANCE.Reload();
    }

}
package mystuff.plugins.TestPluginTwo;

import mystuff.lib.common.CommonSingleton;
import mystuff.lib.common.Objects.Cache;

public class TestClassTwo {

    public TestClassTwo() {
    }

    public String GetItemFromCache(String key) {
        return CommonSingleton.INSTANCE.getCache().get(key);
    }

    public void Reload() {
        CommonSingleton.INSTANCE.Reload();
    }

}