spring-aop
추가aspectJ
추가(이미 있음)<org.aspectj-version>1.9.7</org.aspectj-version>
...
...
<!-- spring-aop -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${org.springframework-version}</version>
</dependency>
<!-- AspectJ -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>${org.aspectj-version}</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>${org.aspectj-version}</version>
</dependency>
->
<!-- @Aspect 사용할 수 있도록 -->
<aop:aspectj-autoproxy/>
<!-- servlet-context 에서 이미 사용중?이기 때문에 false -->
<context:component-scan base-package="com.kh.app24" use-default-filters="false">
<context:include-filter type="annotation" expression="org.aspectj.lang.annotation.Aspect"/>
</context:component-scan>
@Asepct
를 사용한 클래스에 S
가 붙는다!!@EnableAspectJAutoProxy
@Component
@Aspect
@Slf4j
public class MyAspect {
//advice, 조인포인트, 포인트컷
//이 안에서 사용할 메소드를 advice라고 명명한다.
//언제 : HomeController가 실행되기 전에 : @Before
//대상 : "target(대상)"
@Before("target(com.kh.app24.HomeController)")
public void myAdvice01() {
log.info("myAdvice01 called~~");
}
}
@Before
)에 자기가 할 거 하고("target(대상)")
: 대상에 클래스 또는 인터페이스 지정@EnableAspectJAutoProxy
@Component
@Aspect
@Slf4j
public class MyAspect {
//advice, 조인포인트, 포인트컷
//이 안에서 사용할 메소드를 advice라고 명명한다.
//언제 : HomeController가 실행되기 전에 : @Before
//대상 : "target(대상)"
@Before("target(com.kh.app24.HomeController)")
public void myAdvice01() {
log.info("Before =============");
}
@After("target(com.kh.app24.HomeController)")
public void myAdvice02() {
log.info("After ==============");
}
}
@Controller
@RequestMapping("my")
@Slf4j
public class MyController {
@Autowired
private MyService service;
@GetMapping("test")
@ResponseBody
public String test() {
log.info("test method called...");
service.test();
return "test~~~";
}
}
@Service
@Slf4j
public class MyService {
@Autowired
private MyDao dao;
public void test() {
log.info("test method called...");
dao.test();
}
}
@Repository
@Slf4j
public class MyDao {
@Autowired
private SqlSession session;
public void test() {
log.info("test method called...");
}
}
@Before("target(com.kh.app24.aop.service.MyService)")
public void myAdvice03() {
log.info("MyService 클래스 실행 이전~~");
}
@After("target(com.kh.app24.aop.service.MyService)")
public void myAdvice04() {
long time = System.currentTimeMillis();
log.info("현재시간(ms) ::: {}", time);
}
/* @Around(대상)
* 리턴타입 : Object
* 파라미터 : ProceedingJoinPoint
* 예외 : Throwable
* Before, After 둘다 간섭 가능
* */
@Around("target(com.kh.app24.aop.service.MyService)")
public Object myAdvice05(ProceedingJoinPoint jp) throws Throwable {
//before
long start = System.currentTimeMillis();
//타겟 메소드 호출
Object obj = jp.proceed();
//after
long end = System.currentTimeMillis();
long elapse = end - start;
log.info("elapse : {}", elapse);
return obj;
}
// @Around("target(com.kh.app24.aop.service.MyService)")
// @Around("target(com.kh.app24.aop.dao.MyDao)")
@Around("within(com.kh.app24.aop..*)")
// @Around("within(com..*)")
public Object myAdvice05(ProceedingJoinPoint jp) throws Throwable {
System.out.println("elapse check start ==========com.kh.app24.aop..");
//before
long start = System.currentTimeMillis();
// long start = System.nanoTime();
//타겟 메소드 호출
Object obj = jp.proceed();
//after
long end = System.currentTimeMillis();
long elapse = end - start;
log.info("elapse : {}", elapse);
return obj;
}
"execution(대상)" : 대상에 표현식(접근제한자 반환형 패키지명.클래스명.메소드명(매개변수))
public : 생략 가능
리턴타입에 *
: 리턴타입 상관없으면
매개변수에 *
: 매개변수 1개 이상
매개변수에 ..
: 매개변수 0개 이상
@Around("execution(public void com.kh.app24.aop.dao.MyDao.test())")
public Object myAdvice05(ProceedingJoinPoint jp) throws Throwable {
System.out.println("elapse check start ==========com.kh.app24.aop..");
//before
long start = System.currentTimeMillis();
// long start = System.nanoTime();
//타겟 메소드 호출
Object obj = jp.proceed();
//after
long end = System.currentTimeMillis();
long elapse = end - start;
log.info("elapse : {}", elapse);
return obj;
}
// @Around("execution(public void com.kh.app24.aop.dao.MyDao.test())")
//public 은 생략 가능
//리턴타입 상관없으면 *
//매개변수에 * : 매개변수 1개 이상
//매개변수에 .. : 매개변수 0개 이상
//패키지명, 클래스명, 메소드명 : 표현식으로 처리 가능
// @Around("execution(* com.kh.app24.aop.dao.MyDao.select*(..))")
// @Around("execution(* com.kh.app24.aop.dao.MyDao.te*(..))")
// @Around("execution(* com.kh.app24.aop.dao.MyDao.*st(..))")
// @Around("execution(* com.kh.app24.aop.dao.*Dao.*(..))")
// @Around("execution(* com.kh.app24..*.*(..))")
// @Around("execution(* com..*Dao*.*(..))")
@Around("execution(* com..*.*(..))")
public Object myAdvice05(ProceedingJoinPoint jp) throws Throwable {
System.out.println("elapse check start ==========com.kh.app24.aop..");
//before
long start = System.currentTimeMillis();
// long start = System.nanoTime();
//타겟 메소드 호출
Object obj = jp.proceed();
//after
long end = System.currentTimeMillis();
long elapse = end - start;
log.info("elapse : {}", elapse);
return obj;
}