Spring application development and analysis process


최근 스프링개발환경은 많은 변화가 있었다. 고전적인 XML 설정방식외에도 JavaConfig 방식이 가능해졌고, 기존에 설정의 복잡함을 줄이기 위한 관례적인 설정을 자동으로 제공하는 자동설정Auto-configuration을 제공하는 스프링부트(http://projects.spring.io/spring-boot/) 프로젝트를 기반으로 한 애플리케이션 개발환경이 제공되고 있다.


1. 스프링애플리케이션 개발순서

  1. 스프링애플리케이션 기능설계

  2. 스프링 프로젝트 빌드

  3. web.xml 설정

    1. servlet 3.0+ 이상을 적용하는 경우에는 ServletInitializer를 통해서 web.xml 설정 대체가능

  4. 스프링 애플리케이션 컨텍스트ApplicationContext 설정

    1. application-context.xml(DAO, 서비스 영역)

      1. datasource 설정

      2. AOP 설정

    2. web-application-context.xml(웹 영영)

    3. security-context.xml(웹접근 인증 설정)

      1. URL과 사용자 권한을 기준으로 접근제어

  5. 애플리케이션 컨텍스트 정상설정 테스트

  6. MyBatis 를 사용하느냐, 하이버네이트등의 ORM 을 사용하느냐에 따라 DB 사용방식 달라짐

    1. MyBatis 인 경우에는 Database 에 스키마와 테이블들이 생성되어 있어야 함

      1. Mapper 클래스 및 SQL 을 설정해줘야 함

      2. iBatis 말고 MyBatis 사용을 권장: iBatis는 개발지원이 끝난지 꽤 되었음

      3. MyBatis와 관련된 부분은 MyBatis를 참고

    2. ORM인 경우에는 개발단계에서 ddl-auto 의 설정을 통해서 테이블 및 컬럼의 자동생성처리가 가능

      1. Spring Data JPA를 사용할 경우 기본적인 CRUD 처리를 JPARepository를 통해서 처리가 가능함

      2. 이와 관련된 자세한 내용은 자바 ORM 표준 JPA 프로그래밍 을 살펴보기

  7. 이후 애플리케이션의 패키지를 구성하고 기능별로 계층을 나눠 개발

io.honeymon.spring
  configuration
    - WebConfiguration.java
  domain
    - Member.java
    - Project.java
  repository
    - MemberRepository.java
    - ProjectRepository.java
  service
    - MemberService.java
    - DefaultMemberService.java
    - ProjectService.java
    - DefaultMProjectService.java
  web
    - MemberController.java
    - ProjectController.java
  common
    - FileUtils.java
    - DateUtils.java

위와 같은 형태로 기능별로 계층을 나눠 개발하기도 하고

io.honeymon.spring
  configuration
    - WebConfiguration.java
  member
    - Member.java
    - MemberRepository.java
    - MemberService.java
    - DefaultMemberService.java
    - MemberController.java
  project
    - Project.java
    - ProjectRepository.java
    - ProjectService.java
    - DefaultProjectService.java
    - ProjectController.java

와 같은 기능별 패키지로 나눠 개발하는 방식도 있습니다. 저도 최근에 이 방식으로 변환을 시도하고 있다.

위와 같은 형태로 개발을 진행합니다.

  1. 애플리케이션 개발에 있어서 MyBatis 보다는 JPA 사용을 선호함. MyBatis 는 4년전 이후로 사용해본 경험없음

  2. ORM을 기반으로 개발하면 엔티티 객체를 기반으로 해서 DB와의 매핑처리도 쉽고 기능구현도 쉬움.


스프링부트를 기반으로 개발하게 될 경우, 스프링과 관련된 설정의 부담감이 줄고 개발에 필요한 라이브러리들을 `Starter-POM`s 를 통해서 쉽게 처리가 가능하기 때문에 스프링 프레임워크에 대한 이해가 어느정도 있는 개발자에게는 스프링부트 사용을 권함

1.1. 화면개발

  1. 기본설정이 완료된 후에는 개발하는 화면에 따라 기능 구현 시작

  2. JSP 페이지 등의 템플릿 파일 작성

  3. Controller ModelAndView 에 템플릿 페이지 등록

    1. ajax 를 활용할 경우 화면처리를 담당할 컨트롤러와 데이터를 JSON으로 처리해줄 컨트롤러를 분리하면 좋음

    2. Spring 4.0 이후 @RestController 애노테이션이 생겨서 요청한 컨텐트타입으로 반환해주는 컨트롤러를 만들 수 있음

  4. 화면에 필요한 데이터를 담을 데이터들을 ModelAndView 혹은 템플릿엔진을 사용하는 경우에는 Model에 담아주면 ViewResolver에 의해서 처리됨

  5. 화면에 필요한 데이터에 따라서 Controller에서 Model에 담아주는 데이터가 달라지고 이는Service의 구현이 필요해짐

    1. 화면데이터에 따라 데이터, 서비스 가 달라짐

2. 스프링 애플리케이션 분석

2.1. 고전적인 XML 설정을 기반으로 한 경우

  1. web.xml 찾아서 애플리케이션 필터 설정들을 확인

  2. application-context.xml 혹은 *-context.xml 파일 분석

    1. application-context.xml: 파일은 보통 src/main/resource/META-INF에 위치

    2. web-application-context.xml: 파일은 보통 WEB-INF 에 위치

    3. 프로젝트를 설정한 사람에 따라 파일명이나 위치는 다를 수 있으므로 파일찾기를 통해서 찾아보기 바람

  3. DB 설정 확인

  4. 애플리케이션 패키지 구성 확인

  5. 애플리케이션을 구동하면서 찍히는 로그를 통해서 동작순서 확인

  6. 관련한 설정 확인

2.2. JavaConfig 인 경우

  1. @Configuration 애노테이션을 사용한 클래스 탐색

  2. 나머지 항목들은 고전적인 XML 설정을 기반으로 한 경우 와 동일

2.3. STS를 이용한 경우


STS: Spring Tool Suite http://spring.io/tools/sts
  1. spring explorer view 를 활용해서 각 설정빈을 확인 가능함

3. 참고자료


20141130 SpringSprout’s Last Conference

침대에서 뭉기적거리다가 일어나 눈을 뜨니 10시 반.
습관적으로 열어본 스마트폰에 올라와 있는 일정알림.
봄싹의 컨퍼런스가 있다는 것을 뒤늦게 인지한 나는 부랴부랴 씻고 밥먹고(점심시간 넘겨서 도착할테니, 밥은 먹고가야지)
정자동 네이버 그린팩토리를 향했다.

멀긴 멀다. ㅡ_-);; 전 회사는 1년여를 전철타고 왔다갔다 했었지.

내가 도착했을 때는 이미 세미나 중반쯤 다다른 상황이었다. 접수대에는 익숙한 얼굴들이 있었다.
그중 한 사람은 마지막 까지도 발표자료를 정리하느라 정신없었다.





Front-end development process


0123


  • 발표자: 변정훈(Outsider)
  • 발표자료: Adieu 2014, 봄싹에서 발표한 “프론트엔드 개발프로세스, 어디까지 개선할 수 있나” 발표자료

  • 게으른 개발자
    ‘게으른’과 ‘개발자’의 어울림
    개발자는 “1시간이면 할 일’을 ‘7~8시간동안 하는’ 사람이다.

  • 프론트엔드의 개발자동화는 서버사이드에 비해 많이 뒤쳐져 있었다.
    그러나 프론트엔드도 다양해지기 시작했다. 2~3년 사이에 빠르게 변화했다.
    그 중심에는 node.js 가 있다. 프론트엔드도 자동화된 개발프로세스를 가질 수 있는 환경을 가지게 되었다.
    언어에 대한 ‘커뮤니티, 문화’ 가 형성하는 문화였다?
    자바에서 쓰는 방법, 루비에서 쓰는 방법.
    node.js가 출현하면서 이런 환경이 생겨나기 시작했고, 2~3년의 짧은 기간 동안 일어나면서 앞으로도 빠른 변화가 일어날 것이다.

의존성 관리

  • 사용패턴
    1. 라이브러리 사이트 검색
    2. 프로젝트 폴더에 다운로드
    3. HTML에 코드 추가

      프로젝트, 라이브러리를 추가할 떄마다 반복

  • 패키지 매니저Package manager
    • Bower(http://bower.io, browserify(http://browserify.org)
      • browserify는 npm을 활용한다.

        도구들을 소개하지만 상세한 설명은 생략한다!

    • Bower 사용방법
      • bower install jquery bootstrap
      • 컴포넌트를 사용한다. 명령이 수행된 위치 하위에 component 폴더를 생성한다.
      • 노드의 npm과 유사
  • 패키지 매니저를 사용할 때의 장점
    • 라이브러리 파일을 형상관리에 넣지 않는다.
    • CSS나 JS가 아닌 컴포넌트 단위로 관리한다.
      = 도구들의 최근 배포형태가 JS, CSS 가 하나의 컴포넌트로 묶여 배포되는 형태에서는 ‘컴포넌트Component‘라는 이름이 이해가 된다.
    • 버전만 관리하면 필요에 따라 업데이트하기 쉽다.
    • 보통은 min 버전이 함께 제공한다.

웹서버 실행

  • 사용패턴
    • 로컬 파일을 브라우저에서 실행
    • Apache, nginx에 설정해서
    • WAS 실행(Tomcat 등)
      • 서버의 템플릿파일과 연동하여 보이는 것을 제공하지만,
      • 분리하는 것이 더욱 적합하다고 본다.
  • 빌드도구: Grunt와 Gulp
    • Grunt
      • grunt-contrib-connect, grunt-contrib-watch
  • 장점
    • 프로젝트 별로 필요한 환경을 자동화
    • 프로젝트 내에서 자동화된 환경을 공유
    • 다른 개발도구에 종속되지 않는다.
      • 에디터에 종속적인 기능?
    • CI 서버 등에서 사용할 수 있다.

코드의 품질관리


  • 여러가지 방법!?
    • Lint, Linting
  • recess!?
    recess style.css
    
  • JShint
    jshint util.js
    
  • Flow
    페이스북에서 내놓은 타입체크기
    /* @Flow */
    ...
    flow check hello.js
    

    Grunt를 이용한 설정을 할 수 있다.

Pre-processor

  • sass, less, coffeescript, stylus
  • 전처리자는 빌드가 필요하다. 빌드를 해서 그 결과물을 봐야한다.
    • grunt에 등록해두면 less를 수정할 때마다 자동으로 빌드되어, 브라우저에서는 자동빌드된 less의 결과물로 변경사항을 확인
  • 사용방법
    • 코드 수정
    • 빌드
    • 확인
    • 수정

Unit test

  • Assert: chai
  • test framework: mocha, jasmine
  • test runner: Karma
    • 브라우저에서는 별도로 실행할 방법이 없으나, Karma를 이용하면 실행해볼 수 있다.
    • 브라우저(지정한)를 띄워서 자동으로 불러들여서 실행시킨다.
    • socket.io와 브라우저가 연결되어 있어 자동으로 실행 및 확인이 가능하다.
    • 실행방법
      • 필요한 파일 로딩, socket.io로 쏘고~
  • 작성한 자동화 스크립트는 최대한 써먹자.
    • coveralls, BrowserStack, Gemnasium, SauceLabs

배포

  • 기존의 소스코드를 어떻게 배포할 것인가
  • 어떻게 사용하고 있는가?
    • CSS/JS 병합
    • CSS/JS 압축
    • HTML에서 링크변경
  • grunt
    • usemin
      • 압축대상 파일에 주석으로 build:와 endBuild로 처리가능하다.
      • 이게 JSP 에서도 적용이 될까… 했는데, JSP 하기전에 하면 되지.

정리

프론트엔드의 개발프로세스는 몇년 사이 매우 빠른 속도로 변화했다. node.js의 출현과 함께 npm의 패키지 관리 기능이 가져온 변화가 자바스크립트를 기반으로 하는 프론트엔드에 큰 변화를 가져왔으며, 그 변화는 앞으로도 지속될 것으로 보인다. 프론트엔드쪽에서도 백엔드와 마찬가지로 의존성을 관리하고 빌드, 배포를 자동화하려는 시도가 지속적으로 변화를 야기할 것이다. 다양한 자바스크립트 프레임워크들의 춘추전국시대가 당분간은 계속 될 것으로 보인다.

우선은, 현재에 사용목적에 적합하다고 생각되는 기술을 찾아 그것을 잘 활용하는 것에 집중하는 것만으로도 충반하다고 본다.


Resource Handling in Spring MVC

01234567


  • 발표자: 박용권(SK planet)
  • 발표자료: Slideshare
  • Github: resource-handling-in-springmvc

    Spring MVC에서 정적자원(css, js, etc)을 처리해본 경험을 공유
    프론트엔드에서 개발, 빌드된 정적자원을 백엔드에서 어떻게 가져와서 사용할 것인가?

Spring MVC: 리소스 제공(Serving)

  • ResourceHttpRequestHandler
  • 설정 간소화 기능제공
  • 리소스 제공 설정
     registry.addResourceHander("/resources/**").addResourceLocation("/resources/*")
    

    Spring Boot에서는 어떻게 설정할까나? -> classpath:를 붙여!!

     registry.addResourceHander("/resources/**").addResourceLocation("classpath:/resources/*")
    
     public class ResourceWebMvcConfiguration extends WebMvcConfigureAdapter {
     }
    

Resource 인터페이스에 대한 다양한 구현체

  • ServletCOntextResource
  • ClassPathResource
  • FileSystemResource
  • UrlResource
  • etc

캐시 설정이 가능하다.

registry.setCachePeriod(31556926); //캐시 주기는 1년이 적당하다!?
  • 로그를 보라~~
    • 캐시가 있을 때, 브라우저의 행동을 파악
    • 조건부 요청이 날아가는 경우!!

      웹을 확인하려고 하면,

Multi Module Web Application

  • Backend
    • SpringBoot
    • Thymeleaf
  • Frontend
    • NPM
    • Bower
    • Grunt
  • 핑거프린트(캐시에 대한 이야기, 두 파일의 내용, 조합)
  • assemble: hbs 파일들을 엮어서 HTML로…
  • 개발develop과 출시release 두가지의 형태로 처리
  • 개발에서는 usemin의 작업이 필요없다.

프론트엔드가 가출한 이유

  • 의존성관리
  • 사용된 라이브러리들의 모듈화, 조각으로 나누고 조합하여 사용한다.
  • 테스트
  • 빌드 자동화

    프론트엔드와 백엔드의 개발을 분리하여 진행

프론트엔드의 자원을 사용하는 방법

  • 프론트엔드의 의존성 다루기
  • WebJars
    • Client-side 웹 라이브러리를 JAR로 묶어서 제공하는 서비스
    • JVM 기반 빌드도구를 지원
  • Front-end를 빌드 후 jar로 만들기
    • 프론트엔드

개발 배포는 다르다.

  • 프론트엔드: 배포시에는 최적화된 자원을 사용한다.
  • 프론트엔드: 배포시에는 작성중인 css, js 사용
  • 백엔드: 환경에 따른 자원접근방법을 변경
    • Profile, Environment
    • 개발과 배포에 대한 캐시사용 전략도 변경하라~~ +_+)

