2011-10-17 81 views
1

我创建了一个实现ServletContextAttributeListener没有默认构造函数的类和容器抱怨:为什么ServletContextAttributeListener需要默认构造函数?

严重:错误配置..... java.lang.InstantiationException的应用听众:......

所以我创建了一个默认构造函数,除了参数化构造函数,并且一切正常。由于容器需要一个默认构造,我怀疑容器正在创建一个新的类实例,而不是使用已经创建的实例。但插入静态对象计数器成员数据,我发现这种怀疑是真实的。

我的问题是:如果我想更新我的对象的成员数据ServletContextAttributeEvent,我可以以线程安全的方式吗?容器创建一个新对象有什么副作用,以及有哪些解决方法?

+0

不应该属性有非默认构造函数吗?通过setter方法设置属性成员数据是否是最佳实践? –

回答

2

是的,容器instanciates它为你。是的,这个对象对于整个webapp(在JVM中)是唯一的,你必须确保一切都是以线程安全的方式完成的,使用同步。我没有看到任何副作用或解决方法。这就是它应该如此。

您似乎混淆了属性和侦听器。您可以设置和删除任何类型的属性到servlet上下文中。这些属性应该是而不是实现ServletContextAttributeListener

另一方面,您也可以通过web.xml注册侦听器,或通过调用ServletContextaddListener方法之一来注册侦听器。那些听众是而不是 servlet上下文属性。

如果您已将一个ServletContextAttributeListener注册到servlet上下文中,那么每次在servlet上下文中设置或删除任何属性时,都会调用该侦听器的适当方法。已设置或删除的属性的名称和值将位于侦听器接收的事件中。因此,由于容器并行处理多个请求,并且由于每个请求都可以从servlet上下文中设置或删除属性,所以侦听器将被并行调用多次,因此必须是线程安全的。

+0

您可以举一个典型的电子商务应用程序中的应用程序范围内的唯一对象的简单示例吗? 我在想 - 主要目标是在不同组件之间共享_attribute_对象 - 次要目标是对_ServletContextAttributEvent_执行特定操作。 当我已经创建了一个我想与其他组件共享的_attribute_对象时,为什么容器应该创建另一个? –

+0

@Ravisankar:对不起,但我不明白你在问什么。 ServletContextListener是一个对象,当在servlet上下文中添加,删除或替换属性时,容器将调用该对象。每次调用ServletContext.set/removeAttribute()时,都会调用监听器。您可以自己创建它并将它自己添加到servlet上下文中,或者在web.xml中声明它,让容器实例化它并为它添加它。在后一种情况下,你需要一个默认的构造函数。 –

+0

续:但在这两种情况下,实例(由您或容器创建)都将接收所有事件,并且必须以线程安全的方式处理它们。 –

相关问题