학습하며 정리한 내용을 올리는 것이니, 참고용으로만 봐 주시길 바랍니다.
자바 스프링 프레임워크(renew ver.) - 신입 프로그래머를 위한 강좌

MVC를 이용한 웹 서비스

  1. MVC의 기본 구조: M1 구조에 비해 유지보수 및 기능개선에 이점

    브라우저 <-> Controller - Service - DAO <- (Model) -> DB
                 |
                View
    .
    Controller: 이것들을 Control(기능, 뷰 등을 Control)
    Service: 기능
    View: 사용자에게 보여주는 부분
    Dao: DB와 연동 
  2. 스프링 MVC 프레임워크 구조

               HandlerMapping   HandlerAdapter <-> Controller
                     |           / 
    브라우저 <-> DispatcherServlet <
                     |           \
                    View         ViewResolver

    2.1. 클라이언트가 브라우저를 통해 요청을 보내면 DispatcherServlet이 받는다.
    2.2. DispatcherServlet은 이를 HandlerMapping에게 보내 가장 적합한 Controller를 찾아준다.
    2.3. DispatcherServlet은 HandlerAdapter에게 요청을 보내고 HandlerAdapter는 HandlerMapping이 찾아준 Controller 객체 아래에 있는 메소드들 중 가장 적합한 메소드가 무엇인지 찾아준다. 그 후, 처리된 결과를 Model(View 포함)이라는 데이터를 가지고와서 DispatcherServlet에게 건네준다.
    2.4. 결과(?Model?, View)를 가지고 DispatcherServlet은 ViewResolver에게 보내 View에 해당하는 가장 적합한 JSP 문서를 찾아달라고 요청하여, ViewResolver는 View를 선택해준다.
    2.5. 찾아진 JSP가 있는 View에게 가서 응답(JSP)을 클라이언트에게 보내 주도록 한다.

  3. DispatcherServlet 설정하기

    // WEB-INF/web.xml
    //
    <servlet>
     <servlet-name>appServlet</servlet-name> // 서블릿 별칭
     <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> // 서블릿명(패키지 이름을 포함한 전체 서블릿 명)
     <init-param> // 초기 파라미터
         <param-name>contextConfigLocation</param-name>
         <param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value> // 스프링 설정파일 (DispatcherServlet이 등록될 때 스프링 설정파일까지 설정해 주도록 함)
     </init-param>
     <load-on-startup>1</load-on-startup>
    </servlet>
    //
    <servlet-mapping>
     <servlet-name>appServlet</servlet-name> // 위에서 별칭으로 지정한 appServlet이
     <url-pattern>/</url-pattern> // root(/)로 들어오는 모든 요청을 처리하도록
    </servlet-mapping>
    • DispatcherServlet 설정 시 위의 초기 파라미터(init-param)에서 지정한 파일을 이용해 스프링 컨테이너를 생성한다. 초기 파라미터를 지정하지 않은 경우 서블릿별칭(appServlet-context.xml)(이 파일이 존재해야함.)을 이용해 스프링 컨테이너를 생성한다.
    • 이를 통해 HandlerMapping, HandlerAdapter, ViewResolver가 생성된다.
    1. Controller 객체
      1. Controller 생성 방법
    // servlet-context.xml
    //
    <annotation-driven /> // 스프링 컨테이너 사용을 위한 부가적인 클래스들이 빈 객체로 스프링 설정파일에 등록됨.
    // Controller 객체로 사용할 클래스 정의
    //
    @Controller
    public class HomeController {
      ...
    }

    4.2. @RequestMapping
    :사용자로부터 들어오는 요청을 Controller가 메소드로 맵핑

    http://localhost:8090/ch08/success (ch08: project path?name?)
    //
    @RequestMapping("/success")
    public String success(Model model) {
     return "success";
    }

    4.3. Model 타입의 파라미터
    : Controller는 Model 객체에 데이터를 담아 DispatcherServlet에 전달

    @RequestMapping("/success")
    public String success(Model model) {
     model.setAttribute('tempData', "model has data");
    //
     return "success";
    }

    4.3. view 객체
    : 스프링 설정파일에 ViewResolver를 생성

    <beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
     <beans:property name="prefix" value="/WEB-INF/views/" />
     <beans:property name="suffix" value=".jsp" />
    </beans:bean>
    @RequestMapping("/success")
    public String success(Model model) {
     return "success";
    }

    : return값의 success 앞뒤로 ViewResolver의 prefix, suffix를 붙여주어 /WEB-INF/views/success.jsp 라는 View를 만들어준다.

