[Spring AOP] 포인트컷 표현식 - bean

목차

bean

bean 표현식은 스프링 컨테이너에 등록된 Bean 이름을 기준으로 Advice 적용 여부를 판단합니다.

bean은 AspectJ 표준 지시자가 아닌 스프링 AOP에서만 사용 가능한 지시자입니다. 패키지나 타입 대신 Bean 이름을 기준으로 Advice를 적용하고 싶을 때 유용합니다.

bean(빈 이름 패턴)

와일드카드 *를 사용해 이름 패턴으로 여러 Bean을 한 번에 지정할 수 있습니다.

기본 사용 예시

특정 Bean 이름 지정

Bean 이름을 정확히 명시하면 해당 Bean의 모든 메소드에 Advice가 적용됩니다.

// orderService 빈의 모든 메소드에 Advice 적용
bean(orderService)

와일드카드로 패턴 지정

*를 사용해 이름이 특정 패턴과 일치하는 Bean들을 대상으로 지정할 수 있습니다.

// 이름이 Repository 로 끝나는 모든 빈에 Advice 적용
bean(*Repository)

// 이름이 Service 로 끝나는 모든 빈에 Advice 적용
bean(*Service)

// 이름에 Order 가 포함된 모든 빈에 Advice 적용
bean(*Order*)

// 스프링 컨테이너의 모든 빈에 Advice 적용
bean(*)

논리 연산자 조합

||, &&, ! 연산자를 사용해 여러 조건을 조합할 수 있습니다.

// orderService 빈 또는 이름이 Repository 로 끝나는 빈에 Advice 적용
bean(orderService) || bean(*Repository)

// orderService 가 아닌 빈에 Advice 적용
!bean(orderService)

예제 코드

@Slf4j
@Import(BeanTest.BeanAspect.class)
@SpringBootTest
public class BeanTest {

@Autowired
OrderService orderService;

@Test
void success(){
orderService.orderItem("itemA");
}

@Aspect
static class BeanAspect{
// orderService 빈과 이름이 Repository 로 끝나는 빈에 Advice 를 적용합니다.
@Around("bean(orderService) || bean(*Repository)")
public Object doLog(ProceedingJoinPoint joinPoint) throws Throwable {
log.info("[bean] {}", joinPoint.getSignature());
return joinPoint.proceed();
}
}
}

orderService.orderItem("itemA")를 호출하면 내부에서 OrderRepository.save()도 함께 호출됩니다. orderService Bean과 *Repository 패턴에 해당하는 orderRepository Bean 모두 Advice 대상이므로, 두 메소드 모두에 로그가 출력됩니다.

2021-12-21 00:13:43.463  INFO 35836 --- [    Test worker] com.example.aop.pointcut.BeanTest        : [bean] void com.example.aop.order.OrderService.orderItem(String)
2021-12-21 00:13:43.474 INFO 35836 --- [ Test worker] com.example.aop.order.OrderService : [orderService] 실행
2021-12-21 00:13:43.475 INFO 35836 --- [ Test worker] com.example.aop.pointcut.BeanTest : [bean] String com.example.aop.order.OrderRepository.save(String)
2021-12-21 00:13:43.480 INFO 35836 --- [ Test worker] com.example.aop.order.OrderRepository : [orderRepository] 실행

execution, within 과의 비교

지시자 기준 인터페이스 지원 스프링 전용
execution 메소드 시그니처 (반환 타입, 패키지, 클래스, 메소드명, 파라미터) O X
within 타입 (클래스/패키지) X X
bean 스프링 Bean 이름 - O
  • execution, within타입/메소드 구조를 기준으로 Advice를 적용합니다.
  • beanBean 이름을 기준으로 Advice를 적용하므로, 타입 구조와 무관하게 Bean 등록 이름만으로 간단히 포인트컷을 설정할 수 있습니다.
  • 단, bean은 스프링 AOP에서만 동작하므로 AspectJ 위빙 방식으로 전환할 계획이 있다면 execution을 사용하는 것이 적합합니다.

주의사항

  • bean 지시자는 스프링 컨테이너에 등록된 Bean에만 적용됩니다. new 키워드로 직접 생성한 객체에는 적용되지 않습니다.
  • Bean 이름은 기본적으로 클래스 이름의 첫 글자를 소문자로 변환한 값이므로 (OrderServiceorderService), 와일드카드 패턴 작성 시 유의해야 합니다.
  • @Bean 등록 시 이름을 명시한 경우 (@Bean("myService")) 명시한 이름을 기준으로 매칭됩니다.
Share