필자가 배운 내용을 정리하고자 함에 의의를 뒀으니 비유적인 표현이 많고 개념을 정의함에 있어서 정석적인 정의가 아님을 인식해주었으면한다.
피드백 절대환영!!!
필터라고 함은 흔히 무언가를 걸러내는 것일 것이다.
그렇다면 스프링에서의 필터도 무언가 걸러내는 역할일까? 맞다!
예를 들어, A나라와 B나라가 전쟁 중이라고 하자.
A나라의 성이 있고(톰캣), 이 성에 B나라 사람들이 잠입하지 못하도록 필터(web.xml)로 걸러내야 할 것이다.
그리고 성 안에는 왕이 거주지(스프링 컨테이너)가 있을 것인데, 이 성을 통과했다쳐도 왕의 거주지에 방문하려면 A나라 사람이라도 아무나 들여보낼 수 없으니 여기서도 필터(인터셉트, AOP)를 통해 권한을 부여받은 사람만 통과시킬 것이다.
정확히는 톰캣안에 스프링 컨테이너가 내장되어있는 구조는 아니다.
하지만 조금 더 쉬운 이해를 위해 다음과 같이 표현했음에 양해를 구한다.
public class Animal{
public void run(){
}
public class Dog extends Animal{
@Override
run(){
}
}
어노테이션은 무엇일까?
어노테이션은 한마디로 스프링에게 주석임을 알리며, 힌트를 주는 것이다.
이게 무슨 말이냐면, 주석은 다들 무슨 의미인지 알 것이다.
주석은 컴파일러에게 "이 부분은 해석하지마"라고 알리는 것이다.
힌트를 준다는 것의 의미는 무엇일까?
자바에서 Override는, "부모 클래스의 메서드를 상속받아 재정의했다" 라는 의미이다.
그러면 스프링이 매번 이것을 직접 해석하기 보다는 메뉴얼을 하나 만들어 스프링에게 전달하면
스프링이 이해하기 더 쉬울 것이다.(우리가 음식점에 갔는데, 메뉴판에 사진과 설명이 없고 메뉴의 이름만 띡하니 써있다고 생각해보자. 그러면 우리는 매번 불편하게 인터넷에 해당 메뉴가 어떤 음식인지 검색을 해봐야할 것이다.)
정리하자면, 주석은 컴파일러가 무시하고 어노테이션은 컴파일러가 해석한다.
스프링에는 다음과 같은 어노테이션들이 있다.
@Component // 클래스를 스프링 컨테이너 메모리에 로딩해라!
@Autowired // 로딩된 객체를 해당 변수에 집어넣어라!(DI, DI가 뭔지 모르겠다면 이전 글을 참고하자)
다음의 어노테이션을 예를 들어서 설명해보겠다
@Component
public Class A{
}
public Class B{
@Autowired
A a;
}
만약 클래스 A와 클래스 B가 있다고 해보자. A에 @Component
가 달려있으면 프로젝트가 실행되면, A라는 Object가 heap메모리에 올라가 스프링 컨테이너가 이 Object를 관리한다는 뜻이다.
클래스 B의 a라는 필드에는 @Autowired
가 붙어있다.
여기서 a는 클래스 A의 Object이고, 스프링 컨테이너는 A라는 클래스 타입을 가진 Object를 찾아 B에게 주입한다.
그렇다면 리플렉션과 컴파일 체킹은 무엇일까?
프로젝트가 실행돼 스프링 컨테이너가 생성되면 @Component
가 달린 모든 것들을 스캔해 heap 메모리에 올려 관리할 것이다.
리플렉션은 스캔하는 과정에서 각 클래스들이 어떤 필드, 메서드, 어노테이션을 가지고 있는지 분석하는 것이다.(런타임에)
public class Animal{
public void run(){
}
public class Dog extends Animal{
@Override
fly(){ // 컴파일 체킹 시 에러
}
}
컴파일 체킹이란?
위에서 설명했던 예제를 바탕으로 설명하겠다.
위의 예처럼 부모 클래스에 없는 메서드를 @Override
어노테이션을 달아놓으면 스프링이 리플렉션을 진행하던 도중 정말 Override한건지 확인을 하는 과정이 컴파일 체킹이다.
그리고 컴파일 체킹 결과 fly메서드는 부모 클래스의 메서드에 존재하지 않으니 오류가 발생할 것이다.