스프링 MVC 웹 서비스 파일의 구성

  1. web.xml

    • DispatcherServlet을 등록한다.
    • 사용자의 모든 요청을 받기 위해 서블릿 맵핑 경로를 /로 설정한다.
  2. servlet-context.xml

    • DispatcherServlet을 서블릿으로 등록할 때 contextConfigLocation이라는 초기화 파라미터를 servlet-context.xml로 지정하고 있었다.
    • 이는 스프링 설정파일이다.
    • 클래스로부터 객체(bean)을 생성하고 조립하는 역할을 한다.
    • 웹 구동을 위한 resource(jsp, html, css) 등을 맵핑해 준다.
    • InternalResourceViewResolver의 prefix, suffix를 정의하여 View로써 response를 응답하도록 해 준다.

Service Annotation

: 스프링 설정파일(servlet-context.xml)에 Bean 객체를 생성하지 않아도, 서비스 객체마다 @Service Annotation을 붙여주면 자동으로 스프링 컨테이너에 담겨지고, Controller에서 @Autowired만 붙여주면 자동으로 서비스 객체를 사용할 수 있음.
: @Component, Repository
: Dao 또한 동일하게 사용가능
: @Repository("memService"), @Repository(name="memService") 와 같이 key-value 형식으로 특정 이름을 지정할 수 있으나 권장되진 않음.

HttpServletRequest 대신 RequestParam 사용하기

