의존성(Dependency) 주입
Dependency Lookup
스프링 컨테이너가 생성한 객체를 컨데이너 외부에서 검색(Lookup)하는 과정
Dependency Injection
- 객체 사이의 의존관계를 스프링 설정 파일에 등록된 정보로 컨테이너가 자동 처리
- 의존관계를 변경하고 싶을 때 자바 코드를 수정하지 않고 메타 데이터만 수정하여 유지보수에 좋음
- Constructor Injection : <bean> 엘리먼트 사이에 <constructor-arg> 사용
- Setter Injection : 클래스에 setter() 메소드 생성, <bean> 엘리먼트 사이에 <property> 사용
- Type Injection : @Autowired 사용
Annotation 과 bean 사용
- 유지보수 과정에서 바뀌지 않는 코드라면 주로 annotation 사용하며, 바뀌는 경우가 있다면 bean 으로 등록한다. → 자바소스 건들이지 않고 xml 만 수정하여 적용 가능하기 때문에
- <bean> 등록이 싫으면 class 위에 @Component 작성 → Annotation 을 통해 컨테이너가 객체를 생성함.
의존성 주입 관련 어노테이션
- @Autowired (Type Injection) : 변수 위에 설정하여 해당 타입의 객체를 메모리에서 찾아 자동할당 (Spring)
- @Qualifier : 특정 이름의 객체를 주입할 때 사용 (거의 사용 x)
- @Resource (Type Injection) : 위 두개를 결합한 어노테이션 (전자정부표준 프레임워크에서 사용)
IoC를 이용한 비즈니스 컴포넌트 개발
- VO (Value Object) 클래스 작성
- 멤버변수 선언
- getter, setter 생성
- DAO (Data Access Object) 클래스 작성
- Extract Interface 생성 → Service 인터페이스 생성 및 implement 삭제
- @Repository 추가 (bean 생성이 귀찮다면)
- Service 인터페이스 작성
- Service 구현 클래스 작성
- ServiceImpl 구현
- userDAO 사용
- @Service 추가 (bean 생성이 귀찮다면)
- @Autowired 추가 (userDAO가 Repository 참조할 수 있도록)
@Component 어노테이션 구분
- @Service : 비즈니스 로직을 처리하는 Service 객체 (XXXServiceImpl 에 사용)
- @Repository : 데이터베이스 연동을 처리하는 DAO 객체 (XXXDAO)
- @Controller : 사용자 요청을 제어하는 Controller 객체 (XXXController)
AOP(Aspect Oriented Programming)
AOP 개념
AOP 이해에 가장 중요한 핵심 개념이 바로 관심분리(Seperation of Concerns) 이다.
- 핵심관심 (Core Concerns) : 실제로 수행되는 핵심 비즈니스 로직
- 횡단관심 (Crosscutting Concerns) : 비즈니스 메소드마다 공통으로 등장하는 코드들(로깅, 예외 등)
관심분리의 중요성으로 메소드를 구현할 때 횡단관심의 공통코드만 제거하면, 소스코드가 줄어들며 정책을 바꾸기가 쉽다. 분리된 관심을 적절하게 연결해주는 것이 AOP 의 역할이다.
AOP 설정
<aop:config> -- 루트
<aop:pointcut />
<aop:aspect />
</aop:config>
AOP 용어
총 5가지 중 2가지만 이해하면 된다 - Pointcut, Advice
- 조인포인트 : ServiceImpl 에 있는 모든 메소드
- 포인트컷
- 필터링된 조인포인트 / 필터링된 비즈니스 메소드
- 횡단관심이 내가 원하는 메소드에서만 동작할 수 있도록 하는 것
- 포인트컷 표현식
- 리턴타입 + 패키지경로 + 클래스명 + 메소드명 및 매개변수
- ex) * com.test..*Impl.*(..) / * com.test..board.*Impl.get*(..)
- 리턴타입
- * : 모든 반환형 허용
- void : 반환형이 void 인 메소드 선택
- !void : 반환형이 void 가 아닌 메소드 선택
- 패키지 경로
- com.test.. : com.test 패키지로 시작하는 모든 패키지 선택
- com.test..board : com.test 패키지로 시작하면서 마지막이 패키지 명이 board 패키지 선택
- 클래스명
- *Impl : 클래스 이름이 Impl로 끝나는 모든 클래스 선택
- 메소드명 및 매개변수
- get* : 메소드 이름이 get으로 시작하는 모든 메소드 선택
- (..) : 매개변수의 개수와 타입에 제약 없음
- (*) : 반드시 1개의 매개변수를 가지는 메소드만 선택
- 어드바이스(Advice)
- 횡단관심에 해당하는 공통 기능의 코드 자체를 의미
- 코드 자체를 의미하나 메소드 형태로 작성하기 때문에 메소드를 의미하기도 한다.
- 5가지 동작시점
- before
- after
- after-returning : 비즈니스 메소드의 리턴값을 받아서 사후처리 가능
- after-throwing : 예외가 발생하는 순간 동작 및 예외를 받음
- around : 사전/사후 처리, 클라이언트의 메소드 호출을 가로챔
- 리턴타입 : Object
- 매개변수 : ProceedingJointPoint
- 리턴타입과 매개변수가 위와 같이 정해져 있다.
- 위빙(Weaving)
- 핵심관심, 횡단관심을 적절히 삽입해주는 것
- 적절하게 결합되기(Weaving) 을 위해서는 애스팩트와 어드바이저가 필요
- 애스팩스(Aspect) or 어드바이저(Advisor)
- 포인트컷과 어드바이스 연결
- 위빙이 동작하기 위해서는 반드시 애스팩트 설정이 반드시 필요
- 애스팩트 = 포인트컷 + 어드바이스 결합
public class LogAdvice {
public void printLog() {
System.out.println("[로그] 비즈니스 로직 수행 전 동작");
}
}
<bean id="log" class="com.test.common.LogAdvice"></bean>
<aop:config>
<aop:pointcut id="allPointcut" expression="execution(* com.test..*Impl.*(..))"/>
<aop:pointcut id="getPointcut" expression="execution(* com.test..*Impl.get*(..))"/>
<aop:aspect reg="log">
<aop:before pointcut-ref="getPointcut" method="pringLog"/>
</aop:aspect>
</aop:config>
getPointcut 으로 필터링한 비즈니스 메소드가 호출될 때(1), log라는 어드바이스 객체(2)의 printLog 메소드가 실행되는데(3), 이때 printLog 메소드 동작 시점이 <aop:before>(4) 이다.
Advice 매개변수
클라이언트가 호출한 비즈니스 메소드의 정보가 필요하다. 스프링에서 JoinPoint 인터페이스를 제공한다.
- Signature getSignature() : 호출되는 메소드 시그니처(패키지 경로, 클래스 이름, 메소드 이름, 매개변서, 리턴타입) 정보를 포함하는 Signature 객체를 리턴
- Object[] getArgs() : 클라이언트가 비즈니스 메소드를 호출할 때 전달한 인자의 목록을 Object 배열로 리턴
주의할 점)
1. before / after / after-returning / after-throwing 어드바이스에서는 JoinPoint 사용하며,
around 어드바이스에서만 ProceedingJoinPoing 를 매개변수로 사용해야한다.
→ around 에서는 proceed 메소드가 필요하기 때문에
ProceedingJoinPoint 는 JoinPoin 를 상속 받고, proceed 메소드만 추가했다고 보면된다.
2. JoinPoint 와 ProceedingJoinPoing 모두 반드시 첫번째 매개변수로 선언되어야한다.
'IT > Spring' 카테고리의 다른 글
ViewResolver 적용하기 (0) | 2022.05.30 |
---|---|
포워드(Forward)와 리다이렉트(Redirect) 차이 (0) | 2022.05.26 |
Java Framework - Spring(4) : MVC 모델 (0) | 2022.05.19 |
Java Framework - Spring(3) : JDBC (0) | 2022.05.18 |
Java Framework - Spring (1) : 컨테이너 / IoC (0) | 2022.05.16 |
댓글