Chapter1. 스프링 속으로

1.1 자바 개발 간소화

1.1.1 POJO 의 힘

POJO: Plain Old Java Object. 어느 컨벤션이나 프레임워크의 요구사항이 전혀 없는 보통 자바 오브젝트

ex) extends, implements, annotations, ... 등을 제거한 오브젝트

  • POJO 를 이용한 가볍고(lightwight) 비침투적(non-invasive)인 개발

1.1.2 종속객체 주입

DI: Dependency Injection. 구성요소간의 종속관계를 외부에서 주입하는 패턴

Setter, Interface, 그리고 Constructor based injection 을 흔히 볼 수 있다.

  • DI와 인터페이스 지향(interface orientation)을 통한 느슨한 결합도(loose coupling)

1.1.3 애스펙트 적용

AOP: Aspect-Oriendted Programming. 비즈니스 로직에서 2차적 또는 보조 기능들을 분리시키는 개발 방법. 이렇게 분리시킨 모듈을 필요한 곳에 삽입하되, 코드 밖에서 설정한다.

로깅, 인증, 보안, 트랜잭션 관리, 메소드 성능검사, 예외반환, ... 같은 공동 모듈

  • 애스펙트와 공통 규약을 통한 선언적(declarative) 프로그래밍

1.1.4 템플릿을 이용한 상투적인 코드 제거

  • 애스펙트와 템플릿(template)을 통한 반복적인 코드 제거

1.2 빈을 담는 그릇, 컨테이너

  • 스프링 기반 애플리케이션에서는 스프링 컨테이너(Spring Container) 안에서 객체가 태어나고, 자라고, 소멸한다.
    • DI 을 이용해서 애플리케이션을 구성하는 컴포넌트를 관리.
  • 크게 2가지로 분류된다.
    • 빈 팩토리(BeanFactory)
    • 애플리케이션 컨텍스트(Application Context)

1.2.1 또 하나의 컨테이너, 애플리케이션 컨텍스트

1.2.2 빈의 일생

enter image description here

1.3 스프링 현황

1.3.1 스프링 모듈

spring module

  1. Core container

    어플리케이션에서 빈의 생성, 설정 그리고 처리방법을 관리하는 컨테이너. 이 모듈 내에서 DI를 제공하는 스프링 빈 팩토리를 확인한다. 이 외에도 이메일, JNDI 액세스, EJB통합, 스케쥴링 등 다양한 엔터프라이즈 서비스도 제공한다. 모든 스프링 모듈은 코어 컨테이너 위에 구축되므로 암묵적으로 코어모듈을 사용한다.

  1. Data Access/Integration

    • JDBC : spring-jdbc

      데이터 access시 커넥션을 얻어오고, 질의객체를 생성하고 결과집합을 처리하고 커넥션을 닫는 작업을 반복한다. JDBC와 DAO 모듈은 이렇게 반복되는 코드를 추상화하고 리소스 관리를 해준다.

    • ORM : spring-orm

      ORM모듈은 JDBC보다 객체관계 매핑 도구를 선호하는 사람들을 위한 모듈이다. 직접 ORM 솔루션 구현보다는 hibernate, java persistence, mybatis와 같은 ORM 프레임웍과의 연결고리를 제공해준다.

    • OXM : spring-oxm

      객체 - XML 매핑

    • JMS : spring-jms

    • Transaction : spring-tx

      AOP모듈을 이용하여 객체들의 트랜젝션을 관리한다.

  2. web
    • Web
    • Web-MVC
    • Web-Socket
    • Web-Portlet
  3. etc

    • AOP
    • Aspects

      AOP 모듈을 통해 aspect 지향 프로그래밍을 풍부하게 지원한다. AOP는 주로 애플리케이션의 전체 걸친 관심사 ( 트랜잭션, 보안, 로깅 etc)와 객체 간의 결합도를 낮추는데 이용된다.

    • Instrumentation

       > JVM에 에이젼트를 추가하는 기능을 제공한다. 정확히는 톰캣용 위빙 에이젼트 제공. (좀더 찾아보자)
      
    • Messaging

    • Test

       > 단위테스트를 위한 모의객체 구현이나 어플리케이션 컨텍스트에서 빈을 로드하고 이 컨텍스트에 있는 빈과의 작업을 지원한다.
      

