[스프링 프레임워크란]
최초에 사용자로부터 요청한 값이 들어오게 되면 컨트롤러 → 서비스 → 뷰 순서로 진행된다.
스프링 프레임워크는 객체지향의 의존성 주입기법을 적용한 객체지향 프레임워크였다.
또한 자체적으로 객체를 생성하고 관리하면서 필요한 곳으로 객체를 주입해 주는 역할을 한다.
스프링 프레임워크의 중요한 특징 중 하나는 다른 프레임워크들을 쉽게 결합해서 사용할 수 있다는 점이다.
스프링 프레임워크가 웹이나 데이터베이스와 같이 특정한 영역을 구애받지 않고 시스템의 객체지향 구조를 만드는 데 이용된다는 성격 때문이다.
이 역할들은 설정 파일이나 어노테이션을 이용해야 한다.
스프링이 관리하는 객체들을 빈이라는 이름으로 불린다.
→ 빈은 보통 root-context.xml이라는 파일에서 관리한다.
[의존성이란??]
과거에는 의존성을 해결하기 위해 컨트롤러에서 직접 서비스 객체를 생성하거나 하나의 객체만 생성해서 활용하는 등의 다양한 패턴을 사용해 왔지만 스프링 프레임워크가 만들어지게 되면서 이러한 불편한 점들이 개선되었다.
@Autowired // 4개의 객체 모두 빈으로 등록되어 영속성 컨텍스트에 추가된다.
private PostService postService;
@Autowired
private CommentService commentService;
@Autowired
private MemberService memberService;
@Autowired
private CommentRepository commentRepository;
- 의존성 주입이란? 그렇다고 모든 클래스에 의존성 주입을 하느냐?? → X
- DTO와 VO는 데이터에 중점을 두고 설계된 객체들이기 때문에 빈으로 등록 X
- 특히 DTO는 생명주기가 굉장히 짧고 데이터 보관이 주된 역할이기 때문에 빈으로 처리 X
- 인터페이스는 틀만 짜놓고 상속받은 클래스에서 다형성을 이용하여 객체를 재정의 및 추상화를 하여 보다 코드의 유연성을 높인다면, 의존성 주입은 외부의 클래스에서 선언해 놓은 객체를 불러와서 객체 간의 관계를 정의 및 사용하여 객체 간의 결합도를 낮추기 위해 사용한다.
- 핵심 객체들에게만 의존성 주입을 해준다.
- 의존성 주입이란 객체를 외부에서 받아와서 받아온 객체를 통해 수정 및 삭제와 같은 작업을 함으로써 객체를 보다 유연하고 효율적으로 사용하기 위함. → 원본 객체에는 영향 X
- 의존성이란 하나의 객체가 자신이 해야 하는 일을 하기 위해서 다른 객체의 도움이 필수적인 관계를 의미한다.
[MyBatis]
기존의 SQL을 그대로 사용할 수 있다는 다음과 같은 편리한 기능들이 있다.
- PreparedStatment / ResultSet의 처리 - 기존에 프로그램을 작성해서 하나씩 처리해야 하는 파라미터나 ResultSet의 getXXX()를 MyBatis가 알아서 처리해 주기 때문에 코드의 양을 크게 줄일 수 있다.
- Connection / PreparedStatment/ResultSet을 자동으로 close() 처리를 해준다.
- SQL의 분리 - MyBatis를 이용하여 별도의 파일이나 어노테이션들을 이용해서 운영이 가능하다.
MyBatis와 스프링의 연동방식은 크게 2가지가 있다.
- 기존의 DAO에서 SQL의 처리를 MyBatis를 이용하는 구조로 스프링 프레임워크랑 완전한 독립적인 존재로 바꾸는 방식
- 스프링과 MyBatis사이에 mybatis-spring이라는 라이브러리를 이용해서 스프링이 데이터베이스 전체에 대한 처리를 하고, MyBatis는 일부 기능 개발에 활용하는 방식이다.
- 개발 시에는 Mapper 인터페이스라는 방식을 이용해서 인터페이스로만 모든 개발이 가능한 방식
MyBatis의 대표적인 기능으로는 Mapper기능이 있다.
Mapper기능을 통해 SQL 쿼리와 자바 메서드를 자동으로 매핑해 준다.
사용 방법은 Mapper 인터페이스를 만들고 xml파일에 쿼리문을 작성한다.
[web.xml & root-context.xml & servletcontext.xml]
[web.xml]
최초로 WAS가 구동될 때 각종 설정을 정의하기 위한 파일
하위에 위치한 xml파일들을 어디서 가져올 건지 인식해 준다.
[root-context.xml]
view 관련되지 않은 객체를 정의한다.
빈 객체를 정의하기 위한 파일
Service, DAO, DB 등의 비즈니스 로직과 관련된 설정을 해준다.
이곳에 등록된 빈은 모든 콘텍스트에서 사용할 수 있다.
Servlet-context내의 빈들은 이용이 불가하고 Servlet-context에서 공유해야 하는 빈들을 등록해 놓고 사용할 수 있다.
- 예시 코드
<bean id="hikariConfig" class="com.zaxxer.hikari.HikariConfig">
<property name="driverClassName" value="org.mariadb.jdbc.Driver"></property>
<property name="jdbcUrl" value="jdbc:mariadb://localhost:5306/webdb"></property>
<property name="username" value="webuser"></property>
<property name="password" value="webuser"></property>
<property name="dataSourceProperties">
<props>
<prop key="cachePrepStmts">true</prop>
<prop key="prepStmtCacheSize">250</prop>
<prop key="prepStmtCacheSqlLimit">2048</prop>
</props>
</property>
</bean>
<bean id="dataSource" class="com.zaxxer.hikari.HikariDataSource"
destroy-method="close">
<constructor-arg ref="hikariConfig" />
</bean>
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="mapperLocations" value="classpath:/mappers/**/*.xml"/>
</bean>
</bean>
[Servlet-context.xml]
url과 관련된 Controller, 어노테이션, View 등을 설정해 준다.
이곳에 등록된 빈은 해당 콘텍스트에서만 사용할 수 있다.
DispatchServlet이 직접 사용하는 컨트롤러를 포함한 웹 관련 빈을 등록하는 데 사용한다.
독자적인 콘텍스트를 가지고, root-context내의 빈을 사용할 수 있다.
- 예시 코드
<!-- 스프링 MVC설정을 어노테이션 기반으로 처리한다-->
<!-- 스프링 MVC와 관련된 여러 객체를 자동으로 Bean으로 등록한다-->
<mvc:annotation-driven></mvc:annotation-driven>
<!-- html, css, js, 이미지와 같은 정적 파일의 경로-->
<!-- 스프링 MVC에서 별도로 처리하지 않는다-->
<mvc:resources mapping="/resources/**" location="/resources/"></mvc:resources>
<!-- 주소 요청이 FrontController에 들어왔을 때, 처리가 끝나고 View이동해야 하는데-->
<!-- 주소의 앞에 prefix를, 주소의 뒤에 suffix를 붙여서 jsp의 경로를 결정한다-->
<!-- /hello라는 요청이 들어오면, 이 주소와 매핑된 Page Controller의 메서드가 처리하고-->
<!-- /WEB-INF/views/hello.jsp 로 이동시킨다-->
<!-- 외부에서 jsp의 경로를 알 수 없도록 내부에서 경로를 정해주는 것이다-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
<!-- 웹에서 보내온 parameter와 메서드의 parameter포맷이 일치 하지 않을 때, 아래에 등록한 bean으로 처리한다-->
<bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
<property name="formatters">
<set>
<bean class="org.zerock.springex.controller.formatter.LocalDateFormatter"/>
<bean class="org.zerock.springex.controller.formatter.CheckboxFormatter"/>
</set>
</property>
</bean>
<mvc:annotation-driven conversion-service="conversionService" />
<!-- 아래 패키지의 하위를 모두 scan해서 어노테이션 설정되어 있는 것을 bean으로 로딩해라-->
<context:component-scan base-package="org.zerock.springex.controller"/>