일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
- 웹브라우저 수용도
- html
- SQL
- 숫자 형식
- 웹 브라우저 전쟁
- DoIt
- 자바 예외
- 예제
- 크롤링 오류
- 데이터베이스
- Doit입문SQL
- DoitSQL
- 우아한테크
- 예외
- HTML역사
- 크롤링
- 키-값 데이터베이스
- dbms
- 자바
- 함수 선언
- SQL입문
- 자바 오류
- R1C3
- 배열 3요소
- 숫자형식오류
- 페이지분석
- 배열 예제
- 함수
- DoitSQL입문
- 생성자
- Today
- Total
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
- 웹브라우저 수용도
- html
- SQL
- 숫자 형식
- 웹 브라우저 전쟁
- DoIt
- 자바 예외
- 예제
- 크롤링 오류
- 데이터베이스
- Doit입문SQL
- DoitSQL
- 우아한테크
- 예외
- HTML역사
- 크롤링
- 키-값 데이터베이스
- dbms
- 자바
- 함수 선언
- SQL입문
- 자바 오류
- R1C3
- 배열 3요소
- 숫자형식오류
- 페이지분석
- 배열 예제
- 함수
- DoitSQL입문
- 생성자
- Today
- Total
프로그래밍
[Spring] day66 : AOP(관점 지향 프로그래밍) 본문
2023.08.10.목
AOP
AOP는 Aspect Oriented Programming의 약자로 관점 지향 프로그래밍이다
기존에는 OOP, 즉,객체지향 프로그래밍 방식을 사용하였는데
보다 높은 응집도를 위해 AOP 방식을 사용해보도록 하자
현재 로그인 로직은 다음과 같다
1. 로그 출력(객체 확인)
2. 수행할 메서드의 보안 / 인증 / 허가(API) 확인(권한 확인 / 인가 확인)
3. 비즈니스 메서드 실행
4. 관제 로그 작성
※ 컴퓨터가 모든 수행을 기록에 남긴다. 그걸 관제식이라고 하며 관제 로그라고 한다
Controller 메서드
1.(개발자용) 로그
2. 권한 확인 : 보안, 인증, 허가
3. 비즈니스 메서드(CRUD, 핵심 로직, 핵심 관심)
4. 트랜잭션, 보안 관제 로그, ....
비즈니스 메서드가 달라졌는데(사용자의 요청이 달라졌는데)
결론적으로 "진짜" 변경되는곳은 3번밖에 없다 (1,2,4는 계속 사용)
관심 분리
"관심 분리(Separation of Concerns)"
관심== 로직
1,2,4: 공통 로직, 횡단 관심(어딜가도 실행 /가로지르는 로직)
3: 핵심 관심, 핵심 로직, 비즈니스 메서드
우리는 횡단관심과 핵심관심을 분리하는 관심분리를 할것이다
AOP 용어 정리
1. Advice 어드바이스
: 횡단 관심
: 공통 로직
동작 시점을 설정할 수 있다
(비즈니스 메서드 기준으로 전/후/함께/.....)
컨트롤러에서 조합하지 않고 서비스레이어에서 진행
2. PointCut 포인트컷
: 핵심 관심, 핵심 로직, 비즈니스 메서드. CRUD
공통 로직인 Advice가 결합될 대상
3. Aspect 애스팩트(Advisor 어드바이저)
: 포인트컷 + 어드바이스
포인트컷과 어드바이스의 "결합" 그 자체를 의미
애스팩트 설정에 따라 위빙이 처리됨
4. Weaving 위빙
포인트컷으로 작성한 핵심 관심 메서드가 호출될때
어디바이스에 해당되는 횡단 관심 메서드가 삽입되는 과정 그 자체를 의미
스프링은 런타임 위빙 방식을 사용함
5. JointPoint 조인 포인트
: 포인트컷 후보
포인트컷이 될 수 있는 대상들
== 핵심 관심들
관심 분리 예제
먼저 pom.xml에 AOP를 위한 의존성을 추가한다
<!-- AOP -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>${org.aspectj-version}</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.8</version>
</dependency>
applicationContext.xml namespace -> AOP 추가
xmlns:aop="http://www.springframework.org/schema/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:context="http://www.springframework.org/schema/context"
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/context http://www.springframework.org/schema/context/spring-context-4.2.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd">
<context:component-scan base-package="com.spring.biz" />
</beans>
applicationContext.xml에 추가하는 이유는
Controller의 로직과 소통할 확률이 높기 때문이며
불러내는 시점이 사용자 요청 직후이기 때문이다
또한 AOP 설정 완료되는 시점이
사용자 *.do를 하는 시점보다 더 먼저여야 하기 때문에
루트 컨테이너로 등록된 applicationContext.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:context="http://www.springframework.org/schema/context"
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/context http://www.springframework.org/schema/context/spring-context-4.2.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd">
<context:component-scan base-package="com.spring.biz" />
<!-- new를 컨테이너가 대신 수행 -->
<bean id="logAdvice" class="com.spring.biz.common.LogAdvice"></bean>
<bean id="aroundAdvice" class="com.spring.biz.common.AroundAdvice"></bean>
<!-- AOP 설정 -->
<aop:config>
<!-- execution(OUTPUT FUNCTION(INPUT)) -->
<!-- *은 하나 .. 은 갯수도 무관 -->
<aop:pointcut expression="execution(* com.spring.biz..*Impl.*(..))" id="aPointcut"/>
<aop:pointcut expression="execution(* com.spring.biz..*Impl.select*(..))" id="bPointcut"/>
<!-- logAdvice와 결합 -->
<aop:aspect ref="logAdvice">
<!-- aPointcut 수행"전에" printLog 메서드 호출 -->
<aop:before method="printLog" pointcut-ref="aPointcut"/>
<aop:after method="printLogSelect" pointcut-ref="bPointcut"/>
</aop:aspect>
</aop:config>
<aop:config>
<aop:pointcut expression="execution(* com.spring.biz..*Impl.*(..))" id="cPointcut" />
<aop:pointcut expression="execution(* com.spring.biz..*Impl.select*(..))" id="dPointcut" />
<aop:aspect ref="aroundAdvice">
<aop:around method="aroundPrintLog" pointcut-ref="dPointcut" />
</aop:aspect>
</aop:config>
</beans>
XML을 안보면 AOP가 존재하는지도 모른다
장점: 정말 해당 핵심 로직만이 보인다
단점: 설정 확인하려면 XML을 열어 확인해야 한다
서비스를 사용하지 않는 메서드는 로그가 작성되지 않는다
(단순 페이지 이동과 같은 건)
→ 메서드 호출시 연산 속도가 더 느려지기 때문에 더 가볍고 빠르게 페이지 이동이 가능하다
https://github.com/jihyean/Spring/tree/main/day66
'자바 > Spring' 카테고리의 다른 글
[Spring] day68 : JDBC Template (0) | 2023.08.17 |
---|---|
[Spring] day67 : AOP 예제(+바인드 변수) (0) | 2023.08.16 |
[Spring] day64 : 2-Layerd 아키텍처 스타일 (1) | 2023.08.14 |
[Spring] day63 : 테스트계정 / 검색 예제 (3) | 2023.08.13 |
[Spring] day61 : Command 객체 (0) | 2023.08.13 |