본문 바로가기
Spring 프레임워크/메모

스프링 컨테이너 어노테이션 메모

by Hwanii_ 2023. 8. 2.
728x90

1.

<context:component-scan base-package="com.spring.biz"/>

 

com.spring.biz 하위 폴더에,

모든 자료형을 (클래스 파일) 대상으로 객체화를 해주게 하는 코드 이다.

 

위와 같이 applicationContext.xml 기능 설정 파일 내부에, 코드를 작성 하고,

 

자바에서 @ (어노테이션) 을 명시 하면 된다.

 

해당 컨테이너는, 스프링 컨테이너 이므로,

 

 

위의 경로에 저장 생성 한다.

 

해당, .xml 파일을 생성 하기 위해서 아래와 같이 하면 된다.

 

 

 

 

 

1-2.

23.08.07 추가.

 

1)

위에서, Java Resources - src/main/resources 폴더에,

applicationContext.xml 설정 파일을 생성 하고,

위의 .xml 파일에,

<context:component-scan base-package="com.spring.biz"/>

코드를 작성해서, Spring이 해당 하위 폴더에서 사용되는 객체들을 관리한다고 했다.

 

@Service, @Repository 와 같은 어노테이션 들은,

applicationContext.xml 에서 설정을 하는데,

이는 비즈니스 로직을 다루거나 데이터 액세스를 위한 작업 처리 이라면,

주로 이곳에서 설정 하게 된다.

 

2)

src - main - webapp - WEB-INF 폴더에,

DispatcherServlet-servlet.xml 설정 파일을 반드시 생성 해야 한다고 공부했다.

위의 .xml 파일에,

<context:component-scan base-package="com.spring.view.controller"/>

코드를 작성해서, Spring이 해당 하위 폴더에서 사용되는 객체들을 관리한다.

 

 

com.spring.view.controller 패키지의 위치는 위의 이미지와 같다.

 

DispatcherServlet-servlet.xml은, DispatcherServlet의 설정을 관리하는 역할을 한다.

웹 관련된 설정들은 이곳에 명시하고,

주로 컨트롤러,  HM (핸들러 매핑), VR (뷰 리졸버) 등과 관련된 설정이 이곳에서 들어 가게 된다.

 

@Controller 와 같은 어노테이션 들은,

DispatcherServlet-servlet.xml 에서 설정 한다고 생각 하면 된다.

 

[ 결론 ]

 

컴포넌트 스캔 설정은 각각의 파일에 분리하여 설정 하여,

 

웹 관련 부분은 DispatcherServlet-servlet.xml

 

비즈니스 로직 & 서비스 계층은 applicationContext.xml

 

에 명시하여, 코드의 구조적인 구분과 관리를 쉽게 하게 한다.

 

2.

@Component 

>> 해당 자료형을 객체화 한다.

 

만약, 참조변수 (객체명 / 주체) 로 무언가 해야 하거나,

암튼 사용 해야 한다면, 참조변수가 필요 하니까,

 

@Component("참조변수명 / 객체명") 으로 작성 해주면 된다.

 

3.

@Autowired

 

>>

1) 어노테이션이 작성된 곳의 "자료형" 이 메모리에 올라와 있으면,

DI (의존 주입) 을 해주는 어노테이션 이다.

 

>>

2) 의존관계인 멤버가 "의존관계 라는 것을" 명시해주고,

알아 보기 쉽게, 위의 어노테이션을 사용 한다.

 

"자료형"이 "메모리" 에 올라와 있어야 DI를 해주니까 ~

즉, 객체화가 되어 있어야 사용이 가능 하다.

 

그래서, 의존 관계에 놓인 멤버는 .xml 파일 내부에서,

<bean class = "패키지명.자료형" id = "참조변수명" /> 

과 같이 코드를 작성 해서 해당 자료형의 멤버를 객체화 한다.

 

>>

3) 무엇보다, DAO나 VO 처럼 수정될일이 없는 객체가 아니라,

자주 바뀔 가능성이 있는 객체는,

재 컴파일을 하지 않기 위해서라도,

.xml 에서 객체화를 해주는 식으로 작성 한다.

 

사실,

의존관계에 놓인 멤버도 @Component 어노테이션을 사용해서,

객체화를 할 수 있지만, 이렇게 하지 않는다.

 

2) 의 이유 처럼, 의존관계 라는 것을 알려주기 위함과,

3) 의 이유 처럼, 자주 바뀔 가능성이 있기에,

 

@Component 어노테이션이 아닌,

@Autowired 어노테이션을 사용 한다.

 

4.

@Component 어노테이션을 상속받은, 어노테이션이 존재 한다.

 

1) @Repository

 

스프링 컨테이너는 @Repository 어노테이션을

"Model 파트에서 "객체화" 하는구나 ?" 라고 자동으로 인지 하는 기능을 가진다.

 

 

위와 같이, @Repository 어노테이션을 작성하는데,

@Repository("참조변수명") 으로 작성하면,

해당 참조변수명으로 해당 자료형을 객체화를 해주게 된다.

 

즉, BoardDAO 라는 자료형을 boardDAO 라는 참조변수로 객체화 하게 된다.

 

2) @Service

 

스프링 컨테이너는 @Service 어노테이션을

"Controller 파트에서 "객체화" 하는구나 ?" 라고 자동으로 인지 하는 기능을 가진다.

 

 

여기서도, @Service("참조변수명") 으로 작성이 되어 있다.

 

사실, 참조변수를 (객체명 / 주체) 직접적으로 사용 하지 않는다면,

