简体   繁体   中英

Scheduled method in Spring Boot

I want to send a post request within a period. I created my method like this;

@Scheduled(cron = "0 0 */6 * *")
@PostMapping
public List<TagsRes> getTags(Date date) {
    return null;
}

@Scheduled(cron = "0 0 5 * * ?")
@PostMapping
public List<TagsRes> getAll() {
    return null;
}

Should i use @Scheduled in my controller? Is there any better way to do it?

Thanks!

To schedule a job in spring boot application to run periodically, spring boot provides @EnableScheduling and @Scheduled annotations. In my opinion, since spring boot provides the annotation and functionality for scheduler using it will make more sense

  1. Add @EnableScheduling annotation to your spring boot application class. @EnableScheduling is a Spring Context module annotation. It internally imports the SchedulingConfiguration via the @Import(SchedulingConfiguration.class) instruction
@SpringBootApplication
@EnableScheduling
public class SpringBootWebApplication {
         
}
  1. Now you can add @Scheduled annotations on methods that you want to schedule. The only condition is that methods should be without arguments.

    ScheduledAnnotationBeanPostProcessor that will be created by the imported SchedulingConfiguration scans all declared beans for the presence of the @Scheduled annotations.

    For every annotated method without arguments, the appropriate executor thread pool will be created. This thread pool will manage the scheduled invocation of the annotated method.

@Scheduled(initialDelay = 1000, fixedRate = 10000)
public void run() {
    logger.info("Current time is :: " + Calendar.getInstance().getTime());
}

Source: https://howtodoinjava.com/spring-boot/enable-scheduling-scheduled-job-example/

Controllers are meant to receive web requests, not to post anything. You can think about them as endpoints exposed by your application and called by external service from time to time.

Now, the Controller abstraction by itself should do any business logic. You may want to validate some parameters received in the request, maybe convert the request parameters to java object with some customization and then call the class (usually mentioned as Service in spring universe) that actually executes your business logic.

Now back to your question. I suspect you should not "POST a request" but should invoke some piece of code "as if someone called the controller's method (endpoint)". But this time not the external "user" will cause the code execution but an internal scheduler.

If so you can slightly refactor your code to achieve the better clarity:

  • Create a service that will execute the code
  • Do not put any scheduling related stuff on controller
  • From controller call the service
  • Create a bean and put a "@Scheduled" method on it. The bean will have the service injected and will call it just like the controller does.

Don't forget to put @EnableScheduling annotation - otherwise the scheduled code won't run.


public class MyService {
   public void doBusinessLogic(){ ... }
}

@RestController
public class MyController {
    @Autowired
    private MyService service;
    public void myPostMethod(...) {
      service.doBusinessLogic(...);
    }
} 

public class MyScheduledInvoker {
    @Autowired
    private MyService service;

    @Scheduled(...cron expression or whatever...) 
    public void invokeScheduled() {
       service.doBusinessLogic(...);
    }
}


@SpringBootApplication
@EnableScheduling
public class MyApp {

     public static void main(String [] args) { .... run the app ...}
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM