728x90
반응형

12. 스프링 프레임워크 기본 강좌 (12) - 스프링MVC (고전적인 JSP 코딩)

 

* 스프링 MVC 샘플 코드를 보기 이전에 고전적인 JSP 코딩 방식을 보도록 하겠습니다.

 

// NoticeController.java (1단계 DB 제어 클래스를 통한 DB데이터 가져오기)

package controllers.customer;

public class NoticeController implements Controller { // 스프링이 제공 (Controller)

 

    @Override

    public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response)

        throws Exception {

 

        String _page = request.getParameter("pg");

        String _field = request.getParameter("f");

        String _query = request.getParameter("q");

 

        int page = 0;

        String field = "TITLE";

        String query = "%%"

 

        if(_page == null && _page.equals(""))            page = Integer.parseInt(_page);

        if(_field == null && _field.equals(""))               field = _field;

        if(_query == null && _query.equals(""))          query = _query;

 

        NoticeDao dao = new NoticeDao();

        List<Notice> list = dao.getNotices(page, field, query); // 페이지번호검색항목검색어

       

        ModelAndView mv = new ModelAndView("notice.jsp");

        mv.addObject("listData", list);

 

        return mv;

    }

}

 

실행 호출 notice.tst?pg={param.pg}&f={param.f}&q={param.q}

 

 - 코드 설명 -

 * NoticeDao 클래스는 DB 커넥션 개체를 생성하고, DB와 연결하며, 쿼리를 통해 데이터를 가져오는 작업을 처리하여 주는 클래스.
 * AOP개념이라고 볼 수 있는데 NoticeDao 를 통해서 DB 개체 생성, 접속, 쿼리 실행, 종료 등에 대한 처리를 위임한 클래스 개체를 만들어 사용.

 * Controller Interface 구현
 * Controller의 handleRequest 함수 구현 (XML에 매핑된 함수임)

 

// notice.jsp

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> // core library

<table>

<tbody>

<c:forEach var="n" items="${listData}">

    <tr>

        <td class="seq">${n.seq}</td> // n.getSeq();

        <td class="title"><href="noticeDetail.tst?seq=${n.seq}">${n.title}</td>

        <td class="writer">${n.writer}</td>

        <td class="writer">${n.regDate}</td>

        <td class="writer">${n.hit}</td>

   </tr>

</c:forEach>

</tbody>

</table>

 

* 참고로 JSP페이지에 스크립트릿, 표현식, HTML 등의 코드가 섞이게 되면 가독성이 떨어지게 되는데, 보다 가독성을 높이기 위한 언어 및 태그를 표현언어(EL, Expression Language) / JSTL 코드를 사용.

 

* ${n.seq} 는 실제 n.getSeq() 함수를 호출하는 것이며, 이 setter 함수는 이미 정의되어 있어야 함.
* EL은 $와 {}를 사용하여 값을 표현

참고 : JSTL – JSP Standard Tag Library
 - jsp 페이지에 스크립트릿과 표현식, html 코드등이 뒤섞이면 가독성이 낮아지게 되는데, 이때 태그 형태인 el과 jstl이나 커스텀태그를 사용하면 스크립트릿을 사용하는 것보다 가독성을 높일 수 있음. 표현언어(el)같은 경우는 톰캣 라이브러리에 기본적으로 포함되어 배포되기 때문에 별도로 라이브러리를 추가해주지 않아도 되지만, jstl같은 경우는 함께 제공되지 않기 때문에 따로 라이브러리를 추가해야 함.



출처: http://ooz.co.kr/223?category=818548 [이러쿵저러쿵]

728x90
반응형

'Web Programming > spring' 카테고리의 다른 글

Spring AOP with Annotation  (0) 2018.08.29
Spring AOP with XML  (0) 2018.08.29
Spring MVC Model2  (0) 2018.08.29
Spring 빈 후처리기  (0) 2018.08.29
Spring 포인트컷 조인포인트  (0) 2018.08.29
728x90
반응형

스프링 MVC (Model2)

 

* Front Controller : URL매핑을 담당. (어떠한 컨트롤러가 어떤 URL을 쓸것인가에 대한 설정 파일 포함) - 설정 파일을 통해서 적절한 컨트롤러를 호출. (Front Part : Servlet (DispatcherServlet.class))

* Controller : 화면 단에서 보여줄 데이터들을 미리 만들어 놓는 것. 그 데이터는 모델(Model)이라 함.
* Model : 데이터


Model, Controller, Front Controller, View 를 잘 구조화하는 것이 MVC 모델을 제어하고 있는 라이브러리가 할 역할.

 

