Notice
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
Tags
- SpringMVC
- java lambda
- spring
- Spring Boot
- micrometer tracing
- traceId
- ResponseBody
- java
- spring3 spring2 traceid
- elasticsearch
- traceasynccustomautoconfiguration
- CompletableFuture
- java list
- DeferredImportSelector
- Spring JPA
- awssecretsmanagerpropertysources
- asynccustomautoconfiguration
- jpa
- aws secretmanager
- map
- kotlin
- java.util.list
- b3-propagation
- list
- EnableWebMvc
- HashMap
- @FunctionalInterface
- Sleuth
- asyncconfigurer
- spring MVC
Archives
- Today
- Total
du.study기록공간
JPA save() Domain Event 추가하기 본문
728x90
JPA 를 사용하면서 save동작시, event를 등록하는 방법에 대해 기록하려합니다.
특정 entity가 저장이 될때, event호출을 통하여 특정 동작을 수행하게 할 수 있습니다.
코드로 간략하게 보면 다음과 같습니다.
Event 코드
public class AccountEvent extends ApplicationEvent {
private final Account account;
public AccountEvent(Object source) {
super(source);
this.account = (Account) source;
}
public Account getAccount() {
return account;
}
}
Listener 코드
@Component
public class AccountSaveListener implements ApplicationListener<AccountEvent> {
@Override
public void onApplicationEvent(AccountEvent accountEvent) {
System.out.println("event occurred");
Account account = accountEvent.getAccount();
System.out.println(account.getUsername() +","+account.getPassword());
}
}
Entity 코드
@Entity
public class Account extends AbstractAggregateRoot<Account> {
@Id
@GeneratedValue
private Long id;
private String username;
private String password;
.... 생략
public Account publish(){
this.registerEvent(new AccountEvent(this));
return this;
}
}
테스트를 위한 Runner코드
@Component
public class JpaRunner implements ApplicationRunner {
@Autowired
private AccountRepository accountRepository;
@Override
public void run(ApplicationArguments args) throws Exception {
Account account = new Account();
account.setUsername("DUSANG");
account.setPassword("PWD");
accountRepository.save(account.publish());
}
}
간단하게 정리하면 동작 순서는 다음과 같게됩니다.
1. 사전세팅을 진행한다.
- Event 작성
- Event를 받는 Listener 작성 ( bean으로 등록)
- Entity에 AbstractAggregateRoot<{Entity name}> 상속.
- save() 시 registerEvent 코드가 같이 등록될 함수 어딘가에 저장.
2. save를 하면서 특정 registerEvent 를 같이 등록하는 함수 호출
3. 이벤트 리스너 호출.
다음과 같이 동작하게됩니다.
추가)
save과정에서 코드를 따라가다 보면 다음 EventPublishingRepositoryProxyPostProcessor 클레스에서 해당 함수가 호출되게 됩니다.
public void publishEventsFrom(@Nullable Object object, ApplicationEventPublisher publisher) {
if (object == null) {
return;
}
for (Object aggregateRoot : asCollection(object)) {
for (Object event : asCollection(ReflectionUtils.invokeMethod(publishingMethod, aggregateRoot))) {
publisher.publishEvent(event);
}
if (clearingMethod != null) {
ReflectionUtils.invokeMethod(clearingMethod, aggregateRoot);
}
}
}
해당 코드에서 publisher.publishEvent(event); 를 보고 여러 event를 등록할 수있다는것을 알 수있습니다.
한코드에 모든것을 때려박는 짓을 피할 수 있습니다.
728x90
'JPA' 카테고리의 다른 글
JPA - Pageable을 이용한 Limit설정 방법 (0) | 2020.09.17 |
---|---|
JPA Null 처리 방법, List가 null이 아닌 이유 (0) | 2020.09.15 |
JPA - JpaRepository API (0) | 2020.09.11 |
JPA Query update @modifying (0) | 2020.08.26 |
Comments