스프링ApplicationEventPublisher는 스프링에서 이벤트 프로그래밍에 필요한 인터페이스를 제공한다.ApplicationContext인터페이스에 이미 상속되어있어서ApplicationContext의 구현체에서도 접근이 가능하다.
@Component
public class AppRunner implements ApplicationRunner {
@Autowired
ApplicationContext applicationContext;
@Override
public void run(ApplicationArguments args) throws Exception {
applicationContext.publishEvent(new MyEvent(this, 1)); // event에 접근 가능
}
}
이벤트 수신 방법? @EventListener를 사용해서 빈의 메소드에 사용
기본적으로는 synchronized 이다.
@Component
public class MyEventHandler {
@EventListener
// 반드시 다음 어노테이션을 써주어야 한다.
public void handle(MyEvent event){
System.out.println("Event 수신 !!!" + event.getData());
}
}
<navigation-link url="/profile">
Your Profile
</navigation-link>
이런식으로 해주면 <slot></slot> 의 부분에
Your Profile이란 글씨가 나오게된다.
3. 컴파일 범위
여기서 중요하게 알아야 할 것은,
컴파일 범위이다 (Compilation Scope)
<navigation-link url="/profile">
Logged in as {{ user.name }}
<!-- user는 부모 컴포넌트에서 있기때문에 잘 표시 될것이닷! --!>
</navigation-link>
<navigation-link url="/profile">
Clicking here will send you to: {{ url }}
<!--
url은 undefined로 나올 겁니다. 이 데이터는 <navigation-link>로
넘어가지만 <navigation-link> 컴포넌트 안에 정의되어 있지는
않으니까요.
-->
</navigation-link>
부모 템플릿 안에 있는 것들은 부모 컴포넌트의 범위에 컴파일되고 자식 템플릿 안에 있는 것들은 자식 컴포넌트의 범위에 컴파일됩니다.
<base-layout>
<template v-slot:header>
<h1>Here might be a page title</h1>
</template>
<p>A paragraph for the main content.</p>
<p>And another one.</p>
<template v-slot:footer>
<p>Here's some contact info</p>
</template>
</base-layout>
다음도 가능 default 이름 넣어주기
<base-layout>
<template v-slot:header>
<h1>Here might be a page title</h1>
</template>
<template v-slot:default>
<p>A paragraph for the main content.</p>
<p>And another one.</p>
</template>
<template v-slot:footer>
<p>Here's some contact info</p>
</template>
</base-layout>
@Bean
public TaskScheduler scheduler() {
ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
scheduler.setPoolSize(10);
scheduler.setThreadNamePrefix("Scheduler-Thread-");
scheduler.initialize();
return scheduler;
}
4.2 TimerManagerTaskScheduler
참고) 유연한 조건을 이용!할때 쓰는 Trigger 인터페이스
package org.springframework.scheduling;
import java.util.Date;
import org.springframework.lang.Nullable;
public interface Trigger {
@Nullable
Date nextExecutionTime(TriggerContext var1);
}
그 Trigger 인터페이스를 구현한 CronTrigger CronExpression을 지원한다.
package org.springframework.scheduling.support;
import java.util.Date;
import java.util.TimeZone;
import org.springframework.scheduling.Trigger;
import org.springframework.scheduling.TriggerContext;
public class CronTrigger implements Trigger {
private final CronSequenceGenerator sequenceGenerator;
public CronTrigger(String expression) {
this.sequenceGenerator = new CronSequenceGenerator(expression);
}
public CronTrigger(String expression, TimeZone timeZone) {
this.sequenceGenerator = new CronSequenceGenerator(expression, timeZone);
}
public String getExpression() {
return this.sequenceGenerator.getExpression();
}
public Date nextExecutionTime(TriggerContext triggerContext) {
Date date = triggerContext.lastCompletionTime();
if (date != null) {
Date scheduled = triggerContext.lastScheduledExecutionTime();
if (scheduled != null && date.before(scheduled)) {
date = scheduled;
}
} else {
date = new Date();
}
return this.sequenceGenerator.next(date);
}
public boolean equals(Object other) {
return this == other || other instanceof CronTrigger && this.sequenceGenerator.equals(((CronTrigger)other).sequenceGenerator);
}
public int hashCode() {
return this.sequenceGenerator.hashCode();
}
public String toString() {
return this.sequenceGenerator.toString();
}
}
5. Annotaion 활용 ( @Scheduled , @Async )
5.1 @Scheduled
태스크 역할을 맡은 메소드에 직접 스케줄 정보를 어노테이션을 통해 부여해 수케줄이 적용되게 해준다.
@Scheduled 부여되는 메소드는 파라미터를 가질 수 없으며 반드시 void형 리턴 타입이어야한다.
- fixedDelay : 이전 작업이 끝난 시점부터 일정시간이 지난후에 동작하도록 설정 ,
이전 작업이 끝난후로 부터 정해진 시간이 지난후 다음작업이 시작된다.
@Schduled (fixedDelay=60000)
public void testFixedDelay(){...}
- fixedRate : 밀리초로 설정된 일정한 시간간격으로 메소드 실행
@Schduled (fixedRate=60000)
public void testFixedRate(){...}