[스프링 MVC의 개념도] 

 

 

[예제 코드]

 

// web.xml

<servlet>

    <servlet-name>dispatcher</servlet-name>

    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>

</servlet>

<servlet-mapping>

    <servlet-name>dispatcher</servlet-name>

    <url-pattern>*.oz</url-pattern>

</server-mapping>

 

// dispatcher-servlet.xml // 어떤 URL을 어떤 클래스에 매핑할 것인가?

<bean name="customer/notice.ozclass="controllers.customer.NoticeController"></bean>

 

// NoticeController.java

package controllers.customer;

public class NoticeController implements Controller { // 스프링이 제공 (Controller)

    @Override

    public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response)

         throws Exception  {

        ModelAndView mv = new ModelAndView("notice.jsp");

        mv.addObject("test", "hello");

        return mv;

    }

}

 

// notice.jsp

<div id="main"><h2>테스트 값 : ${test}</h2></div>

 

 

 

// 실행 및 결과

URL Call : localhost/customer/notice.oz   => 화면 출력 : hello

 

* 예지 코드는 게시판 MVC(스프링 MVC – 서블릿 DispatcherServlet)로 공지사항 리스트를 관리하고, 특정 번호의 공지사항을 열람하기 위한 공지사항 페이지를 구현. (스프링의 MVC의 개념을 설명하는데에 있어서 게시물 등록, 수정, 삭제 처리 함수는 크게 다른게 없으므로 생략.)

 

ModelAndView : Controller의 처리결과를 보여줄 View와 View에서 사용할 값을 전달하는 클래스.
ModelAndView의 mv 오브젝트는 web.xml에서 설정했었던 DispatcherServlet이 받아서 처리함.

${test} : 표현 언어 (JAVA 레벨(서버)의 변수를 Front(클라이언트)에 출력하기 위한 표현 언어)

 

 

[WEB.XML 이란?]

* Web Application 의 환경 파일(Deployment Description)

- XML 형식(XML Schema)의 파일로써, WEB-INF 폴더에 위치
- <web-app> 태그로 시작하고 종료하는 문서로써 web.xml 이 정의 된 Web Application의 동작과 관련된 다양한 환경 정보를 태그 기반으로 설정하는 파일.
- Servlet 2.3 까지 DTD 파일, 2.4 부터 XML Schema 파일 형태로 변경.

 

- WEB.XML 파일의 구성 내용
 1) ServletContext의 초기 파라미터
 2) Session의 유효시간 설정
 3) Servlet/JSP에 대한 정의
 4) Servlet/JSP 매핑
 5) Mime Type 매핑
 6) Welcome File list
 7) Error Pages 처리
 8) Listen/Filter 설정
 9) 보안



출처: http://ooz.co.kr/219?category=818548 [이러쿵저러쿵]

728x90
반응형

'Web Programming > spring' 카테고리의 다른 글

Spring AOP with XML  (0) 2018.08.29
Spring MVC jsp jstl  (0) 2018.08.29
Spring 빈 후처리기  (0) 2018.08.29
Spring 포인트컷 조인포인트  (0) 2018.08.29
Spring Advice  (0) 2018.08.29
728x90
반응형

* 빈 후처리기(Bean Post Processor)란?

 

 - 빈(Bean)의 설정을 후처리(postprocessing)함으로써 빈의 생명 주기와 빈 팩토리의 생명주기에 관여.
 - 빈의 초기화 되기 전, 초기화 된 후 2개의 기회를 제공.
 - 빈 프로퍼티의 유효성 검사 등에 사용.
 - 다른 초기화 메소드인 afterPropertiesSet()과 init-method가 호출되기 직전과 직후에 호출되어짐.

public interface BeanPostProcessor {

    Object postProcessBeforeInitialization(Object bean, String name) throws BeansException;

    Object postProcessAfterInitialization(Object bean, String name) trhows BeansException;

    ...

 

 

package com.sample;

public class Foo implements BeanPostProcessor {

    public void method1() {

        // 어떠한 작업..

    }

    Object postProcessBeforeInitialization(Object bean, String name) throws BeansException {

        // 초기화 되기 전 처리

    }

    Object postProcessAfterInitialization(Object bean, String name) throws BeansException; {

        // 초기화 된 후 처리

    }

 

Resource resource = new FileSystemResource("beans.xml");

BeanFactory factory = new XmlBeanFactory(resource);

BeanPostProcess foo = new Foo();

Factory.addBeanPostProcessor(fool);

 

