在Spring 3.0.2中调用了两次调度方法

时间:2012-04-29 13:47:23

标签: spring spring-mvc scheduled-tasks

我使用的是spring 3.0.2

我的预定方法被调用两次..

我犯了一些错误..?

请帮我弄清楚..

@Component("happySundayGreetTask")
public class HappySundayGreetTask {

    @Autowired
    private JavaMailSender mailSender;
    public void setMailSender(JavaMailSender mailSender) {
        this.mailSender = mailSender;
    }

    @Value("${mail.sender}")
    private String fromAddress;
    public void setFromAddress(String fromAddress) {
        this.fromAddress = fromAddress;
    }

    @Autowired
    private VelocityEngine velocityEngine;
    public void setVelocityEngine(VelocityEngine velocityEngine) {
        this.velocityEngine = velocityEngine;
    }

    @Autowired
    private SpitterDAO spitterDAO;
    public void setSpitterDAO(SpitterDAO spitterDAO) {
        this.spitterDAO = spitterDAO;
    }


    @Scheduled(cron="0 58 18 ? * SUN")
    public void greetSundayToSpitters(){
        try {
            System.out.println("task started..");
            MimeMessage message = mailSender.createMimeMessage();
            MimeMessageHelper mimeHelper = new MimeMessageHelper(message, true);
            List<String> spittersEmail = spitterDAO.getSpittersEmail(true);
            String toAddress[] = spittersEmail.toArray(new String[spittersEmail.size()]);
            String templateLoc = "com/spitter/task/sundayGreetEmailTemplate.vm";
            String emailText = VelocityEngineUtils.mergeTemplateIntoString(velocityEngine, templateLoc, null); 
            mimeHelper.setFrom(fromAddress);
            mimeHelper.setTo(toAddress);
            mimeHelper.setSubject("Sunday Greeting from Spitter");
            mimeHelper.setText(emailText, true);
            mailSender.send(message);
        }
        catch (MessagingException ex) {
            Logger.getLogger(HappySundayGreetTask.class.getName()).log(Level.SEVERE, null, ex);
        }    
    }
}

// spitter-servlet.xml

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

       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-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
          http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
          http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
          http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.0.xsd
          http://www.springframework.org/schema/jms http://www.springframework.org/schema/jms/spring-jms-3.0.xsd
          http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.0.xsd
">

    <!-- Defining a PropertyPlaceholderConfigurer -->
    <context:property-placeholder 
                location="classpath:/com/spitter/dao/db.properties,
                          classpath:/com/spitter/service/alerts/mailserver.properties"/>

    <!-- Declaring security aspects to those beans annotated with @PreAutorize -->
    <security:global-method-security pre-post-annotations="enabled" />

    <!-- Support for annotation driven validation, message conversion -->
    <mvc:annotation-driven/>

    <!-- Automatically registering controllers & service objects as beans -->
    <context:component-scan base-package="com.spitter"/>

    <!-- Autowiring enabled using annotations -->
    <context:annotation-config/>   

    <!-- Using annotation driven transaction facility -->
    <tx:annotation-driven transaction-manager="transactionManager"/>

    <!-- Configuring a mail sender -->
    <bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">

        <!-- Configuring mail server properties -->
        <property name="host" value="${mailserver.host}"/>
        <property name="port" value="${mailserver.port}"/>
        <property name="username" value="${mailserver.username}"/>
        <property name="password" value="${mailserver.password}"/>

        <!-- Other mail properties -->
        <property name="javaMailProperties">
            <props>
                <prop key="mail.transport.protocol">${mail.transport.protocol}</prop>
                <prop key="mail.smtp.auth">${mail.smtp.auth}</prop>
                <prop key="mail.smtp.starttls.enable">${mail.smtp.starttls.enable}</prop>
                <prop key="mail.debug">${mail.debug}</prop>
            </props>
        </property>
    </bean>

    <!-- Velocity email template used for sending email alerts -->
    <bean id="velocityEngine" class="org.springframework.ui.velocity.VelocityEngineFactoryBean">
        <property name="velocityProperties">
            <props>
                <prop key="resource.loader">class</prop>
                <prop key="class.resource.loader.class">org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader</prop>
            </props>
        </property>
    </bean>

    <!-- support for scheduled and asynchronous backgorund jobs -->
    <task:annotation-driven/>

