Chapter#01 : [Spring] STS 개발환경 - 다운로드 및 작업 경로 지정
Chapter#02 : [Spring] STS 개발환경 - IDE 환경 설정
Chapter#03 : [Spring] Spring Framework 웹 프로젝트 만들기
Chapter#04 : [Spring] Spring MVC 패턴( Model2 아키텍쳐 ) 구현 하기
Chapter#05 : [Spring] Component-Scan을 사용하는 Annotation 기반 설정
Chapter#06 : [Spring] MyBatis를 이용한 Oracle 데이터베이스 CRUD
#1. 컴포넌트의 이해
1) 컴포넌트( Component )란?
Spring Framework에서의 컴포넌트( Component )란, Spring의 IoC( Inversion of Control ) 컨테이너에 등록되어 관리되는 객체를 의미한다,
Spring에서는 일반적으로 빈( Bean )이라고도 부르며,
Java 객체를 생성하고, 관리하며, 의존성( Dependency Injection )을 통해 객체 간의 결합도를 낮추는 역할을 한다.
① Spring Container에 등록되어 있으며, 해당 컴포넌트가 필요한 곳에서 의존성 주입을 받아 사용할 수 있습니다.
② Component의 라이프사이클을 관리할 수 있으며, 초기화 및 소멸과 같은 라이프사이클 이벤트를 처리할 수 있습니다.
③ Spring의 다른 기능들과 연계하여 사용할 수 있으며, AOP( Aspect-Oriented Programming )와 같은 기능을 사용할 수 있습니다.
Spring 컴포넌트는 Spring Application 개발에서 가장 기본적이고 중요한 개념 중하나이다.
Spring은 컴포넌트 간위로 개발하고 관리함으로써 모듈성( Modularity )을 높이고, 유연성과 재사용성을 높일 수 있다.
2) 컴포넌트 스캔( Component Scann )
Spring Framework에서는 컴포넌트( Component ) 스캔( Component Scanning )이라는 기능을 제공하여,
Spring IoC(Inversion of Control) 컨테이너에 자동으로 빈(Bean)을 등록할 수 있다.
컴포넌트 스캔을 통해, 개발자는 더 이상 수작업으로 빈을 등록하거나 설정 파일을 작성하지 않아도 된다.
대신, 지정된 패키지를 스캔하고, 자동으로 빈( Bean )을 생성하여 IoC 컨테이너에 등록하는 방식으로 빈을 관리할 수 있다.
@Component | 일반적인 Spring Bean으로 등록할 Class에 사용되는 Annotation |
@Controller | Spring MVC에서 Controller로 사용할 Class에 사용되는 Annotation |
@Service | 비즈니스 로직을 수행하는 서비스 클래스에 사용되는 Annotation |
@Repository | Data Access 로직을 수행하는 DAO( Data Access Object ) 클래스에 사용되는 Annotation |
이러한 Annotation들은 @Component 어노테이션을 기반으로 하며, 각각의 역할에 맞게 구체화된 어노테이션이다.
Spring 이러한 어노테이션을 사용하여 지정된 패키지를 스캔하고, 해당 어노테이션을 가진 클래스를 빈으로 자동으로 등록한다.
컴포넌트 스캔은 스프링에서 빈을 자동으로 등록하는 가장 간편한 방법 중 하나이다.
이를 통해 개발자는 더욱 직관적이고 생산적인 개발이 가능해지며, 코드의 가독성을 높일 수 있다.
#2. 리스너를 등록하여 비즈니스 컴포넌트 호출 설정
( web.xml에 ContextLoaderListener 적용하기 )
DispatcherServlet이 생성한 Spring Container는 Controller 객체들만 생성한다.
하지만 Controller 객체들이 생성되기 전에 누군가 먼저 resources 소스 폴더에 있는
context-XXX.xml 파일들을 읽어 비즈니스 컴포넌트들을 메모리에 생성해야 한다.
이때 사용하는 클래스가 스프링에서 제공하는 ContextLoaderListener다.
ContextLoaderListenr도 DispatcherServlet과 마찬가지로 스프링 컨테이너를 구동하는 기능이 구현되어 있다.
web.xml 파일을 열고 contextConfigLocation을 추가한다.
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring/context-*.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/dispatcher-servlet.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
</web-app>
1) Lisener 등록
Lisener는 Servlet이나 Filter 클래스와 마찬가지로 web.xml 파일에 등록한다.
<listener> 태그 하위에 <listener-class> 태그를 이용하여 스프링에서 제공하는
ContextLoaderListenr 클래스를 등록하면 된다.
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
중요한 것은 ContextLoaderListener 클래스는 servlet 컨테이너가 web.xml 파일을 읽어서 구동될 때,
자동으로 메모리에 생성된다.
즉 ContextLoaderListener는 클라이언트의 요청이 없어도 컨테이너가 구동될 때 Pre-Loading되는 객체이다.
2) ContextLoaderListenr 등록
web.xml 파일에 ContextLoaderListenr 클래스를 서블릿 설정위에 등록한다.
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring/context-*.xml</param-value>
</context-param>
contextLoaderListenr가 Pre-Loading되어 스프링 컨테이너를 구동할 때,
src/main/resources 소스 폴더에 작성한 스프링 설정 파일들( 'context'로 시작하는 모든 XML )을
로딩하도록 엘리먼트위에 추가했다.
이제 web.xml을 파일을 저장하고 서버를 재구동해보자.
그러면 ContextLoaderListenr 객체가 Pre-Loading되어 스프링 컨테이너를 먼저 구동하고 이때,
비즈니스 컴포넌트 객체들이 생성된는 것을 확인 할 수 있다.
#3. 비즈니스 컴포넌트 설정
( 어노테이션 기반의 Service, Repository 구현하기 )
대부분의 컨테이너는 컨테이너가 구동될 때 XML 설정 파일( Servlet 컨테이너는 web.xml )을 읽어들인다.
그리고 읽어들인 XML 파일로부터 자신이 생성하고 관리할 객체들의 정보를 확인한다.
스프링 프레임워크는 스프링 컨테이너의 동작과 기능을 XML 설정파일을 통해 제어하므로 XML 설정이 매우 중요하다.
하지만 이런 XML 설정이 너무 복잡하고 방대하다면 오히려 프레임워크 사용을 어렵게 만들 수도 있다.
따라서 Spring Framework에서는 어노테이션( Annotation )을 이용한 설정을 통해 이런 XML 부담을 줄여준다.
※ src/main/resources 경로 Folder 형태로 노출 하기
Eclipse 혹은 STS에서 생성한 Spring Project중
src/main/resources의 형태가 폴더( Folder )가 아닌 패키지( Package ) 형태로 노출되는 경우가 있다.
사용하는데 문제가 되었던건 아니지만, 폴더 형태의 사용에 익숙해져 있었기 때문에
패키지 형태의 사용을 피하고, 익숙한 폴더 형태로 변경하는 방법을 정리한다.
먼저 Spring 프로젝트를 선택하고 마우스 오른쪽 버튼을 클릭하여 Properties를 선택한다.
Properties for 스프링_프로젝트 팝업창이 오픈되면 좌측 메뉴에서 Java Build Path를 찾고
Spring_프로젝트/src/main/resources 를 선택한뒤 Edit 버튼을 클릭한다.
Edit source folder 팝업창이 뜨면 기본적으로 src/main/resources 경로가 잡혀 있을 것이다.
하단의 Next 버튼을 클릭한다.
Exclusion patterns의 Add 버튼을 클릭한다.
Add Exclusion Pattern 창이 뜨면 입력창에 와일드 카드 「 ** 」를 입력하고 OK 버튼을 클릭한다.
Add Exclusion Pattern
---------------------------------------------------------------------------------------------------------------------------
원본 폴더에서 파일을 제외할 패턴을 입력합니다.
허용되는 와일드카드는 '*', '?' 및 '**'입니다. 예: 'java/util/A*.java, 'java/util/', '**/Text*'.
제외 패턴( 'Spring_프로젝트/src/main/resources' 에 대한 경로 ) :
Exclusion patterns을 보면 와일드 카드로 「 ** 」 가 추가된 것을 확인 할 수 있다.
Finish 버튼을 클릭한다.
「 Excluded: ** 」 추가된 것을 확인하면 Appliy and Close 버튼을 클릭하여 준다.
그럼 아래와 같이 이전에 패키지로 노출되던 항목들이 폴더 형태로 노출되는 것을 확인 할 수 있다.
1) context-common.xml 파일 생성하기
먼저 applicationContext.xml 파일을 삭제한다.
applicationContext.xml파일이 삭제되었다면 context-common.xml 파일을 생성한다.
먼저 context-common.xml의 경로를 잡아주어야 하는데
프로젝트의 src/main/resources 경로를 선택하고 마우스 우클릭하고 New → Other 를 선택한다.
Select a wizard 팝업창이 뜨면 General 카테고리에 있는 Folder를 선택한다.
New Folder 생성창에서 Folder name을 spring이라고 지정한다.
Finish 버튼을 클릭하면 spring 폴더를 생성된다.
spring 폴더가 생성되면 선택하고 마우스 오른쪽 버튼을 클릭 다시 New → Other 를 선택한다.
Select a wizard 팝업창이 뜨면 XML카테고리에 있는 XML File를 선택한다.
New XML File 생성창에서 File name을 context-common.xml이라고 지정한다.
Finish 버튼을 클릭하면 context-common.xml 파일이 생성된다.
2) 컴포넌트 스캔 설정
스프링 설정 파일에 Application에서 사용할 클래스들을 <bean> 등록하지 않고 자동으로 객체로 생성하려면
<context:component-scan/>이라는 엘리먼트를 설정해야 한다.
이 설정을 추가하면 스프링 컨테이너는 class 경로에 있는 class들을 스캔하여
@Component가 정의된 클래스들을 자동으로 객체로 생성한다.
생성된 context-common.xml 파일을 열고 코드를 아래와 같이 작성한다.
context-common.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"
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
">
<!-- @Service, @Repository만 include -->
<context:component-scan base-package="com.spring.web.*.*" use-default-filters="true">
<!-- Controller는 자동 스캔에 포함시키지 않는다. -->
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
</beans>
여기서 중요한것은 <context:component-scan> 엘리먼트의 base-package 속성인데,
만약 속성값을 「 com.spring.web.service 」형태로 지정하면
「 com.spring.web.service 」 패키지로 시작하는 모든 패키지를 스캔대상에 포함하게 된다.
따라서 다음과 같은 클래스들이 대상이 된다.
- com.spring.web.service
- com.spring.web.service.impl
- com.spring.web.servicecommon
하지만 실제 작성한 소스의 base-package 속성값은 「 com.spring.web 」 이므로
「 com.spring.web 」 으로 시작하는 모든 패키지들의 클래스들이 대상이 되는것이다.
<context:omponent-scan> 엘리먼트는 <context:exclude-filter>와 <context:include-filter>를 자식으로 가질 수 있다.
<context:exclude-filter>는 특정 어노테이션을 배제할 때 사용하고,
반대로 <context:include-filter>는 포함시킬 때 사용한다.
<!-- @Service, @Repository만 include -->
<context:component-scan base-package="com.spring.web.*" use-default-filters="true">
<!-- Controller는 자동 스캔에 포함시키지 않는다. -->
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
위 설정은 @Controller라는 어노테이션은 컴포넌트 스캔할 때 제외하고
@Controller 이외의 다른 어노테이션( @Service, @Repository )은 컴포넌트 스캔에 포함시키라는 의미의 설정이다.
#4. 프레젠테이션 컴포터는 설정
( 어노테이션 기반의 Controller 구현 )
Spring MVC에서는 어노테이션을 사용하여 복잡한 XML 설정을 최소화할 수 있다.
스프링에서 사용하려면 먼저 <beans>루트 엘리먼트에 context 네임스페이스를 추가하고
<context:component-scan>엘리먼트를 추가한다.
dispatcher-servlet.xml 파일을 열고 component-scan 설정을 아래와 같이 변경한다.
dispatcher-servlet.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:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc
https://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd"
>
<!-- Annotation 활성화 -->
<mvc:annotation-driven></mvc:annotation-driven>
<!-- component-scan 설정 -->
<context:component-scan base-package="com.spring.web.*.controller" use-default-filters="true">
<!-- Controller는 자동 스캔에 포함 시킨다. -->
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"></context:include-filter>
<!-- Service, Repository는 자동 스캔에 제외 시킨다. -->
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Service"></context:exclude-filter>
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Repository"></context:exclude-filter>
</context:component-scan>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/"></property>
<property name="suffix" value=".jsp"></property>
<property name="order" value="1"/>
</bean>
</beans>
위 설정은 모든 Controller 클래스들을 스캔 범위에 포함시키기 위해
<context:component-scan>엘리먼트의 base-package 속성값을 com.spring.web.*.controller 로 등록했다.
그리고 스캔 대상에서 Controller 클래스들만 포함시키고 ServiceImpl 클래스와 DAO 클래스는 제외시키기 위해
다음과 같이 <context:include-filter>, <context:exclude-filter> 설정을 사용하였다.
<context:include-filter>
· <context:include-filter>엘리먼트로 Controller( org.springframework.stereotype.Controller )를 설정
· Controller는 자동으로 스캔에 포함 시킨다.
<context:exclude-filter>
· <context:exclude-filter>엘리먼트는 Service( org.springframework.stereotype.Service )와
Repository( org.springframework.stereotype.Repository )를 설정
· Service와 Repository 자동으로 스캔에서 제외된다.
#5. Apachat Tomcat을 실행하여 Spring 프로젝트 결과 확인
모든 작업이 완료되면 STS에서 Apache Tocmat을 실행한다.
브라우저를 열고 http://localhost:8181/spring_web/ 를 입력한다.
위와 같이 문제 없이 프로젝트의 결과가 노출된다면
이전 포스팅에서 구현한 Spring MVC 패턴에 Component Scan이 적용된 결과이다.
'Spring Web > Spring Framework' 카테고리의 다른 글
[Spring] Android Studio GIT - Clone 기존 GIT 프로젝트와 연결 (0) | 2022.11.08 |
---|---|
[Spring] MyBatis를 이용한 Oracle 데이터베이스 CRUD 기능 사용 (2) | 2022.07.06 |
[Spring] Spring MVC 패턴(Model2 아키텍쳐) 구현 하기 (0) | 2022.05.26 |
[Spring] Spring Framework 웹 프로젝트 만들기 (0) | 2021.12.23 |
[SpringBoot] Windows환경에 IntelliJ 설치하기 (0) | 2021.12.18 |