애플리케이션이 처음 시작될 때 일부 메소드를 실행하는 Spring 3 기능이 있습니까? @Scheduled
주석 으로 메소드를 설정하는 트릭을 수행 할 수 있으며 시작 직후 실행되지만 주기적으로 실행됩니다.
답변
“응용 프로그램 시작”이 “응용 프로그램 컨텍스트 시작”을 의미하는 경우 그렇습니다.이 작업을 수행 하는 가장 쉬운 방법 은 여러 가지 가 @PostConstruct
있습니다. 다른 옵션을 보려면 링크를 살펴보십시오. 요약하면 다음과 같습니다.
- 주석이 달린 방법
@PostConstruct
afterPropertiesSet()
InitializingBean
콜백 인터페이스에 의해 정의 된- 사용자 정의 구성된 init () 메소드
기술적으로 이들은 컨텍스트 라이프 사이클이 아닌 Bean 라이프 사이클에 연결되지만 99 %의 경우 두 가지가 동일합니다.
컨텍스트 시작 / 종료에 구체적으로 연결해야하는 경우 대신 인터페이스 를 구현할Lifecycle
수 있지만 불필요 할 수 있습니다 .
답변
이것은로 쉽게 수행 할 수 있습니다 ApplicationListener
. Spring의 청취를 위해이 작업을 수행했습니다 ContextRefreshedEvent
.
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.stereotype.Component;
@Component
public class StartupHousekeeper implements ApplicationListener<ContextRefreshedEvent> {
@Override
public void onApplicationEvent(final ContextRefreshedEvent event) {
// do whatever you need here
}
}
애플리케이션 리스너는 Spring에서 동기식으로 실행됩니다. 코드가 한 번만 실행되도록하려면 구성 요소의 상태를 유지하십시오.
최신 정보
Spring 4.2 이상부터는 @EventListener
주석을 사용 하여 ContextRefreshedEvent
( 이 점을 지적한 @bphilipnyc 덕분에) 관찰 할 수 있습니다 .
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.stereotype.Component;
@Component
public class StartupHousekeeper {
@EventListener(ContextRefreshedEvent.class)
public void contextRefreshedEvent() {
// do whatever you need here
}
}
답변
Spring 4.2 이상에서는 이제 간단하게 할 수 있습니다.
@Component
class StartupHousekeeper {
@EventListener(ContextRefreshedEvent.class)
public void contextRefreshedEvent() {
//do whatever
}
}
답변
스프링 부트를 사용하는 경우 이것이 가장 좋은 대답입니다.
나는 느낌 @PostConstruct
등 다양한 수명주기 감탄사가 라운드에 대한 방법입니다합니다. 이로 인해 런타임 문제가 직접 발생하거나 예기치 않은 Bean / 컨텍스트 라이프 사이클 이벤트로 인해 눈에 띄지 않는 결함이 발생할 수 있습니다. 왜 일반 Java를 사용하여 Bean을 직접 호출하지 않습니까? 당신은 여전히 빈을 ‘spring way'(예 : 스프링 AoP 프록시를 통해) 호출합니다 그리고 무엇보다도, 그것은 평범한 자바이며, 그보다 더 간단해질 수는 없습니다. 컨텍스트 리스너 나 홀수 스케줄러가 필요하지 않습니다.
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
ConfigurableApplicationContext app = SpringApplication.run(DemoApplication.class, args);
MyBean myBean = (MyBean)app.getBean("myBean");
myBean.invokeMyEntryPoint();
}
}
답변
@PostConstruct 주석을 참조하려고 할 때 경고가 표시되는 Java 1.8 사용자의 경우, fixedRate 또는 fixedDelay를 사용하여 @Scheduled 작업이 이미있는 경우 수행 할 수있는 @Scheduled 주석을 피기 백하는 대신 종료되었습니다.
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
@EnableScheduling
@Component
public class ScheduledTasks {
private static final Logger LOGGER = LoggerFactory.getLogger(ScheduledTasks.class);
private static boolean needToRunStartupMethod = true;
@Scheduled(fixedRate = 3600000)
public void keepAlive() {
//log "alive" every hour for sanity checks
LOGGER.debug("alive");
if (needToRunStartupMethod) {
runOnceOnlyOnStartup();
needToRunStartupMethod = false;
}
}
public void runOnceOnlyOnStartup() {
LOGGER.debug("running startup job");
}
}
답변
우리가 한 일은 org.springframework.web.context.ContextLoaderListener
컨텍스트가 시작될 때 무언가를 인쇄하도록 확장 되었습니다.
public class ContextLoaderListener extends org.springframework.web.context.ContextLoaderListener
{
private static final Logger logger = LoggerFactory.getLogger( ContextLoaderListener.class );
public ContextLoaderListener()
{
logger.info( "Starting application..." );
}
}
다음에서 서브 클래스를 구성하십시오 web.xml
.
<listener>
<listener-class>
com.mycomp.myapp.web.context.ContextLoaderListener
</listener-class>
</listener>
답변
SpringBoot를 사용하면 시작시 @EventListener
주석을 통해 메소드를 실행할 수 있습니다
@Component
public class LoadDataOnStartUp
{
@EventListener(ApplicationReadyEvent.class)
public void loadData()
{
// do something
}
}