1.3.2 스프링 포트폴리오

  1. 스프링 웹 플로

    웹 어플리케이션의 네비게이션 흐름제어 구축을 지원합니다.

  2. 스프링 웹 서비스

    SOAP 웹 서비스 개발을 용이하게 합니다.

  3. 스프링 시큐리티

    포괄적이고 확장 가능한 인증 및 인가를 지원하여 애플리케이션을 보호합니다.

  4. 스프링 인티그레이션

    엔터프라이즈 인티그레이션 패턴을 지원합니다.

  5. 스프링 배치

    대량 배치작업에 대해 간결하고 최적화된 처리를 합니다.

  6. 스프링 데이터

    데이터 접근에 대한 일관된 방식을 제공합니다. 관계형, 비관계형, 맵리듀스 등

  7. 스프링 소셜

    페이스북, 트위터, 링크드인과 같은 서드파티 API와 쉽게 연결해줍니다.

  8. 스프링 모바일

    장비 탐지 및 진보적인 랜더링 옵션을 통해 모바일 웹 어플리케이션 개발을 간편하게 합니다.

  9. 안드로이드 스프링

    안드로이드 개발에 사용되는 스프링 컴포넌트를 제공합니다.

  10. 스프링 부트

    스프링 애플리케이션을 구축하고 빠르게 실행 가능한 독단적인 뷰를 제공합니다.

Spring Framework Artifacts

GroupId ArtifactId Description
org.springframework spring-aop Proxy 기반 AOP 지원
org.springframework spring-aspects AspectJ 기반 스프링 aspect
org.springframework spring-beans Bean 지원
org.springframework spring-context 애플리케이션 컨텍스트의 런타임 구현 , 스케쥴 지원
org.springframework spring-context-support 스프링과 서드파티 라이브러리간의 통합 지원
org.springframework spring-core Core 유틸리티
org.springframework spring-expression 스프링 표현 언어 (SpEL)
org.springframework spring-instrument JVM 부트 스트래핑을 위한 instrumentation agent
org.springframework spring-instrument-tomcat Instrumentation agent for Tomcat
org.springframework spring-jdbc 데이터 소스 설정과 JDBC 액세스 지원하는 JDBC 패키지
org.springframework spring-jms 동기식 JMS 액세스와 메시지 리스너 컨테이너를 지원
org.springframework spring-messaging 메시징 아키텍쳐와 프로토콜 지원
org.springframework spring-orm JPA, hibernate 등의 ORM 지원
org.springframework spring-oxm Object/XML 매핑
org.springframework spring-test 유닛테스트 또는 integration 테스트 지원
org.springframework spring-web web 기능 지원
org.springframework spring-webmvc 웹 어플리케이션을 위한 REST웹 서비스 및 MVC 구현체
org.springframework spring-webmvc-portlet 포틀릿 환경의 MVC 구현체
org.springframework spring-websocket WebSocket, sockJS 구현체 (STOMP 지원)
org.springframework.webflow spring-webflow 스프링 웹 플로워
org.springframework.ws spring-ws-core 스프링 웹 서비스
org.springframework.security spring-security-web 스프링 시큐리티 (spring aop)
org.springframework.integration spring-integration-core 스프링 인티그레이션
org.springframework.batch spring-batch-core 스프링 배치
org.springframework.data spring-data-releasetrain 스프링 데이터
org.springframework.social spring-social-facebook, spring-social-twitter 스프링 소셜
org.springframework.mobile spring-mobile-device 스프링 모바일
org.springframework.android spring-android-rest-template 스프링 소셜
org.springframework.boot spring-boot-starter-web 스프링 부트

spring life cycle

life cycle

spring 처리 흐름

flow

1.4 스프링 새로운 기능

