본 글은 주관적으로 이해하기 위해 작성된 글입니다.
혹시 틀린 부분이 있을 수도 있습니다.
지적해주시거나 남겨주시면 감사히 반영하도록 하겠습니다.
🔹 : JAVA 파일
🔸 : xml 파일
💬 : 멘트
문득 궁금했다.
회사 프로젝트에서 mapper
부분에 @SessionLogin
이라는 어노테이션을 만들어 사용하시는 것을 보고 어떤 원리로 로그인 정보들이 담겨오는지 궁금했다.
@SessionLoginId
public int aaa(VO vo) ;
@SessionLoginId
public int bbb(VO vo ;
어노테이션(@ : annotation)
출처 : 넥스트리.io
과일에 붙는 라벨지
와 비슷하다고 예시 글을 본 적 있다.- 실행하는 곳에 라벨지를 붙여서 해당 라벨지를 통해 다른 메서드를 실행해서 정보들을 담을 수도 있고 넣어줄 수도 있다.
- 회사에서는
로그인을 하면 해당 사용자 정보를 불러오는 SET하여 담아주는
어노테이션을 선언했다.
가장 먼저 @SessionLogin
를 import
해오는 경로를 찾아가 보았다.
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface SessionLoginId {
}
💬
??? 진짜 이게 다야?
🔥 여기서 알게된 사실
@interface
로 어노테이션 클래스를 만들 수 있다.@Target
으로필드, 메소드, 클래스, 파라미터
등 선언할 수 있는 타입을 설정.@Retention
으로어느 시점까지 어노테이션의 메모리를 가져갈 지
설정.@Documented
는 어노테이션을 사용하는 클래스가 javadoc과 같은 문서화 될 때,
해당 어노테이션이 적용되었음을 명시함.
💬
해당 어노테이션을 어디서 다루는지 찾아보아야 했는데 어디에도 없었다...
그래서 자문을 구해보니, 해당@sessionLogin
클래스를 import 해서 사용하는 부분을 알 수 있었다.
import ...........anotation.SessionLoginId;
해당 파일에서는 SessionLoginId.class를 import 선언!
...... if( .getAnnotation(SessionLoginId.class) == null ){
return 종료;
}
로그인이 되어있다면, 정보를 다른 vo객체에 set하여 가져오는 방식이었다.
그렇지 않다면, return으로 해당 메서드를 로그인 정보를 담지 않고 종료시키게 된다.
💬
결국 어노테이션의 역할은공통적인 메서드를 실행시켜야 한다면
원하는 곳에 라벨처럼 붙어 해당 메서드를 실행시키게 해주는 역할인가 보다.그럼 왜 저 메서드는 어떻게 실행되는 거지?
라고 생각했을 때,servlet(서블릿)
에서 따로 커스터마이징 하여 동작한다는 주임님의 말씀이 있었다.
servlet(서블릿)
- 자바 서블릿은 자바를 사용하여 웹페이지를 동적으로 생성하는
서버측 프로그램 혹은 그 사양
을 말하며, 흔히 "서블릿"이라 불린다.- 자바 서블릿은 웹 서버의 성능을 향상하기 위해 사용되는
자바 클래스의 일종
이다.
💬
서블릿을 접근하면 Spring의 실행 순서에 대해서 잘 파악해야한다.
사진 출처 : ↗전디버거의 코딩이야기
💬
그림의 구조를 보면 View ➡ DispatcherServlet로 갔다.
DispatcherServlet는web.xml
에 포함되어 있다 하는데
web.xml
에는 다음과 같은 코드가 있었다.
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath*:egovframework/spring/context-*.xml
</param-value>
</context-param>
💬
정리하면,
Spring이 실행
➡ web.xml 구동
➡ web.xml의 코드 실행
➡ 위의 코드인 해당 경로의context-*.xml
이 다 실행 ‼이거다.
다시 거슬러 올라가 그럼resources/egoframwork/spring/context-*.xml
파일들을 확인해보았다.
바로 아까보았던 🔹 MapperSessionLogin.class
가 여기 선언되어 있었다.
<aop:config>
// pointcut : mapper에서 pointcut ( mapper에서만 동작하라는 뜻 )
<aop:pointcut id="mapperMethod" expression="execution(* 경로..mapper.*Mapper.*(..))" />
// aspect : mapperMethod 전에 실행
<aop:aspect ref="MapperSessionLogin">
<aop:around pointcut-ref="mapperMethod" method="before" />
</aop:aspect>
</aop:config>
// 해당 경로를 bean 설정(import같은?)
<bean id="MapperSessionLogin" class="경로.MapperSessionLogin" />
💬
간단하게 이해 한것을 주석으로 표현해보았지만, 확답은 아닐 것이다.
이를 이해하려고 하면 aop 라는 것을 알아보아야 했다.
AOP(관점 지향 프로그래밍)
출처: 새로비
어떤 로직을 기준으로 핵심적인 관점, 부가적인 관점으로 나누어서 보고 그 관점을 기준으로 각각 모듈화하겠다는 것이다.
Aspect
: 위에서 설명한 흩어진 관심사를 모듈화 한 것. 주로 부가기능을 모듈화함.Target
:Aspect
를 적용하는 곳 (클래스, 메서드 .. )Advice
: 실질적으로 어떤 일을 해야할 지에 대한 것, 실질적인 부가기능을 담은 구현체.JointPoint
:Advice
가 적용될 위치, 끼어들 수 있는 지점. 메서드 진입 지점, 생성자 호출 시점, 필드에서 값을 꺼내올 때 등 다양한 시점에 적용가능.PointCut
:JointPoint
의 상세한 스펙을 정의한 것. 구체적으로Advice
가 실행될 지점을 정할 수 있음.
➡ : 실행 순서
💨 : 명령
Spring 실행
➡ 🔸 web.xml
실행중 (💨 🔸 context-*.xml
모두 실행)
➡ 🔸 context-aspect.xml
실행중 (💨 선언된 aop에 따라 🔹 MapperSessionLogin.class
수행 )
➡ 🔹 MapperSessionLogin.class
실행되게 aop 적용 (🔹 sessionLogin.class
포함)
@sessionLogin 포함된 mapper 실행
➡ aop로 정의되어 🔹 MapperSessionLogin.class
동작
➡ .getAnnotation(sessionLogin.class) == null
로 로그인 유무 체크
➡ 존재하면 로그인 정보가 담긴 VO 객체에 set
하여 map형식으로 기존에 담길 vo객체에 합쳐
서 sql로 내려줌
💬
사용방법은 명시되어 있지 않아 이해하기 어렵겠지만
어떤식으로 어노테이션이 활용되는지 간략하게 적어보았습니다.