我有一个Singleton/Factory对象,我想编写一个JUnit测试.Factory方法根据类路径上属性文件中的类名决定实例化哪个实现类.如果未找到属性文件,或者属性文件不包含classname键,则该类将实例化默认实现类.
由于工厂保持Singleton的静态实例在实例化后使用,为了能够在Factory方法中测试"故障转移"逻辑,我需要在不同的类加载器中运行每个测试方法.
有没有办法使用JUnit(或其他单元测试包)来做到这一点?
编辑:这是一些正在使用的Factory代码:
private static MyClass myClassImpl = instantiateMyClass();
private static MyClass instantiateMyClass() {
MyClass newMyClass = null;
String className = null;
try {
Properties props = getProperties();
className = props.getProperty(PROPERTY_CLASSNAME_KEY);
if (className == null) {
log.warn("instantiateMyClass: Property [" + PROPERTY_CLASSNAME_KEY
+ "] not found in properties, using default MyClass class [" + DEFAULT_CLASSNAME + "]");
className = DEFAULT_CLASSNAME;
}
Class MyClassClass = Class.forName(className);
Object MyClassObj = MyClassClass.newInstance();
if (MyClassObj instanceof MyClass) {
newMyClass = (MyClass) MyClassObj;
}
} …Run Code Online (Sandbox Code Playgroud) 不使用实例/引用计数器的Singleton对象是否应被视为C++中的内存泄漏?
如果没有计数器在计数为零时要求显式删除单例实例,该对象如何被删除?当应用程序终止时,操作系统是否清理它?如果那个Singleton在堆上分配了内存怎么办?
简而言之,我是否必须调用Singelton的析构函数,还是可以依赖它在应用程序终止时进行清理?
我需要由字符串名称定义的对象(或"单例对象"或"伴随对象"......除了类之外的任何东西).换句话说,如果我有:
package myPackage
object myObject
Run Code Online (Sandbox Code Playgroud)
...那么有这样的事情:
GetSingletonObjectByName("myPackage.myObject") match {
case instance: myPackage.myObject => "instance is what I wanted"
}
Run Code Online (Sandbox Code Playgroud) 在Java EE 6教程说:
要提高性能,您可以选择无状态会话bean,如果它具有以下任何特征:
- bean的状态没有特定客户端的数据.
- 在单个方法调用中,bean为所有客户端执行通用任务.例如,您可以使用无状态会话bean发送确认在线订单的电子邮件.
- bean实现了一个Web服务.
单例会话bean适用于以下情况:
- 状态需要在整个应用程序中共享.
- 单个企业bean需要同时由多个线程访问.
- 应用程序需要企业bean在应用程序启动和关闭时执行任务.
- bean实现了一个Web服务.
但是如果使用什么:
比如说我有一个具有以下界面的登录服务:
public interface LoginService {
boolean authenticate(String user, String password);
}
Run Code Online (Sandbox Code Playgroud)
它应该用@Singleton或@Stateless注释吗?这一个和另一个有什么好处?如果LoginService需要注入一个EntityManager(可以同时使用),该怎么办?
另外:我正在考虑Spring服务bean的Java EE对应物,它们是无状态单例.如果我理解正确,Java EE对应的是@Stateless会话bean,并且@Singleton Beans用于在启动时配置应用程序或在关机时清理或保存应用程序范围的对象.它是否正确?
我不明白得到单例类和静态类有什么区别?任何人都可以用例子详细说明吗?
我理解单例类只能有一个实例,但我不明白为什么这个有用.为什么不只是创建一个包含静态变量和方法的类,并在需要时使用synchronize以确保没有两个线程同时在类中执行方法.我只是不明白为什么有人会经历创造这种类的麻烦.我知道我在这里遗漏了一些东西.
谢谢,
我有一些不清楚的情况:
在最后一次参考持有活动被破坏后,静态单例是否会被垃圾收集?因为Application中没有对单例实例的引用.那么我可以依靠单身人士吗?
通过官方Android文档:
通常不需要子类Application.在大多数情况下,静态单例可以以更模块化的方式提供相同的功能.
通过一些帖子:
在开发应用程序时,我发现有时一些绑定到活动的静态变量恰好是未初始化的,即使它们之前已被初始化!我认为当一个静态变量被初始化时,它在应用程序的整个生命周期中都是如此,但事实并非如此.
换句话说,如果没有任何东西对我的静态单例类进行引用,那么是什么阻止它被垃圾收集和销毁?
我正在尝试用Ruby编写最安全的单例.我对这种语言很陌生,这种语言很有弹性,我没有强烈的感觉,我的单例类只能创建一个实例.作为奖励,我希望该对象只有在真正使用时才会被实例化.
我正在实现一个单例模式.在这里,我在GetInstance中创建一个新的Singleton*实例,当我尝试在析构函数中删除它时,它在无限循环中执行.在这种情况下如何避免内存泄漏?
请参考下面的代码:
#define NULL 0
class Singleton
{
private :
static Singleton* m_pInstance;
Singleton(){};
public :
static Singleton* GetInstance()
{
if(m_pInstance == NULL)
{
m_pInstance = new Singleton();
}
return m_pInstance;
}
~Singleton()
{
//delete m_pInstance; // The system goes in infinate loop here if i uncomment this
m_pInstance = NULL;
}
};
Singleton* Singleton ::m_pInstance = NULL;
int main()
{
Singleton* pInstance = Singleton::GetInstance();
delete pInstance;
}
Run Code Online (Sandbox Code Playgroud) 我最近遇到了Nifty Counter Idiom.我的理解是,这用于在标准库中实现全局变量,如cout,cerr等.由于专家选择了它,我认为它是一种非常强大的技术.
我试图了解使用更像Meyer Singleton的东西的优势.
例如,人们可以在头文件中:
inline Stream& getStream() { static Stream s; return s; }
static Stream& stream = getStream();
Run Code Online (Sandbox Code Playgroud)
优点是您不必担心引用计数,放置新的,或者有两个类,即代码更简单.既然没有这样做,我肯定有一个原因:
编辑:在阅读Yakk的答案时,我被提示编写以下代码,我将其作为快速演示添加到原始问题中.这是一个非常小的例子,展示了如何使用Meyer Singleton +全局引用在main之前进行初始化:http://coliru.stacked-crooked.com/a/a7f0c8f33ba42b7f.