我想在服务器启动时启动线程.我的线程从db中提取数据,并将其放入JMS队列中.所有的bean都在Spring配置文件中定义.在Weblogic上配置了JMS队列和数据库连接工厂(CONNECTION-FACTORY).
我试图将线程启动代码放入ContextLoaderListener的contextInitialized方法或servlet的init方法中.但是启动服务器时出现以下异常:
nested exception is
javax.naming.NoPermissionException:
User anonymous does not have
permission on CONNECTION-FACTORY to
perform lookup operation.
如果我将其放在Servlet的doGet方法中,并在服务器启动后访问该URL,则我的代码可以正常工作.但是我不想手动启动线程.
我认为我收到此错误是因为所有bean没有正确初始化.
将此添加到您的web.xml:
<resource-ref>
<res-ref-name>timer/MyTimer/res-ref-name>
<res-type>commonj.timers.TimerManager</res-type>
<res-auth>Container</res-auth>
<res-sharing-scope>Unshareable</res-sharing-scope>
</resource-ref>
在您的applicationContext.xml中(需要spring-context-support JAR):
<bean id="scheduler" class="org.springframework.scheduling.commonj.TimerManagerTaskScheduler" scope="singleton">
<property name="timerManagerName" value="java:comp/env/timer/MyTimer"/>
</bean>
然后在您的contextInitialized(…)中执行以下操作:
scheduledFuture = scheduler.schedule(new MyJob());
在你的上下文中Destroyed(…)做;
scheduledFuture.cancel(true);
在我的项目中,我找不到有关在应用程序服务器级别配置计时器的任何信息,因此我认为它“有效”.
如果要异步生成作业(通过java.lang.concurrent.Executor接口),则过程类似,但是需要在Weblogic中配置线程池:
在web.xml;
<resource-ref>
<res-ref-name>wm/MyWorkManager</res-ref-name>
<res-type>commonj.work.WorkManager</res-type>
<res-auth>Container</res-auth>
</resource-ref>
在applicationContext.xml中:
<bean id="executor" class="org.springframework.scheduling.commonj.WorkManagerTaskExecutor" scope="singleton">
<property name="workManagerName" value="java:comp/env/wm/MyWorkManager"/>
</bean>
在您的weblogic.xml(或EARs的等效文件)中,如下所示:
<work-manager>
<name>wm/MyWorkManager</name>
<min-threads-constraint>
<name>minThreads</name>
<count>1</count>
</min-threads-constraint>
<max-threads-constraint>
<name>maxThreads</name>
<count>20</count>
</max-threads-constraint>
</work-manager>
在您的代码中:
executor.execute(new MyRunnable());
阅读Weblogic docs on timers and work managers,以了解有关此特定应用服务器的更多与作业计划相关的信息.