 // beans.xml 개체

<bean id="fooclass="com.sample.Foo/>

 

Bean Factory를 IoC Container 로 사용하는 경우에는 단순히 addBeanPostProcessor() 메서드를 이용하여 프로그램 방식으로만 빈 후처리기(Bean Post Processor)를 등록함.

 

* 빈 후처리 과정 (Process of Bean Postprocessing)

 1) 빈 객체(Bean Instance) 생성 (생성자(Constructor) 또는 팩토리 메서드(Factory Method) 사용).

 2) 빈 프로퍼티(Bean Property)에 값과 빈 레퍼런스 설정.

 3) Aware Interface에 정의된 Setter 메서드 호출

 4) 빈 인스턴스(Bean Instance)를 각 빈 후처리기(Bean Post Processor)의 postProcessBeforeInitialization() 에 전달.

 5) 초기화 Callback 메서드 호출

 6) 빈 인스턴스(Bean Instance)를 각 빈 후처리기(Bean Post Processor)의 postProcessAfterInitialization() 에 전달.

 7) 빈 사용 준비 완료

 8) 컨테이너 종료 후, 소멸(Destructor) Callback 메서드 호출

 

[BeanFactory 인터페이스]

 - 빈 객체를 관리하고 각 빈 객체 간의 의존 관계를 설정해주는 기능 제공.

 - 가장 단순한 컨테이너.

[XmlBeanFactory 클래스]

 - 외부 자원으로부터 설정 정보를 읽어 와 빈 객체를 생성하는 클래스

 

덧붙여!

스프링의 빈 객체는 기본적으로 싱글톤(Singleton)으로 생성되는데, 그 이유는 사용자의 요청이 있을 때마다 애플리케이션 로직까지 모두 포함하고 있는 오브젝트를 매번 생성하는 것은 비효율 적이기 때문. 하나의 빈 객체(Bean Object)에 동시에 여러 스레드가 접근할 수 있기 때문에 상태 값을 인스턴스 변수에 저장해 두고 사용할 수 없음. 따라서 싱글톤의 필드에는 의존 관계에 있는 빈에 대한 참조(Reference)나 읽기 전용(Read-Only) 값만을 저장해 두고, 실제 오브젝트의 변화 상태를 저장하느 인스턴스 변수는 두지 않음. 애플리케이션 로직을 포함하고 있는 오브젝트는 대부분 싱글톤 빈(Singleton Bean)으로 만들면 충분함.

 

하지만, 하나의 빈 설정으로 여러 개의 오브젝트를 만들어서 사용하는 경우도 발생하게 되는데, 이 때는 싱글톤이 아닌 빈을 생성해야 함. 싱글톤이 아닌 빈은 프로토타입 빈(ProtoType Bean)과 스코프 빈(Scope Bean)이 있다.

 



출처: http://ooz.co.kr/217?category=818548 [이러쿵저러쿵]

728x90
반응형

'Web Programming > spring' 카테고리의 다른 글

Spring MVC jsp jstl  (0) 2018.08.29
Spring MVC Model2  (0) 2018.08.29
Spring 포인트컷 조인포인트  (0) 2018.08.29
Spring Advice  (0) 2018.08.29
Spring 디자인 패턴  (0) 2018.08.29
728x90
반응형

스프링 AOP (Aspect Oriented Programming)

 

포인트 컷 & 조인포인트

 

 - 위빙 (Weaving) : 보조업무가 프록시(Proxy)를 통해서 주 업무에 주입되는 것. 즉, 타깃 객체에 애스펙트를 적용해서 새로운 프록시 객체를 생성하는 절차.
 - 조인포인트 (Joint Point) : 위빙하게 되는 함수. 그 지점.

 - 포인트 컷 (PointCuts) : 객체의 특정 함수만 조인포인트 역할을 하도록 하는 것. 

 

 

* 이전 포스팅에서의 스프링 AOP 는 특정 객체(클래스)를 대상으로 타깃(Target)을 설정하였는데, 그렇기 때문에 프록시 적용이 해당 객체 단위 전체에 적용이 됨. 즉 타깃에 속한 모든 조인포인트에 보조 업무(Proxy Class)가 적용됨. 하지만, 포인트 컷을 활용하면 특정 클래스의 특정 함수에만 보조 업무를 삽입할 수 있음.

 

 

* 예제 코드

 

<bean id="cal" class="aoptest.TestCalculator"></bean>

<bean id="logPrintAroundAdvice" class="aoptest.LogPrintAroundAdvice"/>

<bean id="logPrintBeforeAdvice" class="aoptest.LogPrintBeforeAdvice"/>

