AOP(Aspect Oriented Programming)
, 즉 관점 지향 프로그래밍은 어떤 로직을 기준으로 핵심적인 관점과 부가적인 관점으로 나누어 각각 모듈화하는 것
✔ 핵심적인 관점 : 수행하고자 하는 비즈니스 로직
✔ 부가적인 관점 : 비즈니스 로직을 실행하기 위해 수행하는 DB 연결, logging 등
재사용성
과 생산성
을 높일 수 있다❗
📌dependency 추가
implementation 'org.springframework.boot:spring-boot-starter-aop
📌aop.java 생성
aop.java
를 생성하여 @Aspect
,@Component
Annotation을 붙여준다.
@Component
@Aspect
public class LoginAop
✔Aspect
: 해당 클래스가 AOP
임을 알려주는 annotation
✔Component
: 프로그램이 실행되면 component scan
에 의해 controller
, service
, repository
가 등록되지만 aspect의 경우 component로 등록되지 않았기 때문에 따로 등록해주는 과정이 필요하다.
📌point cut 등록
@Pointcut("execution(* com.example.aop.controller..*.*(..))")
@Pointcut("execution(public String com.example.aop.controller.PayController.*(..))
첫번째 point cut은 controller 패키지 밑에 있는 모든 클래스에 등록을 한 것이고,
두번째 point cut은 Paycontroller의 메서드 중 String을 반환하는 메서드에 적용되는 것을 의미한다.
❗point cut 등록 시 여러 개의 클래스 혹은 메서드 등록이 필요하다면 ||
,&&
연산자를 이용하여 여러 개의 등록도 가능하다.
@Pointcut("execution(public String com.example.aop.controller.PayController.*(..))
|| execution(public String com.example.aop.controller.BuyController.*(..))")
public void cut(){}
📌실행 시점 등록
@Before
,@After
,@Around
등이 존재하며 나는 @Around를 사용하여 지정된 패턴이 해당하는 메서드의 실행되기 전, 후 모두에서 사용되도록 설정하였다.
@Around("cut()")
public Object around1(ProceedingJoinPoint joinPoint) throws Throwable {
HttpSession session = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest().getSession();
if(session.getAttribute("email")==null){
return "login";
}
else{
return joinPoint.proceed();
}
}
cut()
이 실행되기 전, 후에 사용되도록 지정하였고 @Around
의 경우 반환 값은 지정된 패턴에 해당하는 메서드의 실행 결과를 반환해야 하므로 Object
이다.
📌정리
예제처럼 어떠한 비지니스 로직을 수행하기 위해 사용자가 로그인이 되어 있는 상태인지 확인하는 부분이 필요하였다.
지금까지는 모든 로직을 수행하기 전에 session에 로그인한 유저의 이메일 값이 저장되어 있는지 확인을 한 후
, 저장이 되어 있지 않다면 로그인을 유도하였고, session 값에 존재한다면 해당 비지니스로직을 수행하도록 하였다.
이런 과정은 동일한 코드의 중복을 야기하며 유지보수에 용이하지 못하다.
또한 객체지향프로그래밍의 원칙 중 단일 책임 원칙(SRP)
을 위배하여 하나의 모듈이 아닌 여러 부분의 수정과정이 필요하므로 AOP
을 이용하여 재사용성과 생산성을 높힐 수 있음을 알게 되었다.