gpt4 book ai didi

java - 在运行时在创建的 spring bean 中使用 @Scheduled 注释

转载 作者:塔克拉玛干 更新时间:2023-11-02 20:02:34 25 4
gpt4 key购买 nike

我的用例如下:

我目前正在开发一个应用程序,其中有一个 EventModule 负责触发各种事件。其中一个事件是 TimeEvent。这些时间事件应该每秒触发一次。当我的应用程序启动并运行时,还应该可以添加对新事件的支持。对于后一个要求,我正在使用 OSGI。

为了自己生成时间事件,我发现 spring 已经为我提供了这样的功能,即通过在将定期调用的方法上放置 @Scheduled 注释(在我的例子中是每秒) .

因此我有了这段代码:

/**
* Generator class that periodically generates {@link TimeEvent}s.
*/
@Component
@EnableScheduling
public class TimeEventGenerator {

@Scheduled( cron = "*/1 * * * * ?" )
public void testSchedule() {
// fire a time event
}

}

这工作正常并且每秒都会触发事件。但是,这需要在启动时实例化 TimeEventGenerator 类(因为它使用 @Component 注释)。在我的用例中,即 OSGI 部分,我应该能够在我的 BundleActivatorstart(BundleContext) 方法中创建此类的实例在对 TimeEvents 的支持中,因此具有 @Component 注释不是一个选项。

这是我遇到麻烦的部分。我了解到我可以使用 BeanFactoryPostProcessor 在 spring 应用程序上下文中自己注入(inject) bean,这正是我所做的,这导致了以下代码:

/**
* Class that allows to add spring beans to a running application context.
*/
@Component
public class RuntimeBeanFactory implements ApplicationContextAware,
BeanFactoryPostProcessor {

private ApplicationContext applicationContext;
private ConfigurableListableBeanFactory beanFactory;

@Override
@Autowired
public void setApplicationContext( ApplicationContext aApplicationContext ) throws BeansException {
applicationContext = aApplicationContext;
}

@Override
@Autowired
public void postProcessBeanFactory( ConfigurableListableBeanFactory aBeanFactory ) throws BeansException {
beanFactory = aBeanFactory;
}

public <T> T createBean( Class<T> aBeanClass, String aBeanName ) throws IOException {
BeanDefinitionRegistry registry = ( ( BeanDefinitionRegistry ) beanFactory );

GenericBeanDefinition beanDefinition = new GenericBeanDefinition();
beanDefinition.setBeanClass( aBeanClass );
beanDefinition.setLazyInit( false );
beanDefinition.setAbstract( false );
beanDefinition.setAutowireCandidate( true );

if ( !registry.isBeanNameInUse( aBeanName ) ) {
registry.registerBeanDefinition( aBeanName, beanDefinition );
}

return applicationContext.getBean( aBeanClass );
}

}

这里的问题是,每当我使用 createBean 方法创建一个 TimeEventGenerator(参见第一个代码片段)时,testSchedule() 方法永远不会被调用,而我预计会是这样,因为该 bean 由 spring 管理。

编辑:我忘了补充一点,我也尝试过使用 GenericBeanDefinition 的两个子类(即 ScannedGenericBeanDefinition 和 AnnotatedGenericBeanDefinition)使用上述代码,但均未成功。

最佳答案

查看 Spring 文档,我认为您应该尝试使用 AnnotatedGenericBeanDefinition 而不是 GenericBeanDefinition。查看文档 here .

编辑我正在查看 ScheduledAnnotationBeanPostProcessor 的代码,我的注释正在处理中。我遇到的问题是,即使后处理器识别了预定任务,它也只与任务执行器一起安排任务一次。当我注册我预定的类(class)时,这已经发生了,它没有被调用。将刷新事件传递给后处理器会强制其进行调度,但它也会重新调度所有其他任务。查看代码(至少在 Spring 3.2 中),使用注释无法实现您想做的事情。您可以创建自定义注释处理器并向任务执行器注册任务。

关于java - 在运行时在创建的 spring bean 中使用 @Scheduled 注释,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26808063/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com