스프링 Schema-Based Spring AOP(<AOP> 네임스페이스 이용), 자바동영상/스프링동영상/자바교육/스프링교육/스프링프레임워크/스프링학원/자바학원/자바/JAVA

ojc.asia/bbs/board.php?bo_table=LecSpring&wr_id=876
ojc.asia
Schema-Based Spring AOP(<AOP> 네임스페이스 이용)
n 선언적인 스프링 AOP 설정을 간단하게 해 준다. <Beans> 태그 내에 aop 네임스페이스를 선언해야 한다.
n 모든 스프링 aop 설정을 <aop:config></aop:config> 안에 넣어야 하는데 포인트컷, 어스펙트, 어드바이저 등을 정의하고 다른 스프링 빈을 참조
가능 하다. aop:config 태그안에서 aspect를 정의하는 데 aspect=advisor=advice + pointcut 이므로 충고와 포인트컷을 aop:config안에서 정의해야 한다. 아래는 충고 클래스인 aBean을 외부에 선언하고 aop:config 태그안에서 ref로 참조 한 경우이다.
<aop:config>
<aop:aspect id="myAspect" ref="aBean">
...
</aop:aspect>
</aop:config>
<bean id="aBean" class="...">
...
</bean>
n aop:aspect 내에 pointcut을 정의할 수도 있다.
<aop:config>
<aop:aspect id="myAspect" ref=“aBean“>
<aop:pointcut id=“onjPointcut“ expression="execution(* x.y.z.service.*.*(..))"/>
……
</aop:aspect>
</aop:config>
<bean id="aBean" class="...">
...
</bean>
n pointcut을 정의하고 사전충고에서 포인트컷을 참조하고 충고메소드를 정의할 수도 있다.
<aop:config>
<aop:aspect id="myAspect" ref="aBean">
<aop:pointcut id=“onjPointcut“
expression=“execution(* x.y.z.service..*(..))"/>
<!– pointcut-ref 대신 pointcut 속성을 사용하여 직접 포인트컷 표현식을 써도 된다 à
<!—myLogic() 메소드가 사전 충고용 메소드임을 정의 à
<aop:before pointcut-ref="onjPointcut " method="myLogic"/>
</aop:aspect>
</aop:config>
<bean id="aBean" class="x.y.z.advice.MyAdvice">
...
</bean>
[MyAdvice.java]
// 충고 클래스인 MyAdvice.java 에서 myLogic이라는 메소드가 정의되어 있어야 한다.
package x.y.z.advice;
public class MyAdvice {
public void myLogic(Object service) { }
…
}
n 포인트컷 조합을 and, or , not을 사용할 수 있다.
<aop:config>
<aop:aspect id="myAspect" ref="aBean“>
<aop:pointcut id=“onjPointcut“
expression=“execution(* x.y.z.service..*(..))
and bean(smallmart)"/>
<aop:before pointcut-ref="onjPointcut " method="myLogic"/>
</aop:aspect>
</aop:config>
<bean id=”smallmart” class=”x.y.z.service.SmallMart”/> <!—타겟 클래스 à
<bean id="aBean" class="x.y.z.advice.MyAdvice">
...
</bean>
[MyAdvice.java]
// 충고 클래스인 MyAdvice.java 에서 myLogic이라는 메소드가 정의되어 있어야 한다.
package x.y.z.advice;
public class MyAdvice {
public void myLogic(Object service) { }
…
}
n 충고 작성 예문
// 포인트컷을 AspectJ Expression으로 직접 정의
<aop:before pointcut="execution(* x.y.z.dao.*.*(..))" method="insert"/>
// 포인트컷을 외부에 만들고 pointcut-ref로 참조
<aop:after-returning pointcut-ref="onjPointcut " method=“myLogic1"/>
<aop:after-throwing pointcut-ref="onjPointcut " method=“myLogic2”/>
<aop:after pointcut-ref="onjPointcut " method="myLogic3"/>
<aop:around pointcut-ref="onjPointcut " method="myLogic4"/>
<aop:around pointcut-ref="onjPointcut " method="myLogic4“ arg-names=“name, age”/>
n Advisor 작성 예문
<aop:config>
<aop:pointcut id=“onjPointcut"
expression="execution(* x.y.z.service.*.*(..))"/>
<aop:advisor pointcut-ref="onjPointcut" advice-ref="tx-advice"/>
</aop:config>
// 스프링 AOP를 이용하여 트랜잭션도 하나의 충고로 주입 가능하다.
// Pointcut 클래스(x.y.z.service 패키지 아래의 모든 클래스)의 모든 메소드가
// 트랜잭션(충고)이 적용됨을 정의한다.
<tx:advice id="tx-advice">
<tx:attributes>
<tx:method name="*" propagation="REQUIRED"/>
</tx:attributes>
</tx:advice>
Schema-Based Spring AOP(<AOP> 네임스페이스 이용) – 실습
n 이전에 프로그래밍적인 AOP / ProxyFactoryBean(XML방식)을 이용하여 작성한 SmallMart 예제를 aop Namespace를 이용한 방식으로 변경해 보자.
n 스프링부트 기반 예제

STS에서
1. File -> New -> Spring Starter Project
Name : demo-smallmart-2
Type : MAVEN
Package : onj.hello.aop2
[pom.xml]
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.4.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>demo-smallmart-2</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demo-smallmart-2</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
[SmallMart.java]
package onj.hello.aop2;
public interface SmallMart {
public void getProducts(String productName) throws Exception;
public void getProducts2(String productName) throws Exception;
}
[SmallMart.java]
package onj.hello.aop2;
public class SmallMartImpl implements SmallMart {
public void getProducts(String productName) throws Exception {
System.out.println("[Target Method]getProduct()..." + productName);
//throw new Exception("error..."); //주석으로 막고 실행해 보자.
}
public void getProducts2(String productName) throws Exception {
System.out.println("[Target Method]getProduct2()..." + productName);
//throw new Exception("error..."); //주석으로 막고 실행해 보자.
}
}
[SmallMartAdvice.java]
package onj.hello.aop2;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
public class SmallMartAdvice {
public void afterReturning(JoinPoint joinPoint) {
System.out.println(joinPoint.getSignature().getName() + "(" + joinPoint.getArgs()[0] + ") : 사후충고");
}
public void before(JoinPoint joinPoint) {
System.out.println(joinPoint.getSignature().getName() + "(" + joinPoint.getArgs()[0] + ") : 사전충고");
}
public void afterThrowing() {
System.out.println("예외충고 발생...");
}
public Object around(ProceedingJoinPoint pjp) throws Throwable {
String findName = (String)pjp.getSignature().getName();
String methodName = (String)pjp.getArgs()[0];
System.out.println("[주변충고]"+ findName + "(" + methodName +") 메소드 실행전");
//타켓클래스의 메소드 호출
Object obj = pjp.proceed();
System.out.println("[주변충고]" + findName + "(" + methodName +") 메소드 실행후");
return obj;
}
}
[DemoSmallmart2Application.java]
package onj.hello.aop2;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.GenericXmlApplicationContext;
@SpringBootApplication
public class DemoSmallmart2Application {
public static void main(String[] args) throws Exception {
SpringApplication.run(DemoSmallmart2Application.class, args);
ApplicationContext ctx = new GenericXmlApplicationContext();
((GenericXmlApplicationContext) ctx).load("smallmart2.xml");
((AbstractApplicationContext) ctx).refresh();
SmallMart smallMart = (SmallMart)ctx.getBean("smallMart");
smallMart.getProducts("과자");
smallMart.getProducts2("과자");
((AbstractApplicationContext) ctx).close();
}
}
[src/main/resources/smallmart2.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:config>
<aop:pointcut expression="execution(* onj.hello.aop2..getProducts2*(String)) and bean(smallMart*)"
id="onjpointcut" />
<aop:aspect ref="advice">
<aop:before method="before" pointcut-ref="onjpointcut" />
<aop:after-returning method="afterReturning"
pointcut-ref="onjpointcut" />
<aop:around method="around" pointcut-ref="onjpointcut" />
<aop:after-throwing method="afterThrowing"
pointcut-ref="onjpointcut" />
</aop:aspect>
</aop:config>
<bean id="advice" class="onj.hello.aop2.SmallMartAdvice" />
<bean id="smallMart" class="onj.hello.aop2.SmallMartImpl" />
</beans>
[결과]
[Target Method]getProduct()...과자
getProducts2(과자) : 사전충고
[주변충고]getProducts2(과자) 메소드 실행전
[Target Method]getProduct2()...과자
[주변충고]getProducts2(과자) 메소드 실행후
getProducts2(과자) : 사후충고
#AOP네임스페이스, #스프링AOP, #aop:config, #ProxyFactoryBean, #스프링포인트컷, #스프링충고, #포인트컷, #스프링pointcut, #스프링AOP, #스프링advice, #SpringAOP, #스프링DI, #스프링IoC, #SpringDI, #SpringIoC, #자바스프링, #Spring동영상, #Spring강의, #스프링프레임워크, #스프링교육, #스프링학원, #스프링강좌, #스프링강의, #자바학원, #자바, #스프링동영상, #자바동영상, #스프링프레임워크교육, #스프링프레임워크강의, #스프링프레임워크학원
댓글 없음:
댓글 쓰기