<bean id="logPrintAfterReturningAdvice" class="aoptest.LogPrintAfterReturningAdvice"/>

<bean id="logPrintAfterThrowingAdvice" class="aoptest.LogPrintAfterThrowingAdvice"/>

 

<bean id="namePointcut" class="org.springframework.aop.support.NameMatchMethodPointcut">

<proporty name="mappedNames">

         <list>

              <value>add</value>

              <value>subtract</value>

          </list>

     </property>

</bean>

 

<bean id="nameAdvisor" class="org.springframework.aop.support.DefaultPointcutAdvisor">

      <property name="pointcut" ref="namePointcut"></property>

      <property name="advice" ref="logPrintAroundAdvice"></property>

</bean>

 

<bean id="proxy" class="org.springframework.aop.framework.ProxyFactoryBean">

    <property name="target" ref="cal"></property>

    <property name="interceptorNames">

        <list>

            <value>nameAdvisor</value>

            /* <value>logPrintAroundAdvice</value>

            <value>logPrintBeforAdvice</value>

            <value>logPrintAfterReturningAdvice</value>

            <value>logPrintAfterThrowingAdvice</value> */

        </list>

    </property>

</bean> 

 

 - 코드 설명 -

 

1)  특정 함수(add, subtract) 만 조인포인트 함수가 되도 록 포인트 컷 지정.
2) 특정 포인트 컷에 특정 어드바이스(핸들러) 지정.

 

어드바이저 = 포인트 컷 + 어드바이스


 

3) 특정 어드바이스(Advice) 대신 어드바이저(Advisor) 지정 가능.

 

TestCalculator : 주 업무(타깃) 클래스 (AOP처리가 필요한 클래스)
LogXXXAdvice : 어드바이스 클래스 (핸들러 클래스 – 주 업무 처리 이전, 이후 등 부가적인 업무를 처리할 클래스)
PointCut(mappedNames) : 주 클래스의 함수 중에 내가 어드바이스를 적용을 한정(포인트 컷 할)시킬 함수를 지정 (특정 함수에만  국한지어 적용)
Advisor(nameAdvisor) : 포인트컷과 어드바이스를 합친 어드바이저를 생성. 어드바이스 대신 어드바이저 사용가능.
Proxy : 타깃 클래스를 지정하고, 어드바이저(또는 어드바이스)를 적용할 것(interceptorNames)을 지정한 후, 대리 클래스 생성. ProxyFactoryBean을 통한 동적 프록시 생성.

참고로 어드바이저에는 여러 개의 어드바이스와 포인트 컷이 추가 될 수 있기 때문에 개별적으로 등록 시 어떤 어드바이스(부가기능)에 대해 어떤 포인트컷(메소드 선정)을 적용 할지 애매해진다. 그래서 어드바이스와 포인트 컷을 묶은 오브젝트를 어드바이저라고 부른다.

 

어드바이저 = 포인트컷(메소드 선정 알고리즘) + 어드바이스(부가 기능, 애스펙트의 한가지 형태)

 

  

<bean id="nameAdvisorclass="org.springframework.aop.support.NameMatchMethodPointcutAdvisor">

    <property name="pointcutref="namePointcut"></property>

    <proporty name="mappedNames">

         <list>

              <value>add</value>

              <value>substract</value>

          </list>

     </property>

     <property name="advice" ref="logPrintAroundAdvice"></property>

</bean>

 

 

// JAVA 정규식 표현을 활용한 포인트 컷 패턴 설정.  

<bean id="nameAdvisorclass="org.springframework.aop.support.RegexpMethodPointcutAdvisor">

    <property name="pointcutref="namePointcut"></property>

    <proporty name="patterns">

         <list>

              <value>.*a.*</value>

              <value>.*b</value>

          </list>

     </property>

     <property name="advice" ref="logPrintAroundAdvice"></property>

</bean>

 

 

* mappedName : 적용시킬 함수를 지정.
* mappedNames : 적용시킬 함수들을 지정.

예제 클래스에는 2개의 함수(add, substract) 밖에 없지만, 함수가 상당히 많은 경우, 패턴을 사용하는 것이 더 효율적일 수 있다. 그룹핑을 통해 어떤 어드바이스(Advice)만 실행되게 할 것인지도 한정할 수도 있다.

[정규식 특수 문자 의미]

. : 어떠한 문자든 상관없다. (한개의 문자가 옴)
* : 임의의 문자가 0개 이상 올 수 있다. (한개 이상의 문자가 옴)

 

 