명시해줄 필요는 없지만, 사용할지 말지 잘 모르겠으면 작성 하도록 하자..

 

 

위의 이미지를 보면, @Autowired 가 작성 되어 있는것을 볼 수 있는데,

 

이미, 위에서 BoardDAO 자료형을 객체화 해줬기에,

 

의존관계에 놓인 해당 자료형의 객체가 메모리에 올라와 있어서,

 

.xml 파일 내부에서 <bean> 태그로 객체화를 해주지 않아도 되는 상황 이다.

 

이미 객체화를 했다.

 

23.08.03 추가

 

3) @Controller

(@Controller_검색 키워드)

 

Spring 에서 @Controller 어노테이션은,

@Component 어노테이션을 상속 받은 어노테이션 이다.

 

@Controller 어노테이션을 사용하면,

더 이상,

Spring의 Controller 인터페이스를,

구현 하지 않겠다는 의미 이다.

 

이것이 의미하는 바는, 아래와 같다.

 

>>

@Controller 를 사용해서,

메서드와 메서드 시그니쳐 강제성이 부여 되지 않는다.

 

>>

@RequestMapping

특정 요청에 대해, Controller 객체를 찾아가는게 아니라,

메서드를 찾아간다.

 

어 ? 근데,

메서드와 메서드 시그니쳐 강제성이 부여 되지 않게 됬네 ?

 

즉, 메서드명, 리턴타입, 인자의 개수를 내 마음대로 작성 할 수 있네 ?

 

어 ? 그러면,

하나의 XxxController 클래스에,

두개 이상의 메서드가 존재 해도 되는거네 ?

의 결론이 나오게 된다.

 

왜 ?

메서드명을 더이상 인터페이스의 추상메서드명과 동일하게,

작성 하지 않아도 되니까 ~~

 

그래서,

유사한 코드 또는 관련된 애들끼리는,

XxxController 클래스에 몰아 넣고,

응집도를 높히고, 유지 보수를 용이 하게 할 수 있다.

 

이러한 방식은 장단점이 있어서, 상황에 맞게 잘 활용 하는게 중요 하다.

 

하지만, 보편적으로 이러한 형태의 구조를 실제로 많이 사용 한다.

 

Controller 인터페이스를 구현 하지 않아, 코드가 가벼워진 모습을 확인 할 수 있다.

 

 

 

 

코드가 유사하고, 비슷한 기능을 가진 XxxController 클래스 내부의 메서드를,

하나의 XxxController 클래스 내부에 몰아 넣는 모습을 확인 할 수 있다.

 

4) @RequestMapping

 

@RequestMapping 어노테이션은,

기존의 HandlerMapping의 기능을 하는 어노테이션 이다.

 

HandlerMapping 이란 ?

사용자의 요청에 대한 Controller 자료형의 객체 반환을 수행 한다.

 

HashMap 으로 이루어져 있고,

사용자의 요청 == command == key 

가 키워드로 들어오면,

 

해당 요청 == command == key 에 대한,

value == 값 == Controller 자료형의 객체

 

를 get(key) 해서 해당 객체를 return 한다.

 

이 HandlerMapping 클래스 내부의 HashMap은 setter로 의존 주입을 했었다.

 

 

 

위의 이미지와 같이, 

@RequestMapping 어노테이션은,  다양한 속성을 가진다.

method = RequestMethod.GET 랑, method = RequestMethod.POST 로,

같은 value 값의 사용자 요청에 대해, 분기 처리를 할 수 있다.

 

또한,

 

반환할 데이터가 있으면, 리턴 타입으로, ModelAndView 를 사용 한다.

반환할 데이터가 없으면, 리턴 타입으로 단순, String 타입을 사용 한다.

 

이렇게 하는 이유는, 반환할 데이터가 없으면, 객체를 return 하는것 보다,

String 타입을 return 하는게 상대적으로 가볍기 때문이다.

 

반환할 데이터가 있는 경우, 참조변수명을 mav 라고 가정 하고,

mav.addObject("파라미터명", 데이터); 를 사용해, 데이터를 View로 보내준다.

mav.setViewName("main.jsp"); 과 같이, 경로도 같이 set 한다.

 

mav.addObject("파라미터명", 데이터); 는,

기존의,

request.setAttribute("bdatas", bDAO.selectAll(null)); 코드와 동일한 기능을 가진다.

 

 

 

23.08.07 추가.

 

위에서,

반환할 데이터가 있으면 리턴타입으로 MAV를 사용 하고,

반환할 데이터가 없으면 리턴타입으로 String 타입을 사용 한다 했다.

 

이 개념에서, 반환할 데이터가 있던, 없던 상관 없이 리턴 타입으로 String 만 사용 할 수 있다.

 

이렇게 Controller 객체 내부 메서드의 리턴 타입으로 String을 사용 하는것을 지향 하는 이유는,

Controller 객체 메서드의 리턴타입을 가볍게 하기 위해서 이다.

즉, MAV 객체 자체를 반환 하면, 상대적으로 무겁기 때문에, 가볍게 보내기 위함 이다.

 

바로 해당 메서드의 인자로  Model model 을 추가 하여 사용하는 방식 이다.

 

Model 자료형은 스프링에서 기본 제공 해주며,

 

import 했을 때, 코드는 아래와 같다.

 

 

사용 예시는 다음과 같다.

 

 

보내야할 데이터가 있는 상황인데,

메서드 리턴 타입은 String 타입 이다.

 

이때, model 을 주체로 해서 addAttribute() 라는 메서드를 사용 한다.

 

반응형