1.4.1 Spring 3.1

  1. Cache Abstraction

    • Cache enable
       <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:cache="http://www.springframework.org/schema/cache"
        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
             http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd">
    
       <cache:annotation-driven />
       ...
     </beans>
    
    • @Cacheable , @CacheEvict
    @Cacheable("books")
     public Book findBook(ISBN isbn) {...}
    
     // use property 'rawNumber' on isbn argument as key
     @Cacheable(value="book", key="#isbn.rawNumber")
     public Book findBook(ISBN isbn, boolean checkWarehouse, boolean includeUsed)
    
    // cache only names shorter then 32 chars
     @Cacheable(value="book", condition="#name.length < 32")
     public Book findBook(String name)
    
     // evict all cache entries
     @CacheEvict(value = "books", allEntries=true)
     public void loadBooks(InputStream batch)
    
  2. Bean Definition Profiles

      @Configuration
     @Profile("production")
     public class JndiDataConfig {
    
         @Bean
         public DataSource dataSource() throws Exception {
             Context ctx = new InitialContext();
             return (DataSource) ctx.lookup("java:comp/env/jdbc/datasource");
         }
     }
    
  3. Environment Abstraction

    • datasource-config.xml

      <beans profile="dev">
         <jdbc:embedded-database id="dataSource">
             <jdbc:script location="classpath:com/bank/config/sql/schema.sql"/>
             <jdbc:script location="classpath:com/bank/config/sql/test-data.sql"/>
         </jdbc:embedded-database>
      </beans>
      <beans profile="production">
         <jee:jndi-lookup id="dataSource" jndi-name="java:comp/env/jdbc/datasource"/>
      </beans>
      
    • web.xml
     <context-param>
         <param-name>spring.profiles.active</param-name>
         <param-value>production</param-value>
     </context-param>
    
    • JVM option
    -Dspring.profiles.active="production"
    
  4. PropertySource Abstraction

    <context:property-placeholder location="com/bank/config/datasource.properties"/>
    
     <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
         <property name="driverClass" value="${database.driver}"/>
         <property name="jdbcUrl" value="${database.url}"/>
         <property name="username" value="${database.username}"/>
         <property name="password" value="${database.password}"/>
     </bean>
    
  5. Code equivalents for Spring's XML namespaces

      자주 사용하는 <context:component-scan/>, <tx:annotation-driven/>, <mvc:annotation-driven>의 
      스프링 XML 네임스페이스 엘리먼트와 동일한 기능을 대부분 @Enable 어노테이션의 형식으로 사용할 수 있다. 
      이 기능은 스프링 3.0에서 도입된 @Configuration 클래스와 결합해서 사용하도록 설계했다.
    
  6. TestContext framework support for @Configuration classes and bean definition profiles

     @ContextConfiguration 어노테이션은 이제 스프링 TestContext를 설정하는 @Configuration 클래스를 제공한다. 
     새로 추가된 @ActiveProfiles 어노테이션은 ApplicationContext 통합테스트에서 엑티브 빈 선언 프로파일을 
     선언적으로 설정을 지원한다.
    
  7. c: namespace for more concise constructor injection

     <beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:c="http://www.springframework.org/schema/c"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans.xsd">
    
       <bean id="bar" class="x.y.Bar"/>
       <bean id="baz" class="x.y.Baz"/>
    
       <-- 'traditional' declaration -->
       <bean id="foo" class="x.y.Foo">
           <constructor-arg ref="bar"/>
           <constructor-arg ref="baz"/>
           <constructor-arg value="[email protected]"/>
       </bean>
    
       <-- 'c-namespace' declaration -->
       <bean id="foo" class="x.y.Foo" c:bar-ref="bar" c:baz-ref="baz" c:email="[email protected]">
    
     </beans>
    
  8. Support for Servlet 3 code-based configuration of Servlet Container

    • 전통적인 web.xml을 프로그래밍적으로 대체하는 서블릿 3.0의 ServletContainerInitializer에 기반을 둔 WebApplicationInitializer를 새로 추가했다
  9. New HandlerMethod-based Support Classes For Annotated Controller Processing

    • RequestMappingHandlerMapping <-- DefaultAnnotationHandlerMapping
    • RequestMappingHandlerAdapter <-- AnnotationMethodHandlerAdapter
    • ExceptionHandlerExceptionResolver <--- AnnotationMethodHandlerExceptionResolver
  10. "consumes" and "produces" conditions in @RequestMapping

    • 'Accept'헤더로 지정된 타입을 만드는 것(produce)과 마찬가지로 'Content-Type'헤더로 지정된 미디어타입을 메서드로 소비(consume)하는 것에 대한 지원이 개선
  11. Flash Attributes and RedirectAttributes

  12. Support for injection against non-standard JavaBeans setters
  13. JPA EntityManagerFactory bootstrapping without persistence.xml
  14. Support for Servlet 3 MultipartResolver
  15. Support for Hibernate 4.x
  16. URI Template Variable Enhancements
  17. @RequestPart Annotation On Controller Method Arguments
  18. @Valid On @RequestBody Controller Method Arguments
  19. UriComponentsBuilder and UriComponents
  20. 3.1-release-notes 참고

