简体   繁体   English

Spring 带有惰性 bean 的计划任务

[英]Spring scheduled task with a lazy bean

Does anyone know how to create a scheduled task that doesn't initialize the lazy bean with application start, but do this only when this task must be executed?有谁知道如何创建一个不使用应用程序启动初始化惰性 bean 的计划任务,但仅在必须执行此任务时才这样做?

For example:例如:

<?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:task="http://www.springframework.org/schema/task"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task.xsd"
       default-lazy-init="true">

    <!-- Configure the scheduler -->
    <task:scheduler id="myScheduler" pool-size="10"/>

    <!-- Configure parameters -->
    <task:scheduled-tasks scheduler="myScheduler">
        <task:scheduled ref="secondBean" method="run" fixed-delay="5000" initial-delay="5000"/>
    </task:scheduled-tasks>

    <bean name="firstBean" class="com.mkazm.lazy.User"/>
    <bean name="secondBean" class="com.mkazm.lazy.User"/>
</beans>

The simple test class:简单测试class:

@Slf4j
public class User implements Runnable, BeanNameAware {
    private String beanName;

    @Override
    public void run() {
        log.warn("I am running {}", beanName);
    }

    @PostConstruct
    private void post() {
        log.warn("Initialized {}", beanName);
    }

    @Override
    public void setBeanName(String name) {
        this.beanName = name;
    }
}

The output: output:

2021-02-25 21:33:49.527  INFO DESKTOP-M766312 --- [           main] c.m.l.PostProcessorApplication           : No active profile set, falling back to default profiles: default
2021-02-25 21:33:50.251  WARN DESKTOP-M766312 --- [           main] c.m.l.User                               : Initialized secondBean
2021-02-25 21:33:50.287  INFO DESKTOP-M766312 --- [           main] o.s.s.c.ThreadPoolTaskScheduler          : Initializing ExecutorService 'myScheduler'
2021-02-25 21:33:50.399  INFO DESKTOP-M766312 --- [           main] c.m.l.PostProcessorApplication           : Started PostProcessorApplication in 1.48 seconds (JVM running for 3.352)
2021-02-25 21:33:55.397  WARN DESKTOP-M766312 --- [  myScheduler-1] c.m.l.User                               : I am running secondBean
2021-02-25 21:34:00.411  WARN DESKTOP-M766312 --- [  myScheduler-1] c.m.l.User                               : I am running secondBean

The only possible solution that I find is to create a proxy object with lazy @Autowired reference to the actual bean.我找到的唯一可能的解决方案是创建一个代理 object 并带有对实际 bean 的惰性 @Autowired 引用。

Using Java config, declare bean as lazy:使用 Java 配置,将 bean 声明为惰性:

@Bean
@Lazy
User user1() {
  return new User();
}

And mark injection point also as lazy:并将注入点也标记为惰性:

@Component
public class CustomJob {

  private final User user;

  public CustomJob(@Lazy @Qualifier("user1") User user) {
    this.user = user;
  }

  @Scheduled(initialDelay = 5000L, fixedRate = 3 * 1000L)
  void execute() {
    user.run();
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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