编辑:我正在尝试为Web应用程序的所有会话创建共享数据库连接池。另一篇文章说,创建Servlet上下文对象的最佳方式是让init侦听器创建它。然而我不清楚如何让这个对象可供我的servlet使用。您如何创建和以后访问应用程序级资源?
回答
一种解决方案是使用专用支架类:
public class SomeClass {
private static class ResourceHolder {
private static final Resource INSTANCE = new Resource();
}
public static Resource getInstance() {
return ResourceHolder.INSTANCE;
}
}
时SomeClass.getInstance()
被称为第一次实例将被初始化。
这被称为[辛格尔顿持有人(http://en.wikipedia.org/wiki/Singleton_pattern#Initialization_On_Demand_Holder_Idiom)图案。它很干净且线程安全,但确实使代码难以测试和模块化。因此应谨慎使用。 – dimo414
是否可以延迟初始化这种模式,就像我说我无法访问在加载时创建此对象所需的参数。 – user3056052
@ user3056052有没有理由你需要它静态最终? – assylias
你可以做到这一点的另一种方法是使用静态初始化:
public class SomeClass {
private static final Object[] CONTENT;
static {
CONTENT = new Object[SomeOtherClass.getContentSize()]; // To show you can access runtime variables
}
}
一旦类是使用类装入器装入这将初始化CONTENT
阵列。
喜欢的东西:
public static abstract class Lazy<T> {
private T t = null;
public synchronized T get() {
if (t == null) {
t = create();
}
return t;
}
protected abstract T create();
}
public static final Lazy<List<String>> lazyList = new Lazy<List<String>>(){
@Override
protected List<String> create() {
return new ArrayList<String>();
}
};
我会提醒你前面,你要描述有位代码的气味,我怀疑你会做的更好,以完全避免了这种模式。依赖外部运行时状态的静态资源打破了有关变量范围的各种最佳实践。
你所描述的,但是,将最被无论是Supplier
或Future
实现什么,这取决于所涉及的成功构建你所需要的对象的工作。所不同的是有些迂腐,但你通常会使用一个Future
举行,这将需要很长的时间来计算,而Supplier
通常很快会返回一个参考。 Future
也具有Java的并发实用程序的一些不错的钩子,但它的声音你并不需要。
你会使用一个Supplier
像这样:
public class GlobalState {
public static final Supplier<LazyData> MY_DATA = Suppliers.memoize(
new Supplier<LazyData>() {
public LazyData get() {
// do whatever you need to construct your object, only gets executed once needed
}
});
...
}
Suppliers.memoize()
将缓存第一次调用底层Supplier
的结果在一个线程安全的方式,所以简单地包装Supplier
给您的通话定义防止重复处理。
最简单的懒初始化是使用enum
一个实例。
enum Singleton {
INSTANCE; // lazy initialised
}
增加的问题是你想要的初始化值。为了处理这个问题,你可以嵌套这个类。
enum Utility {;
static MyType val;
static OtherType val2;
enum Holder {
INSTANCE;
Holder() {
// uses val and val2
}
}
public static Holder getInstance(MyType val, OtherType val2) {
Utility.val = val;
Utility.val2 = val2;
return Holder.INSTANCE; // only created the first time.
}
}
注意:这是线程安全的,因为静态块初始化是安全的。
- 1. 访问应用程序资源
- 2. Android应用程序访问库资源
- 3. 如何在应用程序测试期间访问资源
- 4. 如何访问可运行jar内的应用程序资源?
- 5. 如何访问控制台应用程序中的资源?
- 6. 如何访问我的资源中的应用程序映像?
- 7. 如何访问MVVM WPF应用程序中的图像资源?
- 8. 如何访问应用程序资源代码,c#,WP7
- 9. 如何为控制台应用程序创建资源文件?
- 10. 如何为WinForm应用程序创建全局资源文件?
- 11. 应用程序级资源XAML
- 12. XUL访问资源和应用程序结构
- 13. 添加和访问资源文件到Play Framework应用程序
- 14. 如何让应用程序资源可以访问控制台的initialCommands?
- 15. 如何成功创建资源后创建JSON响应?
- 16. 如何创建安装程序并获取资源然后
- 17. 没有资源后降级应用程序版本
- 18. 应用程序升级后未找到资源文件?
- 19. 如何创建后台应用程序?
- 20. 更新后的应用程序资源
- 21. 如何使用root访问权限创建android应用程序?
- 22. 使用LWJGL小应用程序访问资源
- 23. 用于全局访问单例的Silverlight应用程序资源
- 24. 访问WPF用户控件库中的应用程序资源
- 25. 如何管理应用程序资源?
- 26. 如何处理应用程序资源
- 27. Qt如何访问资源
- 28. 从iPhone应用程序访问资产/资源(例如,单词列表)
- 29. 您可以从远程C#应用程序创建SQL Azure BACPAC
- 30. 访问活动程序集资源
你能不能给我们一些代码,这可能有助于解释你的问题? – Keppil
你不能使用空的构造函数吗?然后检查字段以了解它是否已被初始化?最后的意义何在? –
请求StackOverflow上的某个人为您编写初始化代码。 –