@RequestMapping(value="/memLogin", method=RequestMethod.POST)
// public String memLogin(Model model, HttpServletRequest request) {
public String memLogin(Model model, @RequestParam("memId") String memId, @RequestParam("memPw") String memPw) {    
//    String memId = request.getParameter("memId");
//    String memPw = request.getParameter("memPw");
//    
    Member member = service.memberSearch(memId, memPw);
<form action="/lec17/memLogin" method="post">
    ID : <input type="text" name="memId" ><br>
    PW : <input type="password" name="memPw" ><br>
    <input type="submit" value="Login" >
</form>
  • @RequestParam(value="memPW", required=false, defaultValue="1234") 와 같이 필수로 넘겨주어야 하는지 여부, default 값 을 설정할 수 있다. 잘 사용되지는 않는다.

커맨드 객체를 이용한 HTTP 정보 얻어오기

// public String memJoin(Model model, HttpServletRequest request) {
public String memJoin(Member member) {
//
//  String memId = request.getParameter("memId");
    ...
//    
//    service.memberRegister(memId, ...);
    service.memberRegister(member.getMemId(), ...);

//    model.addAttribute("memId", memId);
      ...
//
    return "memJoinOk";
    <h1> memJoinOk </h1>
//  ID : ${memId}<br />
    ID : ${member.memId}<br />
    ...

MemberAttribute 사용하기

  1. 기존의 커맨드 객체를 이용하는 방식에서 커맨드 개체의 변수명을 사용하는 것이 아니라 닉네임을 사용할 수 있도록 한다.
    public String memJoin(Member member)
    -> ${member.memId}

    public String memJoin(@ModelAttribute("mem") Member member)
    -> ${mem.memId}

  2. 함수 위에 @ModelAttribute("serverTime")을 지정하면, 다른 함수가 호출되어도 항상 @ModelAttribute를 지정한 함수도 같이 호출된다.

    @ModelAttribute("serverTime")
    public String getServerTime(Locale locale) {
     ...
    }
    //   
    @RequestMapping(value="/memJoin", method=RequestMethod.POST) {
     ...
    }

    Model & ModelAndView

    : Model을 뷰에 데이터만을 전달하기 위한 객체이고,
    ModelAndView는 데이터와 뷰ㅜ의 이름을 함께 전달하는 객체이다.

    ////////// Model
    public String memModify(Model model, Member member) {
     ...
     model.addAttribute("memBef", value);
     return "memModifyOk";
    }
    //
    ///////// ModelAndView
    public ModelAndView memModify(Member member) {
     ...
     ModelAndView mav = new ModelAndView();
     mav.addObject("memBef", value);
     mav.setViewName("memModifyOk");
    //    
     return mav;
    }

학습하며 정리한 내용을 올리는 것이니, 참고용으로만 봐 주시길 바랍니다.
자바 스프링 프레임워크(renew ver.) - 신입 프로그래머를 위한 강좌

스프링컨테이너 생명주기

  1. 생성: 스프링컨테이너와 빈 객체들이 생성되고 주입(의존관계)된다.
GenericXmlApplicationContext ctx = new GenericXmlApplicationContext("classpath:appCtx.xml");
  1. 사용
    : `BookRegisterService bookRegisterService = ctx.getBean("bookRegisterService", BookRegisterService.class);

  2. 소멸
    : ctx.close();

Bean 객체 생성/제거 시 특정작업을 수행하도록 하기

: 해당 객체가 인증절차(DB연결, 어떤 작업으로 인한인증작업) 시 주로 사용된다.

  1. 인터페이스 이용하기
public class BookRegisterService implements InitializingBean, DisposableBean {

    @Autowired 
    private BookDao bookDao;

    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.prinltn("Bean 객체 생성 시");
    }

    @Override
    public void destory() throws Exception {
        System.out.println("Bean 객체 소멸 시");
    }
}
  • InitializingBean, DisposableBean 인터페이스를 상속받는다.
  • 상속받은 인터페이스의 afterPropertiesSet, destory 함수를 구현한다.
  1. 스프링 속성 이용하기
<bean id="memberRegisterService" class="com.member.dao.MemberRegisterService" init-method="initMethod" destroy-method="destroyMethod" />
...
public class MemberRegisterService {
    ...
    public void initMethod() {

    }

    public void destroyMethod() {

    }
}
  • bean 태그에 init-method, destroy-method 속성과 함수 이름을 넣어준다.
  • 해당 Class에 init, destroy 함수를 구현해 준다.

XML 파일이 아닌 Java를 이용해 스프링 설정하기

  • applicationContext.xml -> MemberConfig.java

  • 이 자바 클래스 파일(MemberConfig.java)이 스프링 설정파일로써 스프링 컨테이너를 만드는 데 사용될 것임을 명시 -> @Configuration

  • 이 메소드는 Bean객체를 만드는 데 사용될 것임을 명시 -> @Bean

  • 자바 클래스 파일 명세

@configuration
public class MemberConfig {
    /* 기본 Bean 객체 생성하기 */
    // <bean id="**studentDao**" class="*ems.member.dao.StudentDao*" />

    @Bean
    public *StudentDao* **studentDao**()  {
        return new StudentDao();
    }

    /* DI가 있는 Bean 객체 생성하기 */
    /*
    <bean id="registerService" class="ems.member.service.StudentRegisterService">
        <constructor-arg ref="studentDao"></constructor-arg>
    </bean>
    */

    @Bean
    public StudentRegisterService registerService() {
        return new StudentRegisterService(studentDao());
    }

    /* setter가 있는 Bean 객체 생성하기 */
    /*
    <bean id="dataBaseConnectionInfoDev" class="...DataBaseConnectionInfo">
        <property name="jdbcUrl" value="jdbc:oracle:...">
    </bean>
    */

    @Bean
    public DataBaseConnectionInfo dataBaseConnectionInfoDev() {
        DataBaseConnectionInfo infoDev = new DataBaseConnectionInfo();
        infoDev.setJdbcUrl("jdbc:oracle:...");

        return infoDev;
    }

    /* setter에 다른 Bean객체를 넣는? Bean 객체 생성하기 */
    /*
    <bean id="...">
        <property name="dbInfos">
            <map>
                <entry>
                    <key>
                        <value>name</value>
                    </key>
                    <value>Jay</value>
                </entry>
                <entry>
                    <key>
                        <value>dev</value>
                    </key>
                    <ref bean="dataBaseConnectionInfoDev" />
                </entry>
            </map>
        </property>
    */

    @Bean
    ...
    dbInfos.put("name", "Jay");
    dbInfos.put("dev", dataBaseConnectionInfoDev());
    info.setDbInfos(dbInfos);
}
  • 스프링 컨테이너 생성하기
/*
GenericXmlApplicationContext ctx =
    new GenericApplicationContext("classpath:applicationContext.xml");
*/

AnnotationConfigApplicationContext ctx = 
    new AnnotationConfigApplicationContext(MemberConfig.class);

Java 파일 분리

: DB관련 Dao, Service 객체, DB관련 기능, Utils 로 보통 분리한다.

  • 분리된 자바 파일은 다음과 같이 comma를 이용해 여러개를 불러올 수 있다.
    AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(MemberConfig1.class, MemberConfig2.class, MemberConfig3.class);
  • 또는, MemberConfig1.java 파일 내 @Import({MemberConfig2.class, MemberConfig3.class}) 를 기입해주고 MemberConfig1.class만 불러오면 된다.

'Backend > Spring' 카테고리의 다른 글

Spring - 데이터베이스  (0) 2021.02.14
Spring - 세션과 쿠키 && 리다이렉트와 인터셉트  (0) 2021.02.09
Spring - MVC  (0) 2021.02.04
Spring - Bean과 의존객체 주입  (0) 2021.02.01
Spring - Dependency Injection  (0) 2021.01.31

학습하며 정리한 내용을 올리는 것이니, 참고용으로만 봐 주시길 바랍니다.
자바 스프링 프레임워크(renew ver.) - 신입 프로그래머를 위한 강좌

스프링 설정파일(/src/main/resources/applicationContext.xml) 분리

  1. .

     String[] appCtxs = {"classpath:appCtx1.xml", "classpath:appCtx2.xml", "classpath:appCtx3.xml"};
     GenericXmlApplicationContext ctx = new GenericXmlApplicationContext(appCtxs);
  2. appCtxImport.xml 중

    <import resource="classpath:appCtx2.xml"/>
    <import resource="classpath:appCtx3.xml"/>
    GenericXmlApplicationContext ctx = 
    new GenericXmlApplicationContext("classpath:appCtxImport.xml");

Bean의 범위

: Bean은 기본적으로 Singleton의 개념이다.
: getBean("A") 를 하면 Spring Container에 생성되어있는 A 객체를 참조하는 값을 가지고 올 뿐 객체를 새롭게 생성하는 것은 아니다.
: Singleton 과 반대대는 Prototype의 개념도 있는데, 이 방식을 적용하기 위해서는
<bean id="~" class="" scope="prototype"> </bean>을 해 주어야한다. (흔치 않음)

의존객체 자동주입

: 기존에는 <constructor-arg>, <property> 태그를 이용해 의존객체를 명시하였다.
: @Autowired, @Resource 어노테이션을 이용해 스프링 컨테이너가 자동으로 필요한 의존대상 객체를 찾아 의존 대상 객체가 필요한 객체에 주입해준다.
: 스프링 컨테이너 설정파일에 <context:annotation-config />를 기입해 주어야 한다.

  1. @Autowired

    • 주입하려고 하는 객체의 타입이 일치하는 객체를 자동으로 주입
    • 생성자, property(member), method에 쓸 수 있음
    • @Autowired 구문을 보면, 해당 구문에 필요한 객체의 데이터 타입을 갖고있는 빈 객체를 찾아 넣어준다.
      • @Autowired public void wordConstructor(WordDao wordDao) {} > **WordDao** wordDao
      • <bean id = "wordDao" class="com.word.dao.WordDao" /> > class="com.word.dao.WordDao"
  2. @Resource

    • 주입하려고 하는 객체의 이름이 일치하는 객체를 자동으로 주입
    • property(member), method에만 쓸 수 있음
    • 이름: private WordDao wordDao; 에서 변수명(wordDao)
    • @Autowired public void wordConstructor(WordDao wordDao) {} > WordDao **wordDao**
    • <bean id = "wordDao" class="com.word.dao.WordDao" /> > id = "wordDao"

의존객체 선택

: 동일한 객체가 2개 이상인 경우 스프링 컨테이너는 자동 주입 대상 객체를 판단하지 못해 Exception을 발생시킴

<bean id="wordDao" class="com.word.dao.WordDao">
   <qualifier value="useDao" />
</bean>
<bean id="wordDao2" class="com.word.dao.WordDao" />
<bean id="wordDao3" class="com.word.dao.WordDao" />

...

@Autowired
@Qualifier("useDao")
private WordDao wordDao;

: 위 처럼 @Qualifier 어노테이션을 사용하면 해결이 된다.

  • bean 객체에 태그에 value를 할당해 주면, @Qualifier를 만났을 때 해당 value에 매칭되는 bean 객체를 넣어준다.
    : 단, bean 객체의 id와 객체의 이름(변수명)이 일치할 경우 @Qualifier를 쓰지 않아도 되긴한다. 하지만 혼동을 줄 수 있으니 @Qualifier를 쓰도록하자.

의존객체 자동주입 체크

@Autowired(required = false)
private WordDao wordDao;

: 의존객체가 존재하면 주입하고, 없으면 주입하지마!
: required = false를 이용하면, 스프링컨테이너에서 bean 객체를 만들지 않았을 때 Exception이 발생하는 상황을 제거해 줄 수 있음
: 선호되는 방식은 아님

@Inject

: @Autowired와 동일한 기능을 제공하는 것으로, 의존 객체를 자동으로 주입할 수 있다.
: 차이점은, required 속성을 제공하지 않는다.
: 차이점은, @Qualifier 대신 @Named를 쓰며, 스프링컨테이너에서 qualifier 태그를 쓸 필요 없다.
: Autowired가 일반적으로 더 많이 쓰인다.

<bean id="wordDao1" class="com.word.dao.WordDao" />
<bean id="wordDao2" class="com.word.dao.WordDao" />
<bean id="wordDao3" class="com.word.dao.WordDao" />

@Inject
@Named(value="wordDao1")
private WordDao wordDao;

'Backend > Spring' 카테고리의 다른 글

Spring - 데이터베이스  (0) 2021.02.14
Spring - 세션과 쿠키 && 리다이렉트와 인터셉트  (0) 2021.02.09
Spring - MVC  (0) 2021.02.04
Spring - 스프링 컨테이너의 생성관련  (0) 2021.02.02
Spring - Dependency Injection  (0) 2021.01.31

학습하며 정리한 내용을 올리는 것이니, 참고용으로만 봐 주시길 바랍니다.
자바 스프링 프레임워크(renew ver.) - 신입 프로그래머를 위한 강좌

Dependency Injection

  1. 생성자를 이용한 DI
<bean id="studentDao" class="ems.member.dao.StudentDao" ></bean>


    <bean id="registerService" class="ems.member.service.StudentRegisterService">
        **<constructor-arg ref="studentDao" ></constructor-arg>**
    </bean>

: src/main/resources/applicationContext.xml 파일에 <constructor-arg ref="studentDao" >를 이용해 의존성 주입

  1. setter를 이용한 DI
public class DataBaseConnectionInfo {

    private String jdbcUrl;
    private String userId;
    private String userPw;

    public String getJdbcUrl() {
        return jdbcUrl;
    }

    ...
<bean id="dataBaseConnectionInfoDev" class="ems.member.DataBaseConnectionInfo">
        <property name="jdbcUrl" value="jdbc:oracle:thin:@localhost:1521:xe" />
        <property name="userId" value="scott" />
        <property name="userPw" value="tiger" />
    </bean>

: <property name="jdbcUrl" value= ... /> 를 이용해 주입

  1. List 타입 DI 주입
public void setDevelopers(List<String> developers) {
        this.developers = developers;
}
<bean id="informationService" class="ems.member.service.EMSInformationService">
    <property name="developers">
            <list>
                <value>Cheney.</value>
                <value>Eloy.</value>
                <value>Jasper.</value>
                <value>Dillon.</value>
                <value>Kian.</value>
            </list>
        </property>
  1. Map 타입 DI

    <property name="administrators">
            <map>
                <entry>
                    <key>
                        <value>Cheney</value>
                    </key>
                    <value>cheney@springPjt.org</value>
                </entry>
                <entry>
                    <key>
                        <value>Jasper</value>
                    </key>
                    <value>jasper@springPjt.org</value>
                </entry>
            </map>
        </property>

    : 아래와 같이 value 위치에 bean 객체를 넣을 수 있음

    <entry>    
    <key>
        <value>dev</value>
    </key>
    <ref bean="dataBaseConnectionInfoDev"/>
    </entry>

+ Recent posts