1.4.2 Spring 3.2

  1. Support for Servlet 3 based asynchronous request processing
  2. Spring MVC Test framework
  3. Content negotiation improvements
  4. @ControllerAdvice annotation

     @ControllerAdvice
     public class GlobalExceptionController {
    
         @ExceptionHandler(CustomGenericException.class)
         public ModelAndView handleCustomException(CustomGenericException ex) {
    
             ModelAndView model = new ModelAndView("error/generic_error");
             model.addObject("errCode", ex.getErrCode());
             model.addObject("errMsg", ex.getErrMsg());
             return model;
         }
    
         @ExceptionHandler(Exception.class)
         public ModelAndView handleAllException(Exception ex) {
    
             ModelAndView model = new ModelAndView("error/generic_error");
             model.addObject("errMsg", "this is Exception.class");
             return model;
         }
     }
    
  5. Matrix variables

    // GET /owners/42;q=11;r=12/pets/21;q=22;s=23
    
     @RequestMapping(value = "/owners/{ownerId}/pets/{petId}")
     public void findPet(
         @MatrixVariable Map<String, String> matrixVars) {
    
         // matrixVars: ["q" : [11,22], "r" : 12, "s" : 23]
     }
    
  6. Abstract base class for code-based Servlet 3+ container initialization

         public class MyWebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
    
         @Override
         protected Class<?>[] getRootConfigClasses() {
             return null;
         }
    
         @Override
         protected Class<?>[] getServletConfigClasses() {
             return new Class[] { MyWebConfig.class };
         }
    
         @Override
         protected String[] getServletMappings() {
             return new String[] { "/" };
         }
     }
    
  7. ResponseEntityExceptionHandler class

     @ControllerAdvice 
     public class ResthubExceptionHandler extends ResponseEntityExceptionHandler {
    
         @ExceptionHandler(value={ 
                 IllegalArgumentException.class,
                 ValidationException.class,
                 NotFoundException.class, 
                 NotImplementedException.class 
         }) 
         public ResponseEntity<Object> handleCustomException(Exception ex, WebRequest request) {
    
             HttpHeaders headers = new HttpHeaders();
             HttpStatus status;
    
             if (ex instanceof IllegalArgumentException) {
                 status = HttpStatus.BAD_REQUEST;
             } else if (ex instanceof ValidationException) {
                 status = HttpStatus.BAD_REQUEST;
             } else if (ex instanceof NotFoundException) {
                 status = HttpStatus.NOT_FOUND;
             } else if (ex instanceof NotImplementedException) {
                 status = HttpStatus.NOT_IMPLEMENTED;
             } else { 
                 logger.warn("Unknown exception type: " + ex.getClass().getName());
                 status = HttpStatus.INTERNAL_SERVER_ERROR;
                 return handleExceptionInternal(ex, null, headers, status, request);
             } 
             return handleExceptionInternal(ex, buildRestError(ex, status), headers, status, request);
         } 
    
         private RestError buildRestError(Exception ex, HttpStatus status) {
             RestError.Builder builder = new RestError.Builder();
             builder.setCode(status.value()).setStatus(status.getReasonPhrase()).setThrowable(ex);
             return builder.build();
         } 
     }
    
  8. Support for generic types in the RestTemplate and in @RequestBody arguments
  9. Jackson JSON 2 and related improvements
  10. Tiles 3
  11. @RequestBody improvements
  12. HTTP PATCH method
  13. Excluded patterns in mapped interceptors
  14. Using meta-annotations for injection points and for bean definition methods
  15. Initial support for JCache 0.5
  16. Support for @DateTimeFormat without Joda Time & Global date & time formatting
  17. New Testing Features
  18. Concurrency refinements across the framework
  19. New Gradle-based build and move to GitHub
  20. Refined Java SE 7 / OpenJDK 7 support
  21. 3.2-release-notes 참고

1.4.3 Spring 4.0

  1. Improved Getting Started Experience
  2. Removed Deprecated Packages and Methods
  3. Java 8 (as well as 6 and 7) & Java EE 6 and 7
  4. Groovy Bean Definition DSL

    def reader = new GroovyBeanDefinitionReader(myApplicationContext)
     reader.beans {
         dataSource(BasicDataSource) {
             driverClassName = "org.hsqldb.jdbcDriver"
             url = "jdbc:hsqldb:mem:grailsDB"
             username = "sa"
             password = ""
             settings = [mynew:"setting"]
         }
         sessionFactory(SessionFactory) {
             dataSource = dataSource
         }
         myService(MyService) {
             nestedBean = { AnotherBean bean ->
                 dataSource = dataSource
             }
         }
     }
    
  5. Core Container Improvements
  6. General Web Improvements
  7. WebSocket, SockJS, and STOMP Messaging
  8. Testing Improvements

    • Meta-Annotation Support for Testing
     @Target(ElementType.TYPE)
     @Retention(RetentionPolicy.RUNTIME)
     @ContextConfiguration({"/app-config.xml", "/test-data-access-config.xml"})
     @ActiveProfiles("dev")
     @Transactional
     public @interface TransactionalDevTest { }
    
     @RunWith(SpringJUnit4ClassRunner.class)
     @TransactionalDevTest
     public class OrderRepositoryTests { }
    
  9. 4.0-release-notes 참고

1.5 Sample Project

$ git clone [email protected]:adel-yang/SpringStudy.git
$ gradle jettyRun

Access http://localhost:8080/

results matching ""

    No results matching ""