2022.03.29
AOP
일단 덤벼 보자 - 용어편
Pointcut - 자르는 지점? Aspect 적용 위치 지정자
package aop002;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
@Aspect
public class MyAspect {
@Before("execution(* runSomething())")
public void before(JoinPoint joinpoint) {
System.out.println("얼굴 인식 확인 : 문을 개방하라");
}
}
* runSomething()
이 Pointcut
@Before("execution(* runSomething())")
은 지금 선언하고 있는 메서드를(public void before
) 수행하기 전에 실행하라는 의미
public void before
는 횡단 관심사를 실행하는 메서드
- 타깃 메서드 지정자에는 정규식과 AspectJ표현식 등 사용가능
[접근제한자패턴]리턴타입[패키지&클래스패턴]메서드이름패턴(파라미터패턴)[throws 예외패턴]
public void aop002.Boy.runSomething()
- 접근제한자가 public이고
- 리턴타입은 void
- aop002 패키지 밑
- Boy 클래스 안에
- 파라미터가 없으며
- 던져지는 에러가 있든 없든
- 이름이 runSomething인 메서드를
- Pointcut으로 지정
* runtSomething()
- 접근제한자 상관없이
- 리턴타입이 상관없이
- 모든 패키지 밑
- 모든 클래스 안에
- 파라미터없으며
- 던져지는 에러가 있든 없든
- 이름이 runSomething인 메서드를
- pointcut으로 지정
Jointpoint - 연결점? 연결 가능한 지점
package aop002;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
@Aspect
public class MyAspect {
@Before("execution(* runSomething())")
public void before(JoinPoint joinpoint) {
System.out.println("얼굴 인식 확인 : 문을 개방하라");
}
}
- PointCut은 JoinPoint의 부분집합
- 스프링 AOP는 인터페이스를 기반
- 인터페이스는 추상 메서드의 집합체
- 따라서 스프링 AOP는 메서드에만 적용가능
- JoinPoint란 Aspect 적용이 가능한 모든 지점
=> 스프링 aop에서 JoinPoint란 스프링 프레임워크가 관리하는 빈의 모든 메서드
- JoinPoint joinPoint 객체는 호출된 객체의 메서드이다!!
=> 광의의 JoinPoint란 Aspect 적용이 가능한 모든 지점
=> 협의의 JoinPoint란 호출된 객체의 메서드
Advice - 조언? 언제 무엇을!
- PointCut에 언제, 무엇을 적용할지 정의한 메서드
package aop002;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
@Aspect
public class MyAspect {
@Before("execution(* runSomething())")
public void before(JoinPoint joinpoint) {
System.out.println("얼굴 인식 확인 : 문을 개방하라");
}
}
Aspect - 관점?측면? Advisor의 집합체
- Aspect는 여러 개의 Advice와 여러 개의 PointCut의 결합체를 의미하는 용어
- Aspect = Advice들 (언제,무엇을) + PointCut들 (어디에)
=> Aspect = 언제,어디에 , 무엇을
POJO 와 XML 기반의 AOP
package aop003;
import org.aspectj.lang.JoinPoint;
public class MyAspect {
public void before(JoinPoint joinpoint) {
System.out.println("얼굴 인식 확인 : 문을 개방하라");
}
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd">
<bean id="myAspect" class="aop003.MyAspect"/>
<bean id="boy" class="aop003.Boy"/>
<bean id="girl" class="aop003.Girl"/>
<aop:config>
<aop:aspect ref="myAspect">
<aop:before method="before" pointcut="execution(* runSomething())"/>
</aop:aspect>
</aop:config>
</beans>
package aop003;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Start {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("aop003/aop003.xml");
Person romeo = context.getBean("boy",Person.class);
Person juliet = context.getBean("girl",Person.class);
romeo.runSomething();
juliet.runSomething();
}
}
AOP 기초 완성
- After 어드바이스
joinPoint메서드를 실행한 후에 실행
XML기반
package aop003;
import org.aspectj.lang.JoinPoint;
public class MyAspect {
public void before(JoinPoint joinpoint) {
System.out.println("얼굴 인식 확인 : 문을 개방하라");
}
public void after(JoinPoint joinPoint) {
System.out.println("주인님 나갔다!!!");
}
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd">
<bean id="myAspect" class="aop003.MyAspect"/>
<bean id="boy" class="aop003.Boy"/>
<bean id="girl" class="aop003.Girl"/>
<aop:config>
<aop:aspect ref="myAspect">
<aop:pointcut expression="execution(* runSomething())" id="iampc"/>
<aop:before method="before" pointcut-ref="iampc"/>
<aop:after method="after" pointcut-ref="iampc"/>
</aop:aspect>
</aop:config>
</beans>
어노테이션 기반
package aop004;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
@Aspect
public class MyAspect {
@Pointcut("execution(* runSomething())")
private void iampc() {
}
@Before("iampc()")
public void before(JoinPoint joinpoint) {
System.out.println("얼굴 인식 확인 : 문을 개방하라");
}
@After("iampc()")
public void after(JoinPoint joinPoint) {
System.out.println("주인님 나갔다!!!");
}
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd">
<aop:aspectj-autoproxy/>
<bean id="myAspect" class="aop004.MyAspect"/>
<bean id="boy" class="aop004.Boy"/>
<bean id="girl" class="aop004.Girl"/>
</beans>