AOP란
더보기
AOP (API) - 방법론
- AOP를 구현할때 스프링이 도움을 줌
- 스프링이 지원해주는 범주 내에서 AOP 방법론으로 프로그램을 만들게 되면 어떤 도움을 받을 수 있을까 ?
Aspect Oriented Programming (AOP)
사용자 -> 주 업무 로직
- 기존엔 사용자가 원하는 업무 기반의 로직만 관심만 가졌음
- 프로그램을 만들땐 사용자의 업무를 분석하고, 거기에 대한 로직을 구현하려고 많은 서비스를 구현했다.
- 사실 느끼지못한 코드가 여기에 들어갔음
- 사용자 요구사항말고 이것을 수반하기위해 작성하다보니까 그 외의 코드가 들어가게됨.
- 코드 : 사용자가 요구했던 업무적인게 아니라,
- 개발자/관리자가 프로그램을 구현하기 위해서든 테스트하기 위해서든 필요한 코드들이 존재하게 됨.
- 이러한 코드들은 주 업무 로직에 필요한 코드들이 아니라 개발자/관리자가 필요에 따라 코드들을 껴놓은것
- 사용자는 이런걸모름 만들라고 한적 없음.
- 이건 개발자/운영자가 자신들이 쓰기위해 껴놓는 부가적인 코드들임
- 이것을 보조업무라고 표현한다.
- 주 업무만 대우해줬지만 개발자/운영자가 넣게되는 코드들도 관점이 다른 업무라고 봄
- 사용자 관점으로 봤떤것이 지금까지 객체지향으로 잘 만들어 졌다면, 추가로 만들게 되는 로직을 개발자/운영자 관점에서 넣어야하는 로직이 있어야함.
- 이걸 관점 지향 업무라 함. (객체지향보다 큰 개념) - 주 업무 로직 : 객체지향, 그 외의 것까지 포함 : 관점 지향
AOP를 하기위한 구성
- AOP API를 Maven에 등록
- porm.xml
- 파일 구성
- resource : appCTX.xml
- java : Worker, Student, LogAop, MainClass.java
- AOP 용어
Aspect : 공통 기능
Advice : Aspect의 기능 자체 JoinPoint Advice를 적용해야 되는 부분(ex 필드..)
Pointcut : joinpoint의 부분으로 실제로 Advice가 적용된 부분
Weaving : Advice를 핵심 기능에 적용 하는 행위
- AOP 태그 종류
<aop:before> : 메소드 실행 전에 advice 실행
<aop:after-returning> : 정상적으로 메소드 실행 후에 advice 실행
<aop:after-throwing> : 메소드 실행중 exception 발생시 advice 실행
<aop:after> : 메소드 실행중 exception이 발생하여도 advice 실행
<aop:around> : 메소드 실행 전/후 및 exception 발생시 advice 실행
- porm.xml에 AOP api 등록
<!-- AOP -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.7.4</version>
</dependency>
데이터 클래스 생성
- Student, Worker (java)
student.java
package com.javalec.ex;
public class Student {
private String name;
private int age;
private int gradeNum;
private int classNum;
public void getStudentInfo() {
System.out.println("이름 : " + getName());
System.out.println("나이 : " + getAge());
System.out.println("학년 : " + getGradeNum());
System.out.println("반 : " + getClassNum());
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public int getGradeNum() {
return gradeNum;
}
public void setGradeNum(int gradeNum) {
this.gradeNum = gradeNum;
}
public int getClassNum() {
return classNum;
}
public void setClassNum(int classNum) {
this.classNum = classNum;
}
}
Worker.java
package com.javalec.ex;
public class Worker {
private String name;
private int age;
private String job;
public void getWorkerInfo() {
System.out.println("이름 : " + getName());
System.out.println("나이 : " + getAge());
System.out.println("직업 : " + getJob());
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getJob() {
return job;
}
public void setJob(String job) {
this.job = job;
}
}
메인 클래스 생성(출력하기 위한 클래스)
MainClass.java
package com.javalec.ex;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.GenericXmlApplicationContext;
public class MainClass {
public static void main(String[] args) {
AbstractApplicationContext ctx
= new GenericXmlApplicationContext("classpath:appCTX.xml");
Student student = ctx.getBean("student", Student.class);
student.getStudentInfo();
Worker worker = ctx.getBean("worker", Worker.class);
worker.getWorkerInfo();
}
}
본격적인 AOP 사용 부분 클래스와 xml
appCTX.xml
- namespace -> aop 체크
구조
// AOP
// 주 업무 (메인 코드)
// AOP
<?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-3.1.xsd">
<!-- 공통기능 stu하고 work에 똑같이 적용시키고 싶음. LogAop 의 loggerAop 메소드-->
<bean id="logAop" class="com.javalec.ex.LogAop"></bean>
<aop:config >
<aop:aspect id ="logger" ref="logAop">
<aop:pointcut expression="within(com.javalec.ex.Student)" id="publicM"/>
<aop:around method="loggerAop" pointcut-ref="publicM"/>
</aop:aspect>
<aop:aspect id="logger" ref="logAop">
<aop:pointcut expression="within(com.javalec.ex.*)" id="publicM" />
<aop:before method="beforeAdvice" pointcut-ref="publicM" />
</aop:aspect>
<aop:aspect id="logger" ref="logAop">
<aop:pointcut expression="within(com.javalec.ex.*)" id="publicM" />
<aop:after-returning method="afterReturningAdvice" pointcut-ref="publicM" />
</aop:aspect>
<aop:aspect id="logger" ref="logAop">
<aop:pointcut expression="within(com.javalec.ex.*)" id="publicM" />
<aop:after-throwing method="afterThrowingAdvice" pointcut-ref="publicM" />
</aop:aspect>
<aop:aspect id="logger" ref="logAop">
<aop:pointcut expression="within(com.javalec.ex.*)" id="publicM" />
<aop:after method="afterAdvice" pointcut-ref="publicM" />
</aop:aspect>
</aop:config>
<bean id="student" class="com.javalec.ex.Student">
<property name="name" value="ppp" />
<property name="age" value="10" />
<property name="gradeNum" value="1" />
<property name="classNum" value="3" />
</bean>
<bean id="worker" class="com.javalec.ex.Worker">
<property name="name" value="pep" />
<property name="age" value="15" />
<property name="job" value="stu" />
</bean>
</beans>
LogAop.java
// AOP
proceed(); // 핵심기능을 부르는 것임.
// AOP
package com.javalec.ex;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
public class LogAop {
public Object loggerAop(ProceedingJoinPoint joinpoint) throws Throwable{
String signatureStr = joinpoint.getSignature().toShortString();
System.out.println( signatureStr + "is start ");
long st = System.currentTimeMillis();
try {
Object obj = joinpoint.proceed(); // 핵심 기능
return obj;
}finally {
long et = System.currentTimeMillis();
System.out.println(signatureStr + "is finished");
System.out.println(signatureStr + "경과시간 : " + (et - st));
}
}
public void beforeAdvice(JoinPoint joinPoint) {
System.out.println("beforeAdvice()");
}
public void afterReturningAdvice() {
System.out.println("afterReturningAdvice()");
}
public void afterThrowingAdvice() {
System.out.println("afterThrowingAdvice()");
}
public void afterAdvice() {
System.out.println("afterAdvice()");
}
}
반응형
'자바과정 > 스프링' 카테고리의 다른 글
스프링 AOP (Annotation 방식과 Pointcut 종류) (0) | 2021.04.08 |
---|---|
스프링 AOP(자바 방식, Spring XML 방식) (3) | 2021.04.08 |
스프링 실습 예제(Profile, Environment 사용) (0) | 2021.04.07 |
스프링 실습 예제(static과 load로 외부 데이터 2개) (0) | 2021.04.07 |
스프링 실습 예제 (외부 데이터 사용) (0) | 2021.04.07 |
댓글