@Before : 메소드 실행 전 Advice 실행
@After : 메소드 실행 후 Advice 실행 메서드가 성공적으로 수행된 경우와 에러가 발생하여 Exception이 생긴 경우 모두 해당
@After-returning : AOP가 적용될 메소드가 에러(예외)없이 성공적으로 실행이 되면 advice 실행
@After-throwing : AOP가 적용될 메소드가 에러(예외)가 발생하였을때 Exception을 던질때 advice 실행
@Around : AOP가 적용될 메소드의 시작부터 끝까지 전반적인 시점을 모두 관리한다.
패키지 구조
Student.java
package com.test04;
public interface Student {
public String classWork();
}
Man.java
package com.test04;
public class Man implements Student {
@Override
public String classWork() {
System.out.println("컴퓨터를 켜서 뉴스본다.");
return "스프링 연습";
}
}
Woman.java
package com.test04;
public class Woman implements Student {
@Override
public String classWork() {
System.out.println("컴퓨터를 켜서 주식본다.");
return "스프링 연습";
}
}
MyAspect.java
package com.test04;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
@Aspect
public class MyAspect {
//@Before : 메소드 실행 전 Advice 실행
@Before("execution(public * *(..))")
public void before(JoinPoint join) {
System.out.println("출석 한다.");
}
//@After : 메소드 실행 후 Advice 실행 메서드가 성공적으로 수행된 경우와 에러가 발생하여 Exception이 생긴 경우 모두 해당
@After("execution(public * *(..))")
public void after(JoinPoint join) {
System.out.println("집에 간다.");
}
//@After-returning : AOP가 적용될 메소드가 에러없이 성공적으로 실행이 되면 advice 실행
@AfterReturning(pointcut="execution(public * *(..))", returning = "returnVal")
public void returning(JoinPoint join, Object returnVal) {
System.out.println(returnVal + " 열심히 하는 날이었다.");
}
//@After-throwing : AOP가 적용될 메소드가 에러가 발생하였을때 Exception을 던질때 advice 실행
@AfterThrowing("execution(public * *(..))")
public void throwing(JoinPoint join) {
System.out.println("쉬는날이었다...");
}
//@Around는 AOP가 적용될 메소드의 시작부터 끝까지 전반적인 시점을 모두 관리한다.
}
applicationContext.xml
<?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-4.3.xsd">
<aop:aspectj-autoproxy />
<bean id="man" class="com.test04.Man" />
<bean id="woman" class="com.test04.Woman" />
<bean id="myAspect" class="com.test04.MyAspect" />
</beans>
MTest.java
package com.test04;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MTest {
public static void main(String[] args) {
ApplicationContext factory = new ClassPathXmlApplicationContext("com/test04/applicationContext.xml");
Student m = factory.getBean("man", Student.class);
Student w = (Student) factory.getBean("woman");
System.out.println("남학생 입장");
m.classWork();
System.out.println("----------");
System.out.println("여학생 입장");
w.classWork();
}
}
실행결과
applicationContext에서 <aop:aspectj-autoproxy />만 설정하고 bean객체만 만들었습니다.
autoproxy는 필요시에 자동으로 프록시 객체를 만들어줍니다.
MTest에서 보면 m객체와 w객체를 만들고 m.classWork()메소드를 호출하고 w.classWork()메소드를 호출하였습니다.
이들을 joinpoint라고합니다.
어떤 joinpoint에 cc와 ccc를 연결할지 알려주는 역할을 pointcut이 합니다.
MyAspect에서 각 메소드의 어노테이션으로 after, before, after-returning, after-throwing을 달았습니다.
이 어노테이션에는 execution(public * *(..))이 같이 있는데 pointcut의 역할을 합니다.
MyAspect가 advice(ccc code)가 되겠죠.
또한 MyAspect는 ccc(공통 관심사항)로서 Man을 호출해도 Woman을 호출해도 공통으로 나옵니다.
autoporxy가 프록시 객체가 만들어지고 target에게 보내지는 신호를 강탈하여 cc에 ccc를 붙이게 됩니다.
따라서 target인 컴퓨터를 키고 하는 행동의 앞뒤에 출석한다와 집에간다가 붙게 됩니다.
또한 예외발생 없이 정상적으로 동작하기 때문에 "스프링 연습 열심히 하는 날이었다." 까지 함께 출력됩니다
근데 만약 Man.java의 코드에 강제로 에러가 발생하도록 만들면 어떻게 될까요??
package com.test04;
public class Man implements Student {
@Override
public String classWork() {
System.out.println("컴퓨터를 켜서 뉴스본다.");
String t = null;
t.length();
return "스프링 연습";
}
}
이렇게 바뀌게 된다면 어떻게 나올까요??
쉬는날이었다... 가출력됩니다.
String 타입의 t가 null인데 길이가 있을수가 없어서 예외가 발생하게 되는데 예외가 발생하였기에 @after-returning이 아닌 after-throwing이 실행됩니다.
'Java 관련 > Spring Legecy' 카테고리의 다른 글
[Spring] Spring MVC & TODO (@RequestMapping @RequestParam @ModelAttribute @SessionAttribute) (0) | 2022.03.29 |
---|---|
[Spring] AOP(@Component) (0) | 2022.03.28 |
[Spring] AOP(Aspect Oriented Programming) (0) | 2022.03.26 |
[Spring] AOP(joinpoin, pointcut, advice, aspect, weaving) (0) | 2022.03.25 |
[Spring] AOP(cc / ccc) 관점 지향 프로그래밍 (0) | 2022.03.24 |