* 위빙, 조인포인트, 포인트컷을 다시 한 번 상기시키자면

위빙 : 크로스 컷팅 되어 있는 관심사(Concern)를 다시 결합하는 것.
조인포인트 : 위빙하는 함수들이 있는 곳 지점, 시점 (스프링에서는 메소드만을 조인 포인트로 사용함.)

포인트 컷 : 부가 기능 적용 대상 메서드 선정 방법. 내가 원하는 메서드만 골라서 조인포인트 역할을 하도록 함. (단, 포인트 컷을 통해 특정 타깃 함수와 어드바이스를 매 하나씩 연결해야 한다면 설정 파일의 용량도 커지고, 함수가 많아지게 되면 관리도 어려워질 수 있음.)

 

 * 스프링에서의  조인 포인트 특징!
  - 분리하고 도킹하는 것이 자유로움.
  - 조인포인트를 쓸 수 있는 것이 Method에 한정.

 



출처: http://ooz.co.kr/216?category=818548 [이러쿵저러쿵]

728x90
반응형

'Web Programming > spring' 카테고리의 다른 글

Spring MVC Model2  (0) 2018.08.29
Spring 빈 후처리기  (0) 2018.08.29
Spring Advice  (0) 2018.08.29
Spring 디자인 패턴  (0) 2018.08.29
Spring 동적 Proxy  (0) 2018.08.29
728x90
반응형

스프링에서의 AOP (Aspect-Oriented Programming)

 

1) 개념

 

* 스프링은 4가지 형태의 핸들러(어드바이스, Advice)를 제공.
* 스프링에서는 핸들러를 어드바이스(Advice)라는 개념으로 사용.

 

 

 

 

 * JAVA 레벨이 아닌 XML을 통해 객체를 생성하고, 인젝션(Injection)함
 

 

[코드 간략 설명] 

 - 스프링 프레임워크에서 제공해주는 핸들러(어드바이스) : MethodeInterceptor

 - MethodeInterceptor : Around Advice 사용할 때, 구현해야 하는 인터페이스.

 - MethodeInterceptor 는 InvocationHandler 와 동일한 기능을 수행하나 차이점은 InvocationHandler 의 경우에는 프록시할 타깃 객체를 InvocationHandler 인터페이스 구현 객체가 알고 있어야 하나, MethodInterceptor 의 경우에는 MethodInvocation 객체가 타깃 객체와 호출된 메소드 정보를 모두 알고 있음.
 - 인터페이스(Interface)는 스프링 프레임워크에서 알아서 감지(Auto Detecting)하여 연결해줌. 그러므로 위의 Proxy Bean 객체 XML 코드에서 aoptest.Calculator 부분(파란색)은 제거해도 무방함.
 - 스프링 프레임워크는  Invoke 대신 proceed 메서드를 호출하여 주 업무 프로세스를 호출함. / 또한 스프링 프레임워크는 핸들러(Handler) 대신 어드바이스(Advice)를 생성.

 

* 어드바이스(Advice) 란?

 - 타깃 오브젝트(Target Object)에 적용할 부가 기능을 담은 오브젝트

 - 메인 업무에 보조적으로 추가될 보조 업무.

 

 

[XML 레벨로 보조 업무 연결 코드가 이동하면서 JAVA 코드가 단순해짐]

 

 * 위의 X 표시된 코드는 주석처리하고 AOP를 활용하여 Advice 를 적용한 JAVA 코드

 * 객체의 생성과 조립을 메인 함수에서 코드에서 관리하였지만, 부가적인 파트(객체 생성과 의존성)는 XML 파일로 이동시킴.
 * XML 빈 객체의 이름 및 속성을 변경함으로써, 기존 코드에 바로 적용 가능.
 * 부가 코드와 주 코드를 분리하여 필요할 때 도킹(Docking)하여 사용 가능.
 * 위와 같은 동적 프록시(Dynamic Proxy)는 ApplicationContext의 getBean 메서드를 통해서 개체를 얻어옴.

 

 

2) 스프링 프레임워크에서의 4가지 형태의 Advice

 

 



출처: http://ooz.co.kr/213?category=818548 [이러쿵저러쿵]

728x90
반응형

'Web Programming > spring' 카테고리의 다른 글

Spring 빈 후처리기  (0) 2018.08.29
Spring 포인트컷 조인포인트  (0) 2018.08.29
Spring 디자인 패턴  (0) 2018.08.29
Spring 동적 Proxy  (0) 2018.08.29
Spring AOP Proxy  (0) 2018.08.29

+ Recent posts