본문 바로가기

프로그래밍 기초/SPRING

[Spring]AOP란? / Aop를 위한 환경설정 및 Aop활용

AOP란? 

(Aspect Oriented Programming/관점지향 프로그래밍)

프로그램 개발에서 의미하는 Aspect란 '비즈니스 로직은 아니지만, 반드시 해야 하는 작업' 정도로 해석 가능하다. 정말 중요한 작업은 아니지만, 반드시 해야 하는 공통된 작업으로 '횡단 관심사'라고 부르는데 AOP란 비핵심이지만 꼭 필요한 것 중 공통화할 수 있는 부분을 따로 빼서(횡단 분리) 관리하는 것을 뜻한다.

 

횡단 관심의 흔한 예) 로그인 / 보안 / 성능 모니터링 : 보안 검증이 된 사람에 의해서만 특정 비즈니스 로직이 이뤄지는 것 (이 자체가 고객의 비즈니스는 아님

 

 


AOP를 위한 환경설정

1.자바프로젝트생성 후 

->configure->maven project

 

2-1.pom.xml파일 맨 아래</build></project> 둘 사이에 아래의 코드 삽입 후 저장

  <dependencies>
   	<!-- 스프링 기본 라이브러리  -->
  	<dependency>
	    <groupId>org.springframework</groupId>
	    <artifactId>spring-context</artifactId>
	    <version>4.0.0.RELEASE</version>
	  </dependency>
  	<!-- Aop 용 라이브러리 -->
   	<dependency>
   		<groupId>org.springframework</groupId>
   		<artifactId>spring-aop</artifactId>
   		<version>4.0.0.RELEASE</version>
  	</dependency>
    <dependency>
   		<groupId>org.aspectj</groupId>
   		<artifactId>aspectjweaver</artifactId>
   		<version>1.8.0</version>
     </dependency>
    <dependency>
   		<groupId>cglib</groupId>
   		<artifactId>cglib</artifactId>
   		<version>3.2.0</version>
  	</dependency> 
  </dependencies>

2-2.package 3개 test.aspect / test.main/ test.mypac 생성

 

3.init.xml문서 생성

패키지 오른클릭->new->other->spring bean configuration file

4-1. init.xml source내용 추가

	<!-- 컴포턴트 스캔을 해서 bean으로 만들 객체는 만들어 준다. -->
	<context:component-scan base-package="test.mypac"/>
	<context:component-scan base-package="test.aspect"/>
	
	<!-- annotation기반으로  aop를 적용하기 위한 설정 -->
	<aop:aspectj-autoproxy/>

component-scan을 이용하면 bean을 더 편하게 만들 수 있다.

 

4-2. init.xml namespaces 체크 수정

 

init.xml의 namespaces에서 체크리스트를 아래와 같이 수정한다.

 

5.test.mypac에 writingUtil.java만들기

package test.mypac;

import org.springframework.stereotype.Component;
/*
 * [bean이 된다.]
 * -해당 클래스로 객체가 생성이되고 스프링bean컨테이너에서 관리가 된다.
 */
//@Componet어노테이션을 붙여놓으면 컴포넌트 스캔을 했을 때 bean이된다.
@Component
public class WritingUtil {
	public void write1() {
		System.out.println("편지를 써요");
	}
	public void write2() {
		System.out.println("일기를 써요");
	}
	public void write3() {
		System.out.println("소설을 써요");
	}
}

@Component해놓았기 때문에

(1)init.xml에서 component-scan했을 때 객체가 생성되고

(2)spring bean container 에서 관리가 된다.

 

6.test.aspect패키지에 PenAspect.java만들기

package test.aspect;

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;

@Aspect //aspect 역활을 할 수 있도록
@Component //bean 이 될 수 있도록
public class PenAspect {
	/*
	 * spring이 관리하는 객체의 메소드 중에서
	 * 리턴type은 void    메소드명은 write로 시작
	 * 메소드에 전달되는 인자는 없는 
	 * 메소드의 수행 이전에 할 작업
	 */
	@Before("execution(void write*())") //스프링이 관리하고있는 
	//메소드중에서 메소드 수행 이전에 적용한다.
	public void prepare() {
		System.out.println("Pen을 준비해요!");
	}
}

@Aspect : aspect역활 가능하게해줌

@Componet : bean이 되게해줌

@Before(aspectj expression ) : aspectj expression 전에 적용하게 해줌

 

7.test.main패키지에 MainClass.java 만들기

 

package test.main;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import test.mypac.WritingUtil;

public class MainClass {
	public static void main(String[] args) {
		//init.xml문서를 로딩해서 bean으로 만들것들은 만들어서 관리한다.
		ApplicationContext context=
				new ClassPathXmlApplicationContext("test/main/init.xml");
		//관리하고 있는 객체중에서 WritingUtil type의 참조값 얻어오기
		WritingUtil util=context.getBean(WritingUtil.class);
		
		util.write1();
		util.write2();
		util.write3();
	}
}

 

ApplicationContext context= new ClassPathXmlApplicationContext("test/main/init.xml");로 xml문서를 로딩한다.


정리

 

 

init.xml에서 원하는 파일이 들어있는 패키지를 component-scan하고

WritingUtil.java에서 @Compnent하면 

스프링에서 관리하는 bean을 손쉽게 만들 수 있다.

 

 

1.

WritingUtil에 write1,write2,write3메소드 호출 전에 반복적으로 "Pen을 준비해요"라고 출력되는 메소드를 만들고 싶다.

이렇게 반복되는 것을 횡단관심사(Crosscutting Concerns )이라고 한다. 

횡단관심사는 특정상황에서 반복되므로 WritingUtil.java에서 직접 쓰지 않고 따로 관리한다.

 

2.init.xml에서 component-scan, PesAspect에서 @Componet 를 해서 bean으로 만든다.

 @Aspect , @Before로 특정 메소드 이전에 수행하는 aspect역활을 할 수 있게 만든다.

 

 

 

메인메소드에서 호출할 Writingutil객체는 init.xml문서에서 bean으로 만들어져 있기 때문에

new ClassPathXmlApplicationContext("init.xml주소");로 xml문서를 로딩해서

context.getBean(WritingUtil.class)로 참조값을 얻어온다.