DI를 사용할 경우 클래스내의 멤버변수에 대한 의존도가 낮아지게 되면서 결합도가 낮아진다.
하지만, 멤버변수의 존재가 아예 사라진다는 경우에 과연 결합도가 없다고 할 수 있을까?
이를 해결하기위해 Spring에서는 AOP를 사용하였다.
AOP란?
클래스내의 멤버변수와의 의존도를 아예 없게 함으로써 다른 클래스와의 결합도를 낮추는 기법이다.
Spring은 AspectJ의 기술을 채용하여 사용하였다.
쓰는 이유?
예로 쇼핑몰 웹사이트를 제작 시 장바구니, 구매 등등 로그인 상태를 체크를 반드시 필요로 하는 페이지가 존재한다.
이런 경우 AOP와 같은 기술을 사용하지 않게 되면 해당 페이지의 컨트롤러와 같은 클래스나 페이지내에서 의존하게 된다. 이를 AOP와 같은 기술을 사용하여 분리하게 되면 프로그램의 유지보수가 상당히 편할 것이다.
사용방법
mvnrepository의 Spring MVC를 가져와서 pom.xml에 추가해준다.
Spring에서 사용되는 jar들이 많이 생기는데 여기에서 AOP도 추가된다.
<!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.3.30.RELEASE</version>
</dependency>
그리고 aspectJ에서 지원하는 weaber 또한 필요로 한다.
<!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.14</version>
<scope>runtime</scope>
</dependency>
아래의 코드로 예를 들어본다면, Student클래스내에 각 메서드들의 실행 시작과 실행 후에 Bell클래스의 메서드인 startBell(), endBell()실행하도록 만들어봄으로써 AOP를 이해할 수 있다.
package test;
public class Student {
public void study1() { //영어시간
// System.out.println("♬ 시작 종"); //종이 울리는 것은 학생과 관련된 기능이 아님!!! 그리고 중복된다.
System.out.println("1교시는 영어시간이에요");
}
public void study2() {//국어시간
System.out.println("2교시는 영어시간이에요");
}
public void study3() {//물리시간
System.out.println("3교시는 물리시간이에요");
}
public void study4() {//수학시간
System.out.println("4교시는 수학시간이에요");
}
}
package test;
public class Bell {
public void startBell() {
System.out.println("♬ 시작 종");
}
public void endBell() {
System.out.println("♬ 종료 종");
}
}
<!-- 학생과 벨을 엮어보자(weaving) -->
<!-- AOP를 이용하기 위해서는, 공통로직 즉 횡단적 관심사항을 등록한다!! -->
<bean id="bell" class="test.Bell"/>
<!-- 어떤 시점에, 어떤 객체에게 횡단점 관심사항을 적용할지 xml태그로 서술한다..
즉 프로그램 코드가 아닌 xml과 같은 설정파일에서 구현하는 방법을 선언적이라한다..
-->
<aop:config>
<aop:aspect id="bellAspect" ref="bell">
<!-- 어떤 시점에 벨이 관여할지를 결정 -->
<!-- test..*(..) 테스트 패키지 아래의 모든 클래스의 모든 메서드 -->
<aop:pointcut expression="execution(public * test.Student.*(..))" id="bellpointcut"/>
<aop:pointcut expression="execution(public * test.Dog.*(..))" id="pointcutToDog"/>
<!-- 공통기능 동작을 언제 할지, 즉 학생의 동작 이전에 적용, 이후에 동작시킬지.. -->
<aop:before method="startBell" pointcut-ref="bellpointcut"/>
<aop:after method="endBell" pointcut-ref="bellpointcut"/>
<aop:before method="startBell" pointcut-ref="pointcutToDog"/>
<aop:after method="endBell" pointcut-ref="pointcutToDog"/>
</aop:aspect>
</aop:config>
<bean id="student" class="test.Student"/>
<bean id="dog" class="test.Dog"/>
Bell클래스의 인스턴스가 Student의 메서드들의 실행을 관찰하고 있다고 생각하면 쉬운 것 같다.
'프로그래밍 > Spring' 카테고리의 다른 글
Spring - ServletContext 쉽게 가져오기 (0) | 2021.01.05 |
---|---|
Spring | collection & association (0) | 2020.12.24 |
Spring - DI (0) | 2020.12.22 |