https://github.com/chaSunil/FirstProject/tree/practice
보안처리, 수행시간을 구하는 작업에 탁월하다.
Spring 기술중에서 아주 핵심적인 기술
객체지향 프로그래밍 (Object Oriented Programming) OOP를 보완하는 개념으로 어플리케이션을 객체지향적으로 모듈화 하여 작성하더라도 다수의 객체들에 분산되어 중복적으로 존재하는 공통 관심사가 여전히 존재한다.
AOP는 이를 횡단관심으로 분리하여 핵심관심과 엮어서 처리할 수 있는 방법을 제공한다.
로깅작업(개발자의 편의를 위해서 해당하는 날짜에 무슨 작업을 했는지 기입)에 AOP작업은 핵심적으로 쓰인다.
- 아래의 객체지향 개발안에 들어가 있는 여러가지 컬러들은 공통관심사이다. 공통관심사란, 각각의 모든 Method에서 활용되는 객체들을 의미한다. (디버깅 하기 위해서 각각의 Method에 수행시간을 체크할때)
Pointcut : 감시지점 설정(c 클래스의 어디 Method 지점)
before Advice 이 Method가 실행되기 전에 통보해라(start 시간)
after Advice 이 Method가 실행되고 끝난뒤에 통보해라(end 시간) -> 수행시간을 구할 수 있다.
Server가 갑자기 느려졌을때 어느 부분에서 느려졌느지 수행시간을 통해서 check하여, 느려진 부분을 구할 수 있다.
- 기존에 Method의 수행시간을 알기위해서 check하는 수기적인 방법
- 만약 Method의 수행시간을 체크해야하는 Method가 100개라면?? 일일이 이 과정을 100번 넣어주어야 한다는것.
- 디버깅 하기 위해서 수행시간 체크하기 위해서 사용하는 것 (공통 관심사)이 많아지면, 코드 가독성도 떨어질뿐더러, 일일이 기입 해줘야하는 작업들이 번거로운 것이다.
-허나, Pointcut을 만들어주면, 이 수행시간을 일일이 구하는 방법을 사용하지 않고도 수월하게 구할 수 있다.
-AOP(관점지향 프로그래밍) 기술을 사용하면, Method를 호출하기전에 로그인이 필요하다면, session을 체크한 뒤, 돌려보내는 작업 등등을 수행해준다. 로그인 후에 진입할 수 있는 Method 처리를 해준다는 것이다. (보안처리)
JoinPoint 감시지점 (c 클래스의 어디 Method 지점, 결과물)을 포장해서 Advice에게 전달
Weaving : JoinPoint -> Advice에 전달되는 과정
Advice : 공통관심사를 모아놓은 객체
- account에 해당하는 모든 것들을 Pointcut을 걸어놓겠다. (파랑색 원)
- Repository(Dao)에 해당하는 모든 객체들을 Pointcut을 걸어놓겠다. (붉은색 원)
장점
– 중복 코드의 제거
• 횡단 관심(CrossCutting Concerns)을 여러 모듈에 반복적으로 기술되는 현상을 방지
– 비즈니스 로직의 가독성 향상
• 핵심기능 코드로부터 횡단 관심 코드를 분리함으로써 비즈니스 로직의 가독성 향상
– 생산성 향상
• 비즈니스 로직의 독립으로 인한 개발의 집중력을 높임
– 재사용성 향상
• 횡단 관심 코드는 여러 모듈에서 재사용될 수 있음
– 변경 용이성 증대
• 횡단 관심 코드가 하나의 모듈로 관리되기 때문에 이에 대한 변경 발생시 용이하게 수행할 수 있음
기존 환경설정과 동일(최신 파일은 구글 드라이브에)
새로운 라이브러리 추가(AOP 사용에 필요한 라이브러리)
aopalliance
aopalliance
1.0
<!-- https://mvnrepository.com/artifact/aopalliance/aopalliance -->
<dependency>
<groupId>aopalliance</groupId>
<artifactId>aopalliance</artifactId>
<version>1.0</version>
</dependency>
org.aspectj
aspectjweaver
1.6.11
<!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.6.11</version>
<scope>runtime</scope>
</dependency>
cglib
cglib
2.2
<!-- https://mvnrepository.com/artifact/cglib/cglib -->
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>2.2</version>
</dependency>
aop를 context에 추가하기
<!-- 공통 관심사항이 구현된 Advice객체 생성 -->
<bean id="advice" class="advice.Advice" />
<!-- AOP설정 : Target객체의 모든 메서드에 Advice에 구현된 공통기능을 적용한다. -->
<aop:config>
<aop:pointcut expression="execution(public * target.Service.*(..))"
id="myPoint" />
<aop:aspect id="test" ref="advice">
<aop:before method="before" pointcut-ref="myPoint" />
<aop:after method="after" pointcut-ref="myPoint" />
</aop:aspect>
</aop:config>
advice 추가하기
Repository Dao 만들기
TestService 만들기
context-3-dao.xml 생성하기
context-4-service.xml 생성하기
Controller 생성하기
package controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import service.TestService;
@Controller
public class TestController {
@Autowired
TestService test_service;
@RequestMapping("/")
public String sido_list(Model model) {
List<String> list = test_service.sido_list();
model.addAttribute("list",list);
return "text";
}
}
context-7-aop의 연결 경로에 따라서 pointCut을 변경시킬 수 있다.
(public * service package안에 있는.*TestService라는 이름을 가지고 있는.sido_list()를 가지고 매개변수가 없는 메서드)
sido_list(..)을 기입하면 매개변수가 무엇이든 들어가 있어야 한다.
수행 시간을 advice에서 지정해보자.
package advice;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
public class Advice {
long start = 0;
public void before(JoinPoint jp){
Signature s = jp.getSignature();
start = System.currentTimeMillis();
System.out.println("----before:" + s.toString());
}
public void after(JoinPoint jp){
Signature s = jp.getSignature();
long end = System.currentTimeMillis();
System.out.println("----after:" + s.toString());
System.out.printf("수행시간 : %d(ms)\n", end-start);
}
}
유저가 동시다발적으로 refresh를 하면 수행시간이 일정하지 않고, 비규칙적으로 호출이된다.
- 그래서, 정확한 호출시간을 위해서면 요청자가 본인만 사용할 수 있는 값을 넣어놓아야 한다.
request의 특징이 특정 유저가 요청할 때마다 생기는 임시 객체이다. 이를 활용해서 특정 유저만 사용할 수 있게 만들어 주어야 한다.
- DispatcherServlet에게 request를 요청한다.
package advice;
import javax.servlet.http.HttpServletRequest;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.springframework.beans.factory.annotation.Autowired;
public class Advice {
@Autowired
HttpServletRequest request;
public void before(JoinPoint jp){
Signature s = jp.getSignature();
long start = System.currentTimeMillis();
request.setAttribute("start", start);
System.out.println("----before:" + s.toString());
}
public void after(JoinPoint jp){
Signature s = jp.getSignature();
Long start = (Long) request.getAttribute("start");
long end = System.currentTimeMillis();
System.out.println("----after:" + s.toString());
System.out.printf("수행시간 : %d(ms)\n", end-start);
}
}
'SpringBoot↗' 카테고리의 다른 글
Spring)RMI (0) | 2024.08.07 |
---|---|
Spring)Transaction - AOP (0) | 2024.08.06 |
Spring)Rest API로 CRUD 정보 처리하기 (0) | 2024.08.05 |
Spring) ckEditor 사용법 / JSON으로 쉽게 변환시켜서 사용하기 (0) | 2024.08.05 |
★(@Scheduled) 실시간으로 거래 시간이 마감되었는지 check 해주는 로직 (실시간 데이터 갱신) (0) | 2024.08.02 |