</beans>

// spitter-security.xml文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:security="http://www.springframework.org/schema/security" 
       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/security http://www.springframework.org/schema/security/spring-security-3.0.xsd
">


    <import resource="spitter-servlet.xml"/>


    <security:http auto-config="true" use-expressions="true">
        <security:remember-me key="spitterKey" token-validity-seconds="86400"/>
        <security:form-login login-page="/login" authentication-failure-url="/login?login_error=t"
                             login-processing-url="/static/j_spring_security_check"
                             default-target-url="/home"/>
        <security:logout logout-url="/logout" logout-success-url="/login?logout=success"/>                     
        <security:intercept-url pattern="/login" access="isAnonymous()"/>  
        <security:intercept-url pattern="/spitters" access="isAnonymous()"/>
        <security:intercept-url pattern="/logout" access="isAuhenticated()"/>
        <security:intercept-url pattern="/admin/**" access="hasRole('ROLE_ADMIN')"/>
    </security:http>



    <security:authentication-manager>
        <security:authentication-provider user-service-ref="spitterServiceImpl">
            <security:password-encoder hash="md5"/>
        </security:authentication-provider>
    </security:authentication-manager>

</beans>

// web.xml中

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
            /WEB-INF/spitter-security.xml
        </param-value>
    </context-param>
    <filter>
        <description>Filter used to identify requests for PUT &amp; DELETE requests as the case with RESTFul verbs</description>
        <filter-name>httpMethodFilter</filter-name>
        <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>httpMethodFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    <filter>
        <description>Spring security servlet filter delegates to spring managed security filter(Spring security filter)</description>
        <filter-name>springSecurityFilterChain</filter-name>
        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>springSecurityFilterChain</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <listener>
        <listener-class>com.sun.xml.ws.transport.http.servlet.WSServletContextListener</listener-class>
    </listener>
    <servlet>
        <servlet-name>spitter</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <load-on-startup>2</load-on-startup>
    </servlet>
    <servlet>
        <description>Handles static content</description>
        <servlet-name>staticHandler</servlet-name>
        <servlet-class>com.spitter.servlet.StaticServlet</servlet-class>
        <load-on-startup>5</load-on-startup>
    </servlet>
    <servlet>
        <servlet-name>SpitterServiceEndPoint</servlet-name>
        <servlet-class>com.sun.xml.ws.transport.http.servlet.WSServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>spitter</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>staticHandler</servlet-name>
        <url-pattern>/resources/*</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>SpitterServiceEndPoint</servlet-name>
        <url-pattern>/SpitterServiceEndPoint</url-pattern>
    </servlet-mapping>
    <session-config>
        <session-timeout>
            30
        </session-timeout>
    </session-config>
</web-app>

我使用的是spring 3.0.2

我的预定方法被调用两次..

我犯了一些错误..?

请帮我弄清楚..

2 个答案:

答案 0 :(得分:1)

documentation of spring

中找到
  

确保您没有在运行时初始化同一个@Scheduled注释类的多个实例,除非您确实要为每个此类实例安排回调。与此相关,请确保不要对使用@Scheduled注释并使用容器注册为常规Spring bean的bean类使用@Configurable:否则将获得双初始化,一次通过容器,一次通过@Configurable方面,每个@Scheduled方法的结果被调用两次。

也许这就是原因

答案 1 :(得分:0)

看起来你的cron语法错了 - 我的猜测是你输入的?和*意外。你应该把它改成:

@Scheduled(cron="0 58 18 * SUN")

如果指定6个参数(就像原始语法中那样),cron希望第6个元素成为年份。 SUN是一个“星期几”参数,应该在第5位指定,所以cron会感到困惑。