회고

  • 학습의 요구곡선은 높아졌다.
  • 헨들바 + Thymeleaf만….

정리

코드에 금칠하던 냥겐의 비법공개의 느낌이랄까?

Spring Boot를 사용하면서 여기서 어떻게 더 나아갈까?

라는 고민을 하고 있던 찰라에 ‘희망의 빛’을 주는 발표였다.
지금 프로젝트는 Spring Boot를 기반으로 해서, 프로젝트의 resource 폴더에 static 폴더를 만들어 그 안에 css와 js 파일을 위치시켰는데, 생각해보니까 이녀석들을 최적화작업을 하고 하는 과정이 필요하다는 것을 간과했다. 두 개의 서브프로젝트로 나누고 프론트 프로젝트에서 최적화작업하고 그것을 백엔드 프로젝트에서 참조하는 형태로 가면 될 듯 싶다.


Building REST API Server

0123456


라이브 코딩!!

한국스프링의 살아있는 개발자, 백기선님의 발표!

  • 개발자 코드
  • ResponseEntity를 사용하면, HttpStatus 코드를 이용해서 응답상태를 결정지을 수 있어 좋다.

  • 크롬 확장플러그인: Postman 을 통해서 설정정보를 처리

  • DTO

    • static class Request {}
    • static class Response {}
  • ModelMapper 사용

    • Bean 등록
        @Bean
        public ModelMapper modelMapper() {
            return new ModelMapper();
        }
      

      Spock 과 MVC 테스트

  • spock-spring 추가

    • groovy 추가

      @ContextConfiguration(loader=SpringApplicationContextLoader.class, classes = Applications.class)
      @WebApplicationConfiguration
      public ExampleControllerTest extends Specification {
      @Autowired
      WebApplicationContext wac;
      
      def "POST /accounts"() {
           given:
        when:
        then:
      }
      }
      

      JSON으로 리턴할 때는 ObjectMapper(By Jackson)를 등록

  • Controller에 대한 테스트는 Spock를 사용해보자.

@Valid와 검증

  • 컨트롤러에서 @Valid ExampleDto exampleDto, BindingResult bindingResult 처리

스프링시큐리티 추가

  • starter-spring-security
  • Application을 재가동 시키면 스프링시큐리티가 켜져있다.
  • config 파일을 만들어서 WebSecurityConfigureAdapter를 생성
    @Configuration
    @EnableWebSecurity
    public class WebSecurityConfig extends WebSecurityConfigureAdapter {
      ..
      http.csrf().disabled();
      http.authorizeRequest()
      ...
    }
    
  • UserDetails 구현

    public class AccountUserDetails extends UserDetails {
    }
    
  • UserDetails를 제공할 서비스 생성

    @Service
    public AccountUserDetailsService implements UserDetailsService {
      @Autowired
      AccountRepository repository;
    }
    
  • WebSecurityConfig 에 userDetails 설정

    @Autowired AccountUserDetailService
    coufigure(AuthenBuilder auth) {
    ...
    }
    
  • 비밀번호 암호화
    @Bean
    public PasswordEncoder passwordEncoder() {
      return new StandardPasswordEncoder();
    }
    

패키징 및 배포

war로 패포하기 위해서는

  • build.gradle 혹은 pom.xml provide() 선언하고,
  • SpringBootServletInitializer 구현한 클래스를 선언하고
    public class ServletInitializer extends SpringBootServletInitializer {
      @Override
      protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
          return application.sources(Application.class);
      }
    }
    
    만들어진 war를 배포할 수 있다.

● 정리

SpringBoot는 스프링을 사용하는 사람이라면 결국 끌려들어올 수밖에 없는 블랙홀과 같은 강한 마력을 가지고 있다.
물론 이것을 바탕으로 보다 강력한 힘을 사용하기 위해서는 스프링에 대한 프레임워크가 어떻게 동작하는지 이해하고, 자바가 가지고 있는 언어의 특징을 이해하는 등의 학습이 필요하지만,

먼저 만들고 본다!

라는 논리로 보자면 Spring boot는 스프링을 기반으로 한 프로젝트를 구성할 때 부딪힐 수밖에 없는 설정의 벽을 많이 낮춰주는 것이 사실이다. 기선님의 라이브 코딩은 언제나 역동적이다. 이제는 능수능란하게 청중들과 반응하며 코딩을 이끌어가는 모습에서 라이브코딩의 관록을 느낀다.

따라올테면 따라와 봐.

라며 라이브코딩을 따라오던 자와의 신경전 또한 흥미로웠다. ㅎㅎ
스프링 시큐리티를 활용하는 방법에 대해서 힌트를 얻었다. 가볍게 던지는 이야기들 속에서 JavaConfig에 대한 막연했던 것들이 가볍게 정리되며 해소되는 이런 느낌 때문에 이런 컨퍼런스를 오게 되는 것이 아닐까?


Adieu, SpringSprout.


0123456789101112131415


  • 2008.08 스프링 스터디를 하기 위해 모여든 사람들.
  • 2008.08.31. 스프링 첫스터디 진행
  • 2009.03 KSUG 에서 봄싹 독립
  • 2009.06 봄싹 첫 MT
  • 2009.08.27 아지트가 생기다. 봄싹 사이트
  • 2010.07 봄싹을 떠나는 윤군!
  • 2010.11 ~2011.11 봄싹 스웨거 스터디 개설, 기존 스터디에 문제가 생기다.
    • 봄싹 스웨거
  • 2012.06 기선, 스터디 은퇴
  • 2014.08.20 봄싹이 싹을 피워 무럭무럭 자라서 멋진 이들로 제어났다.
  • 2014.11.30 봄싹 세미나, Adieu, 2014

○ 총정리




끊임없이 공부하고 코드로 만들어내는 배움의 장이었던 봄싹의 활동이 2014년 11월 30일, 그 대단원의 막을 내렸다.

이름처럼 새싹개발자들이 무럭무럭 성장하여 자신의 분야에서 한몫하는 멋진 개발자들로 성장하였다. 그들은 앞으로도 꾸준하게 개발자의 길을 걷고 있을 것이라 생각한다. ^^

나도 2011년도엔가 잠시 봄싹 스터디에 합류했다가 3주 정도 참여했다가 꼬리를 내리고 도망간 하드코어한 스터디그룹이었는데…
멋지게 유종의 미를 거둔, 봄싹의 마지막 컨퍼런스를 보면서 많은 사람들이 무엇인가를 얻어갔다는 것만으로도 충분히 보람찬 것이지 않을까?

모두 수고하셨습니다. ^^ 많은 가르침을 받았습니다.


+ Recent posts