Spring @Configuration (non-xml configuration) for

2019-04-26 18:12发布

问题:

Can anyone explain how to do achieve a basic configuration of a task using the @Scheduled annotation without any XML configuration? All the examples I can find use at least a minimal XML configuration. For example:

http://blog.springsource.com/2010/01/05/task-scheduling-simplifications-in-spring-3-0/

This uses a typical:

  <context:component-scan base-package="org/springframework/samples/task/basic/annotation"/> 
  <task:annotation-driven/>

So I'm just using a @Configuration annotation with a bunch of @Bean annotations. They are all instantiated at startup but the one with the @Scheduled does not run. I've used that annotation successfully in the past when using XML configuration, but never with annotations only.

回答1:

The <task:annotation-driven /> annotation ends up declaring a ScheduledAnnotationBeanPostProcessor to read the @Scheduled annotations in your code. See here: http://static.springsource.org/spring/docs/3.1.x/javadoc-api/org/springframework/scheduling/annotation/ScheduledAnnotationBeanPostProcessor.html.

That takes care of the <task:annotation-driven /> line. To get the component scanning you'll need to use AnnotationConfigApplicationContext. Not sure if/how that works with a web container though.



回答2:

Just add @EnableScheduling on you WebMvcConfig class

@Configuration
@EnableWebMvc
@EnableAsync
@EnableScheduling
public class WebMvcConfig extends WebMvcConfigurerAdapter {
   /** Annotations config Stuff ... **/
}


回答3:

In Spring 3.0, you still need that little bit of XML. However, Spring 3.1 (still in beta) introduces additional annotation options to close the gap, removing any need for XML config.

See this blog entry for how it's done. Be very careful before using beta versions of Spring in production code, though - they really are unstable.



回答4:

The answers so far are all helpful for earlier versions of Spring. Here's one that's a bit more tailored to Spring 4:

Assume that you have your main Application class annotated for Component scan like this:

@ComponentScan({"com.my.class"})

And inside of that package, you have a job class that looks like this:

@Configuration
@EnableScheduling
public class MyJobClass {
@Scheduled (cron = "* * * * * *")
public void runJob() throws DocumentException {
    thingsToDoOnSchedule(); 
   }
}

Note that the method that you annotate with @Scheduled must return void and that your cron expression needs to have 6 characters (the example shown here runs every second, which makes testing what your job does easier).

You also need the class level annotations of both @Configuration and @EnableScheduling to make this work. Either by themselves seems to get ignored.

For further reading here is the Spring 4 Enable Scheduling Reference Doc.