2012-03-05 61 views
1

我的Web应用程序是轮询更改数据库并显示在JSP这些变化。数据库由传统系统更改,无法获取有关数据更改的事件。在Webapplikation(JSF +春)使用@Scheduled注释

我的方法是查询数据库,并与应用程序Bean同步数据。如果数据发生了变化,我使用推送机制来更新JSP页面。轮询数据库的线程由Application bean产生。我已经在我的Web应用程序中使用的弹簧

,所以我想用弹簧@Scheduled注释,因为我不希望产生一个线程,并让Spring处理周期性执行。但方法不是定期执行的。

我使用Tomcat和MS SQL Server。

我的应用程序豆看起来像这样

@Named("agentData") 
@Scope("application") 
public class AgentDataBean implements Serializable { 
... 
@Scheduled(fixedRate=5000) 
public void loadData() { 
// do database poll 
} 
... 
} 

我的春天和Web的Xml看起来像这样

<?xml version="1.0" encoding="UTF-8"?> 
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" 
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" 
id="WebApp_ID" version="2.5"> 

<display-name>JavaServerFaces</display-name> 

<listener> 
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> 
</listener> 
<context-param> 
    <param-name>contextConfigLocation</param-name> 
    <param-value>/WEB-INF/spring-application-config.xml</param-value> 
</context-param> 

<listener> 
    <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class> 
</listener> 

<context-param> 
    <param-name>javax.faces.PROJECT_STAGE</param-name> 
    <param-value>Development</param-value> 
</context-param> 
<context-param> 
    <param-name>javax.faces.FACELETS_SKIP_COMMENTS</param-name> 
    <param-value>true</param-value> 
</context-param> 

<context-param> 
    <param-name>primefaces.THEME</param-name> 
    <param-value>#{login.theme}</param-value> 
</context-param> 

<!-- Welcome page --> 
<welcome-file-list> 
    <welcome-file>index.html</welcome-file> 
</welcome-file-list> 

<!-- JSF mapping --> 
<servlet> 
    <servlet-name>Faces Servlet</servlet-name> 
    <servlet-class>javax.faces.webapp.FacesServlet</servlet-class> 
    <load-on-startup>1</load-on-startup> 
</servlet> 

<!-- Map these files with JSF --> 
<servlet-mapping> 
    <servlet-name>Faces Servlet</servlet-name> 
    <url-pattern>/faces/*</url-pattern> 
</servlet-mapping> 
<servlet-mapping> 
    <servlet-name>Faces Servlet</servlet-name> 
    <url-pattern>*.jsf</url-pattern> 
</servlet-mapping> 
<servlet-mapping> 
    <servlet-name>Faces Servlet</servlet-name> 
    <url-pattern>*.faces</url-pattern> 
</servlet-mapping> 
<servlet-mapping> 
    <servlet-name>Faces Servlet</servlet-name> 
    <url-pattern>*.xhtml</url-pattern> 
</servlet-mapping> 

<?xml version="1.0" encoding="UTF-8"?> 
<beans 
xmlns="http://www.springframework.org/schema/beans" 
xmlns:aop="http://www.springframework.org/schema/aop" 
xmlns:context="http://www.springframework.org/schema/context" 
xmlns:p="http://www.springframework.org/schema/p" 
xmlns:task="http://www.springframework.org/schema/task" 
xmlns:tx="http://www.springframework.org/schema/tx" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xsi:schemaLocation=" 
    http://www.springframework.org/schema/beans 
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd 
    http://www.springframework.org/schema/task 
    http://www.springframework.org/schema/task/spring-task-3.0.xsd 
    http://www.springframework.org/schema/tx 
    http://www.springframework.org/schema/tx/spring-tx-3.0.xsd 
    http://www.springframework.org/schema/aop 
    http://www.springframework.org/schema/aop/spring-aop-3.0.xsd 
    http://www.springframework.org/schema/context 
    http://www.springframework.org/schema/context/spring-context-3.0.xsd"> 

<bean 
    class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> 
    <property name="location" value="/WEB-INF/config/database.properties" /> 
</bean> 

<bean class="org.springframework.jdbc.datasource.DriverManagerDataSource" 
    id="dataSource" p:driverClassName="${jdbc.driverClassName}" 
    p:password="${jdbc.password}" p:url="${jdbc.url}" p:username="${jdbc.username}" /> 

<!-- Activates annotaion-based bean configuration --> 
<context:annotation-config /> 

<!-- needed is for @Configurable --> 
<context:component-scan base-package="de.cpls.alo.dashboard" /> 
<tx:annotation-driven /> 
<!-- Activates @Scheduled and @Async annotations fpr scheduling --> 
<task:annotation-driven executor="executorWithPoolSizeRange" scheduler="taskScheduler"/> 

<task:executor id="executorWithPoolSizeRange" 
       pool-size="5-25" 
       queue-capacity="100"/> 

<!-- Defines a ThreadPoolTaskScheduler instance with configurable pool size. 
The id becomes the default thread name prefix. -->    
<task:scheduler id="taskScheduler" pool-size="1"/> 

这个问题是一个解决办法对这个问题 Is there a best practice for showing database changes on a JSP

+0

你是什么意思? – Ralph 2012-03-05 14:32:09

+0

该方法不执行定期执行。 – outofBounds 2012-03-05 14:35:55

+0

如果将@Component注释添加到类中,它会起作用吗? – Ralph 2012-03-05 14:57:45

回答

0

我的解决方案,使用SchedulerComponent

@Named("scheduler") 
@Component 
public class SchedulerComponent { 

private List<IScheduledComponent> components; 

public SchedulerComponent() { 
    this.components = new ArrayList<IScheduledComponent>(); 
} 


public void register(IScheduledComponent component){ 
    this.components.add(component); 
} 


@Scheduled(fixedRate = 5000) 
public void doAllWork() { 
    try { 
     for(IScheduledComponent component : this.components){ 
      component.doWork(); 
     } 

     System.out.println("SchedulerComponent.doAllWork()"); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
} 
} 

一个接口,用于调度执行

public interface IScheduledComponent { 
    public void doWork(); 
} 

一个让数据bean实现接口并注册到SchedulerComponent

@Named("agentData") 
@Scope("application") 
public class AgentDataBean implements Serializable,IScheduledComponent { 
... 
public void doWork() { 
    // do database poll 
} 
... 
} 

ñ我有Spring与Scheduled,我在AgentDataBean中获得了FacesContext,所以我可以执行一个Icefaces Push。 “它不工作”: