https://engkimbs.tistory.com/746
OOP(자바의 기본방식 : 각체지향 ) 에서 Aspect 만 바뀌였다.
특정 한 타이밍에 어느 위치에 어떤 메소드를 실행 시킬 것인지에 대한 프로그래밍 기법
Aspect: 기존 객체 지향 프로그램에서 모듈화 기법으로
추가된 중복 코드(공통 처리 부분)을 별도의 독립된 클래스(Aspect)로 만들어 놓은 것
AOP : 공통(공용), 공유 할 내용, 일종의 기법
핵심모듈 : 반드시 구현할 기능
예) 로그인 여부 확인(회원 수정, 삭제 등에 필요함)
위와 같은 기능을 할 코드들을 따로 클래스로 만들어준다.
이것을 공통 관심사 모듈(Aspect)이라고 한다.
공통 관심사 모듈
예) 로그인 처리부분, 보안, 공통으로 사용할 수 없는 코딩
-> 스프링에서는 Aspect는 Advice라고 한다. Angular에서는 서비스라고 한다.
AOP는 언제 불러다 사용할 것이고, 언제 실행 할 것인지가 중요하다.
이렇게 실행 위치를 지정해주는 것은 joinPoint, PointCut라고 한다.
JoinPoint : 실행 위치를 지정(실행 위치만 지정한다.)
예) before, after
PointCut : 어떤 메소드 앞, 뒤에서 실행을 지정
어느 메소드를 사용할 것인지도 같이 설정해준다.
ex) before에 startMethod 실행지정.
이러한 지정 법은 Weaving이라고 한다.
핵심클래스의 특정위치에 넣어주는 것
이러한 모든 것을 통틀어 Aspect라고 한다.
또한 Aspect와 Advice를 합쳐진 것을 보고 Advisior라고도 한다.
AOP를 실행 시키는 방법
1. 프록시 기반의 AOP지원(AOP객체를 생성해주는 클래스)
default(메소드 중심)->빈즈 클래스로 구성.
2. <aop:config>태그를 사용
3. AspectJ이용 (@Aspect Annotation을 이용하는 방법)
맨 밑에 있는 mvc를 선택해도 되지만(Spring MVC Project),
자동으로 만들어주는 프로젝트이기 때문에 수정하기가 쉽지않다.
따라서, 수동으로 프로젝트를 설계하기 위해 위와 같은 프로젝트로 설정한다.
POM.xml 수정하기
AOP -> springFrame(스프링 프레임워크이 필요하고, 스프링-익스프레션, 스프링-빈즈 라는 라이브러리가 필요하다.)
AOP연습에서는 위와 같은 lib가 필요하다.
변경 전
<?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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.dod</groupId>
<artifactId>dko</artifactId>
<name>fvdsafds</name>
<packaging>war</packaging>
<version>1.0.0-BUILD-SNAPSHOT</version>
<properties>
<java-version>1.6</java-version>
<org.springframework-version>3.1.1.RELEASE</org.springframework-version>
<org.aspectj-version>1.6.10</org.aspectj-version>
<org.slf4j-version>1.6.6</org.slf4j-version>
</properties>
<dependencies>
<!-- Spring -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${org.springframework-version}</version>
<exclusions>
<!-- Exclude Commons Logging in favor of SLF4j -->
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${org.springframework-version}</version>
</dependency>
<!-- AspectJ -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>${org.aspectj-version}</version>
</dependency>
<!-- Logging -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${org.slf4j-version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>${org.slf4j-version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>${org.slf4j-version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.15</version>
<exclusions>
<exclusion>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
</exclusion>
<exclusion>
<groupId>javax.jms</groupId>
<artifactId>jms</artifactId>
</exclusion>
<exclusion>
<groupId>com.sun.jdmk</groupId>
<artifactId>jmxtools</artifactId>
</exclusion>
<exclusion>
<groupId>com.sun.jmx</groupId>
<artifactId>jmxri</artifactId>
</exclusion>
</exclusions>
<scope>runtime</scope>
</dependency>
<!-- @Inject -->
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
<version>1</version>
</dependency>
<!-- Servlet -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<!-- Test -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.7</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-eclipse-plugin</artifactId>
<version>2.9</version>
<configuration>
<additionalProjectnatures>
<projectnature>org.springframework.ide.eclipse.core.springnature</projectnature>
</additionalProjectnatures>
<additionalBuildcommands>
<buildcommand>org.springframework.ide.eclipse.core.springbuilder</buildcommand>
</additionalBuildcommands>
<downloadSources>true</downloadSources>
<downloadJavadocs>true</downloadJavadocs>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.5.1</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
<compilerArgument>-Xlint:all</compilerArgument>
<showWarnings>true</showWarnings>
<showDeprecation>true</showDeprecation>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.2.1</version>
<configuration>
<mainClass>org.test.int1.Main</mainClass>
</configuration>
</plugin>
</plugins>
</build>
</project>
변경 후
<?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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.hjs</groupId>
<artifactId>springAop</artifactId>
<name>SpringAop</name>
<packaging>war</packaging>
<version>1.0.0-BUILD-SNAPSHOT</version>
<properties>
<!-- Generic properties -->
<java-version>1.6</java-version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<!-- Spring -->
<org.springframework-version>4.2.5.RELEASE</org.springframework-version>
<!-- Hibernate / JPA -->
<hibernate.version>4.2.1.Final</hibernate.version>
<!-- Logging -->
<logback.version>1.0.13</logback.version>
<slf4j.version>1.7.5</slf4j.version>
<!-- Test -->
<junit.version>4.11</junit.version>
<org.aspectj-version>1.6.10</org.aspectj-version>
<org.slf4j-version>1.6.6</org.slf4j-version>
</properties>
<dependencies>
<!-- Spring -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${org.springframework-version}</version>
<exclusions>
<!-- Exclude Commons Logging in favor of SLF4j -->
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${org.springframework-version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-expression</artifactId>
<version>${org.springframework-version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${org.springframework-version}</version>
</dependency>
</dependencies>
</project>
샘플 스프링 메이븐으로 만들게 되면 pom.xml의 내용이 필요한 내용만 들어가게 된다.
<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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.springframework.samples</groupId>
<artifactId>AOPSpring</artifactId>
<version>0.0.1-SNAPSHOT</version>
<properties>
<!-- Generic properties -->
<java.version>1.6</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<!-- Spring -->
<spring-framework.version>3.2.3.RELEASE</spring-framework.version>
<!-- Hibernate / JPA -->
<hibernate.version>4.2.1.Final</hibernate.version>
<!-- Logging -->
<logback.version>1.0.13</logback.version>
<slf4j.version>1.7.5</slf4j.version>
<!-- Test -->
<junit.version>4.11</junit.version>
</properties>
<dependencies>
<!-- Spring and Transactions -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring-framework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${spring-framework.version}</version>
</dependency>
<!-- Logging with SLF4J & LogBack -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>${logback.version}</version>
<scope>runtime</scope>
</dependency>
<!-- Hibernate -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>${hibernate.version}</version>
</dependency>
<!-- Test Artifacts -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring-framework.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
https://blog.naver.com/hojysoo/221971341519
버전 정보를 수정해준다.
<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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.springframework.samples</groupId>
<artifactId>AOPSpring</artifactId>
<version>0.0.1-SNAPSHOT</version>
<properties>
<!-- Generic properties -->
<java.version>1.6</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<!-- Spring -->
<spring-framework.version>4.2.5.RELEASE</spring-framework.version>
<!-- Hibernate / JPA -->
<hibernate.version>4.2.1.Final</hibernate.version>
<!-- Logging -->
<logback.version>1.0.13</logback.version>
<slf4j.version>1.7.5</slf4j.version>
<!-- Test -->
<junit.version>4.11</junit.version>
</properties>
<dependencies>
<!-- Spring and Transactions -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring-framework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${spring-framework.version}</version>
</dependency>
<!-- Logging with SLF4J & LogBack -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>${logback.version}</version>
<scope>runtime</scope>
</dependency>
<!-- Hibernate -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>${hibernate.version}</version>
</dependency>
<!-- Test Artifacts -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring-framework.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<!-- 1. 핵심 Class 빈즈 등록 -->
<bean id="testServiceImpl" class="sp.aop.TestServiceImpl" />
<!-- 2. Advice Class 빈즈 등록 -->
<bean id="beforeLog" class="sp.aop.BeforeLogAdvice" />
<!-- 3.PointCut 생성 -->
<bean id="" class="org.springframework.aop.support.JdkRegexpMethodPointcut" />
</dependencies>
</project>
package sp.aop;
import java.lang.reflect.Method;
import org.springframework.aop.MethodBeforeAdvice; // 이후라고하면 MethodAfterAdvice 구현받으면 된다.
//추가
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
//Advice : 모든 Class에 공통으로 사용할 기능( 소스코드 -> method 중심 )
//interface 대신(OOP 방식) 에 Advice Class 를 작성해서 구현(AOP 방식) -> Aspect
//실행 위치를 특정 Method 의 앞에서 실행 -> MethodBeforeAdvice 를 구현
public class BeforeLogAdvice implements MethodBeforeAdvice { //공통관심 모듈 클래스를 만든다.
private Log log = LogFactory.getLog(getClass()); //Log 객체를 얻어오는 문장
//1) Spring의 AOP(method 중심) -> 핵심 CLass의 Method
//2) 생성된 객체를 배열로 받아온다.
//3) target Class(핵심 Class의 객체를 얻어온다.)
@Override
public void before(Method method, Object[] args, Object target) throws Throwable {
//TODO auto-generated method stub
log.info(method.toString()+" Method : "+target+"에서 호출 전!");
}//before() END
}//BeforeLogAdvice CLASS END
package sp.aop;
//모든 핵심 class 에서 공통으로 사용할 목적으로의 Method 작성, 인터페이스는 메소드 옆에 {} 지정하면 안된다.
public interface TestService {
// 해당 메소드들은 public abstract void 와 같이 추상메소드로 작성된다.
public void save(String msg);// 입력
public void write(); //출력
}//TestService INTERFACE END
app.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-4.2.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd">
<!-- 1. 핵심 Class 빈즈 등록 -->
<bean id="testServiceImpl" class="sp.aop.TestServiceImpl" />
<!-- 2. Advice Class 빈즈 등록 -->
<bean id="beforeLog" class="sp.aop.BeforeLogAdvice" />
<!-- 3.PointCut 생성 -> 어느 위치에서 AOP Method 를 지정해서 실행
value="접근 지정 반환명 package 명... Class 명 하위 package 명(..) 특정 Method명 0개 이상"
(*) 매개변수 한 개 표시, (*,*) 매개변수 2개 표시 -->
<bean id="writePointcut"
class="org.springframework.aop.support.JdkRegexpMethodPointcut">
<property name="pattern" value=".*write.*" />
</bean>
<!-- 4. Advice + PointCut(Advisor) 설정 -->
<bean id="testAdvisor"
class="org.springframework.aop.support.DefaultPointcutAdvisor">
<property name="advice" ref="beforeLog" />
<property name="pointcut" ref="writePointcut" />
</bean>
</beans>
package sp.aop;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; // xml문서를 찾을 수 있게 하는 lib
public class ResultMain {
public static void main(String[] args) {
String path="sp/aop/app.xml";
ApplicationContext context = new ClassPathXmlApplicationContext(path);
//TestService service= (TestService)context.getBean("testServiceImpl");
//원래는 위의 것이 일반적이지만, AOP 객체를 얻어오기 위해서는, 밑에처럼 AOP객체를 얻는다.
//AOP객체를 생성 -> Advisor 작동 -> Advice + pointcut 실행
TestService service = (TestService)context.getBean("testService");
service.save("AOP 적용 연습");
//before advice(before() 작동 실행) -> 실행상태에서 처리
service.write();
}//main()END
}//CLASS END
package sp.aop;
import java.lang.reflect.Method;
import org.springframework.aop.AfterReturningAdvice;
public class AfterLogAdvice implements AfterReturningAdvice {
public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
// TODO Auto-generated method stub
System.out.println(method.toString()+"method:"+target+"에서 호출 후!");
}
/* @Override
public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
* 1. 추가된 객체
* 2.핵심클래스의 method명
* 3.생성된 객체들
* 4.targetClass의 객체
System.out.println(method.toString()+"method:"+target+"에서 호출 후!");
}*/
}
app.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-4.2.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd">
<!-- 1. 핵심 Class 빈즈 등록 -->
<bean id="testServiceImpl" class="sp.aop.TestServiceImpl" />
<!-- 2. Advice Class 빈즈 등록 -->
<bean id="beforeLog" class="sp.aop.BeforeLogAdvice" />
<bean id="AfterLog" class="sp.aop.AfterLogAdvice" />
<!-- 3.PointCut 생성 -> 어느 위치에서 AOP Method 를 지정해서 실행
value="접근 지정 반환명 package 명... Class 명 하위 package 명(..) 특정 Method명 0개 이상"
(*) 매개변수 한 개 표시, (*,*) 매개변수 2개 표시 -->
<bean id="writePointcut" class="org.springframework.aop.support.JdkRegexpMethodPointcut">
<property name="pattern" value=".*write.*" />
</bean>
<bean id="savePointcut" class="org.springframework.aop.support.JdkRegexpMethodPointcut">
<property name="pattern" value=".*save.*" />
</bean>
<!-- 4. Advice + PointCut(Advisor) 설정 -->
<bean id="testAdvisor" class="org.springframework.aop.support.DefaultPointcutAdvisor">
<property name="advice" ref="beforeLog" />
<property name="pointcut" ref="writePointcut" />
</bean>
<!-- 4-1. Advice + PointCut(Advisor) 설정 -->
<bean id="testAfterAdvisor" class="org.springframework.aop.support.DefaultPointcutAdvisor">
<property name="advice" ref="AfterLog" />
<property name="pointcut" ref="savePointcut" />
</bean>
<!-- 5. AOP를 적용(ProxyFactoryBean 객체를 생성) target(핵심 Class) -->
<bean id="testService" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="target" ref="testServiceImpl" />
<property name="interceptorNames">
<list>
<value>testAdvisor</value>
<value>testAfterAdvisor</value>
</list>
</property>
</bean>
<!-- ///////END AOP 환경설정 부분 -->
</beans>
':: IT > Spring' 카테고리의 다른 글
[스프링프레임워크] 컨트롤러 작성, DAO,DTO,VO설명, 상세보기 (0) | 2020.05.14 |
---|---|
[스프링프레임워크]VO클래스 작성, 수정,삭제 구현 (0) | 2020.05.13 |
[스프링프레임워크]오라클 테이블 생성과 Dummy 데이터 생성, (0) | 2020.05.12 |
[스프링프레임워크] 스프링프레임워크 폴더 생성, spring MVC 설명, DI, IoC, 스프링 MVC 프로젝트 기초 설정, (0) | 2020.05.11 |