Spring AOP
스프링 AOP(Aspect Oriented Programming : 관점지향프로그래밍) 패키지에 상관 없이 내가 필요로하는 부분을 찾는게 가능 ○ 불특정 다수의 객체(클래스,메소드)에 코드를 탈출할 수 있게 만드는 기능 ○ 공통적으로 사용되는 부분(공통화해서 라이브러리 할 수 있는 부분 : 트랜잭션 혹은 예외부분)을 별도로 분리하는 기술 ○ 공통된 기능을 재사용하는 기법 1. 용어 ① 횡단 관심사 ○ 모든 영역에 공통적으로 적용되는 코딩 ○ 중간중간 삽입되어야 할 기능들 ( 로깅,보안,트랜잭션..) ○ 주로 메소드 단위로 확인 ② 조인 포인트 ○ 어드바이스를 실행할 수 있는 지점 → 포인트컷의 후보 ○ 어플리케이션 실행의 특정 지점 ③ 어드바이스 ○ 조인포인트에게 실행 할 것인가? ○ 종류 - before : 메서드 호출 전 - after : 메서드 호출 후 - after returning : 메서드가 정상적으로 실행된 후 - after throwing : 메소드를 실행하는 도중 에러가 발생하는 경우 - around : 메소드 앞 뒤로 실행 ○ 조인포인트에서 실행 할 코드 ④ 포인트컷 ○ 어드바이스를 실행하는 조인 포인트 ○ 어드바이스를 실행하는 시간(위치) ⑤ 애스팩트 ○ 어드바이스 + 포인트컷 ○ 무엇을 언제할지 정의 |
1. 프로젝트 생성
new > Legacy Project >
2. AOP 라이브러리 다운
① Spring AOP
<!-- spring-aop --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aop</artifactId> <version>${spring.framework.version}</version> </dependency> |
② AspectJ Runtime
<!-- https://mvnrepository.com/artifact/org.aspectj/aspectjrt --> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjrt</artifactId> <version>1.5.4</version> </dependency> |
③ AspectJ Weaver
<!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver --> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.8.0</version> </dependency> |
④ CGLIB
<!--cglib --> <dependency> <groupId>cglib</groupId> <artifactId>cglib</artifactId> <version>3.2.4</version> </dependency> |
⑤ 라이브러리 파일 확인
3. 클래스 작성
○ 위치 : com/main/java > com.exe.aop
① targetA.java
② targetB.java
3-1. 실행할 시점에 따라 클래스 파일 생성
① MyBeforeAdvice.java
○ after, afterReturning, afterThrowing도 동일 코딩
package com.exe.aop; public class MyBeforeAdvice {
public void beforeMethodCall() { System.out.println("Jointpoint 메소드가 실행되기 전에..."); } } |
② MyAroundAdvice.java
○ processed();
- Around 어드바이스에서는 processed()를 만나기 전 까지는 Before 어드바이스와 같은 상태
- 이를 기준으로 위는 before, 밑은 after throwing
package com.exe.aop; import org.aspectj.lang.ProceedingJoinPoint; public class MyAroundAdvice { public Object aroundMethodCall(ProceedingJoinPoint jointPoint) {
Object result = null;
try {
System.out.println("Joinpoint 메소드 실행 전..(Around)");
result = jointPoint.proceed();
System.out.println("Joinpoint 메소드 실행 후..(Around)");
} catch (Throwable e) {
}
return result; } } |
4. app-context.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:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
<description>Example configuration to get you started.</description>
<context:component-scan base-package="com.exe.aop" />
</beans> |
② aspect 작성
○ expression="execution(public void com..aop.*.*(..))"
- excution(메소드 접근지정자 반환값 패키지이름.클래스이름.메소드이름(매개변수)
- ..은 생략 → 사이에 뭐가 오든 상관 없다
- com..aop : 맨 앞은 com, 맨 뒤는 aop, 중간은 상관 없음
<!-- 객체 생성 --> <bean id="beforeAdvice" class="com.exe.aop.MyBeforeAdvice"/>
<aop:config> <!-- ref : aspect를 적용할 객체 --> <aop:aspect ref="beforeAdvice"> <!-- 실행할 행동 --> <aop:pointcut id="beforePointcut" expression="execution(public void com..aop.*.*(..))"/>
<!-- 실행할 시점 --> <!-- method : --> <!-- aop:pointcut의 id와 ref는 같아야 한다 --> <aop:before method="beforeMethodCall" pointcut-ref="beforePointcut"/>
</aop:aspect> </aop:config> |
5. main작성
package com.exe.aop; import org.springframework.context.support.GenericXmlApplicationContext; public class AopMain { public static void main(String[] args) {
GenericXmlApplicationContext context = new GenericXmlApplicationContext("app-context.xml");
TargetA ta = (TargetA)context.getBean("targetA");
ta.doAnother1(); ta.doAnother2(); ta.doSomething1(); ta.doSomething2();
TargetB tb = (TargetB)context.getBean("targetB");
tb.doAnother1(); tb.doAnother2(); tb.doSomething1(); tb.doSomething2();
} } |
6. 어노테이션으로 변경
① app-content.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:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
<description>Example configuration to get you started.</description>
<context:component-scan base-package="com.exe.aop" />
<!-- aop를 어노테이션으로 만들겠다 --> <aop:aspectj-autoproxy/>
</beans> |
② 클래스 변경
○ MyBeforeAdvice.java
- @Aspect : 객체를 IoT까지 실행
<aop:aspect ref="beforeAdvice"> </aop:aspect>
- @Component : bean객체 생성
<bean id="beforeAdvice" class="com.exe.aop.MyBeforeAdvice"/>
package com.exe.aop; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.springframework.stereotype.Component; @Aspect @Component public class MyBeforeAdvice {
//실행시점 및 적용할 메소드 지정 @Before("execution(* com..aop.*.*(..))") public void beforeMethodCall() { System.out.println("Jointpoint 메소드가 실행되기 전에..."); }
} |
'STUDY > SPRING' 카테고리의 다른 글
스프링(3.0) 게시판 스프링 JDBC로 변경 (0) | 2019.04.18 |
---|---|
스프링(3.0) MVC : 게시판 만들기 (0) | 2019.04.18 |
스프링(3.0) MyBatis 연결 (0) | 2019.04.17 |
스프링(3.0) Spring JDBC (0) | 2019.04.16 |
스프링(3.0) Java에서 DB사용 (0) | 2019.04.16 |
댓글