The Debugging Chronicles : "코드의 미학"
[Spring] AOP(Aspect Oriented Programming) 관점 지향 프로그램 - 2 본문
IoC ====> 결합도를 낮추고
AOP ====> 응집도가 높다
스프링은 유지보수 용이하다!!!
AOP 적용은 쉽다.
설정대로 하라는 대로 하면 된다.
하지만 용어에 초점을 맞추어 봐야한다.
핵심관심, 비즈니스, CURD를 분리해준다.
Advice란?
== 횡단 관심
== 공통 로직
로그를 찍는 공통 로직.
로그는 CRUD가 잘 수행되어서 잘 진입해는지 확인하기 위해 찍는다.
개발자 new 하지 않는다
멤버변수로 만들어 주입한다.
어노테이션 주입
그런데 로그를 모든 곳에 찍어야 한다면?
로그 성능을 업데이트 해야한다면?
객체지향프로그래밍(OOP)의 한계
; Advice를 교체할때 코드가 많이 변경되므로 개발시간, 컴파일 비용이 많이 필요해진다.
해결 방법
>> 스프링 컨테이너야.
너 객체 생성 및 관리 할수 있잖아?
네가해줘라!!
Advice 의 메서드(공통 로직)를 제시간에 호출해줘라~
==> 관점 지향 프로그래밍 (AOP)
AOP를 해보자.
1. Dependency 주입
aop를 스프링 라이브러리에 추가한다.
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
</dependency>
2. 스키마 추가
의존성을 이해하기 위해 스키마 추가
<?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/aop
http://www.springframework.org/schema/aop/spring-aop-4.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.2.xsd">
3. Bean 태그 추가
스프링 컨테이너에 제때 알아서 호출되려면 메모리에 있어야한다.
메모리에서 불러오려면 Bean태그를 사용해야한다.
4.AOP 설정 파일 추가
제때 호출하기 위해 AOP 설정 파일이 필요하다
크게 두가지 부분으로 나뉘는데
1.어떤 무슨 핵심관심에 대해서
2. 언제 어떤 공통로직을 호출해야하는지
1.어떤 핵심관심에 대해서 => Pointcut
= = 포인트컷
== 핵심관심,CRUD,비즈니스메서드
execution(* com.koreait.app.biz.board..*Impl.*(..))
3부분으로 나뉜다
out 부분 - 타입의 무관하게
메서드 부분 - com.koreait.app.biz내부 안에 모든 메서드를 지금 부터
input 부분 - 개수, 타입이 무관하다는 뜻에서 점이 두개 찍어 있다.
aPointcut에서
CRUD모두다
bPointcut에는 R만
2. 언제 어떤 공통로직을 호출해야하는지
Aspect(Advisor, 어드바이저)
== 에스팩트
== 어드바이스 + 포인트컷
== 어드바이스(공통로직) 과 포인트컷 (핵심 관심)의 결합
>>>실무에서는 설정 그 자체를 의미하는 경우가 많음
ref= 객체명을 써준다
log advice랑 결합할꺼야
핵심 관심 후에
핵심관심 반환후에
핵심관심 에러 반환후
핵심관심 전후에
핵심관심 전에
결합 완료!!
Joinpoint
== 조인포인트
== 포인트컷 후보(포인트컷이 될 수 있는 대상)
== 모든 CRUD를 의미함
Weaving
== 위빙
== 핵심 관심에 공통로직을 끼워 넣는 과정
== 스프링에서는 실행 시 위빙처리가 수행됨
== 런타임 위빙 방식
(스프링에서는 실행되야지만 처리가 된다.)
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.3.4</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>day058_1001_01</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<name>day058_1001_01</name>
<description>Demo project for Spring Boot</description>
<url/>
<licenses>
<license/>
</licenses>
<developers>
<developer/>
</developers>
<scm>
<connection/>
<developerConnection/>
<tag/>
<url/>
</scm>
<properties>
<java.version>21</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.33</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
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.koreait.app.biz.board" />
<context:component-scan base-package="com.koreait.app.biz.member" />
<bean class="com.koreait.app.biz.common.LogAdvicePlus" id="la" />
<aop:config>
<aop:pointcut expression="execution(* com.koreait.app.biz..*Impl.*(..))" id="aPointcut" />
<aop:pointcut expression="execution(* com.koreait.app.biz..*Impl.select*(..))" id="bPointcut" />
<aop:aspect ref="la">
<aop:before pointcut-ref="aPointcut" method="teemo" />
</aop:aspect>
</aop:config>
</beans>
LogAdvice.java
package com.koreait.app.biz.common;
public class LogAdvice {
public void printLog() {
System.out.println("공통 관심 - 로그 : 비즈니스 메서드 수행 전에 호출됨");
}
}
LogAdvicePlus.java
package com.koreait.app.biz.common;
public class LogAdvicePlus {
public void teemo() {
System.out.println("향상된 로그 ^_^");
}
}
'Spring' 카테고리의 다른 글
[Spring] AOP 관점 지향 프로그램 어노테이션 설정 - 1 (0) | 2024.10.16 |
---|---|
[Spring] "00님이 DB에 글을 등록했습니다" 로그 AOP로 설정하기 (0) | 2024.10.15 |
[Spring] AOP(Aspect Oriented Programming) 관점 지향 프로그램 - 1 (1) | 2024.10.15 |
[Spring]@RequestBody vs @RequestParam (0) | 2024.10.15 |
[Spring] 비동기 검색창 (0) | 2024.10.14 |