내 사용 사례는 다음과 같은 : 나는 현재 모든 종류의 이벤트를 발사 담당하는 EventModule이있는 응용 프로그램을 개발하고 있어요사용 @Scheduled 주석은 런타임에서 스프링 빈을 생성
. 이러한 이벤트 중 하나가 TimeEvent입니다. 이 시간 이벤트는 매 초마다 발생해야합니다. 또한 응용 프로그램이 시작되어 실행 중일 때 새 이벤트에 대한 지원을 추가 할 수 있어야합니다. 후자의 요구 사항에 대해서는 OSGI를 사용하고 있습니다.
시간 이벤트 자체를 생성하기 위해 스프링이 이미 저의 기능을 제공한다는 것을 알았습니다. 즉, 주기적으로 (매초마다) 호출 할 메서드에 @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 부분에서는 TimeEvents
에 대한 지원을 꽂기로 결정할 때마다이 start(BundleContext)
메서드에서 내 BundleActivator
메서드로이 클래스의 인스턴스를 만들 수 있어야합니다. 따라서 @Component
주석을 사용하는 것은 옵션이 아닙니다.
일부 문제가있는 부분입니다. 나는 내가 한 정확히 무엇이다하는 BeanFactoryPostProcessor
를 사용하여 스프링 애플리케이션 컨텍스트에 콩에게 자신을 주입 할 수 있다는 것을 배웠이 다음 코드 결과 :
/**
* 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);
}
}
여기에 문제가 있음을 내가 만들 때마다 TimeEventGenerator
(예를 들어 createBean
메서드를 사용하면 콩이 봄에 의해 관리되기 때문에 testSchedule()
메서드는 호출되지 않습니다.
편집 : 나는 또한 위의 코드를 두 가지 하위 클래스 인 GenericBeanDefinition, 즉 ScannedGenericBeanDefinition과 AnnotatedGenericBeanDefinition으로 성공하지 못했다고 덧붙였다.
오 예, 저도 시도했습니다. 내 질문에 그것을 추가하는 것을 잊었다. 나는 어느 쪽도 일하지 않았다. 원래 질문에 추가하겠습니다. –
귀하의 편집은 실제로 그것을 해결하는 데 도움이되었습니다! .... 공공 T createBean (클래스 aBeanClass, 문자열 aBeanName : 내가 한 것은'RuntimeBeanFactory'가'ScheduledAnnotationBeanPostProcessor'을 확장하고 응용 프로그램 컨텍스트에서 새로 만든 빈을 검색 _after_은'afterSingletonsInstantiated' 메소드를 호출했다) IOException을 던졌습니다. { // 원래 게시물의 이전 코드는 그대로 유지 // .... T bean = applicationContext.getBean (aBeanClass); afterSingletonInstantiated(); return bean; } –