스프링의 변천사 그리고 Java 9 과 Spring 5 (2)

2. 스프링의 위기와 극복

2-1. 첫 번째 위기

과도한 기술로 복잡해진 코드(J2EE, EJB)

J2EE, EJB 규약을 통해 애플리케이션을 개발했다.
J2EE, EJB 규약은 너무 복잡하고 많은 클래스를 상속하고 의존하도록 강제되어 있어
좋은 객체지향 애플리케이션을 만들기 어렵게 되어 있었다.
이 문제를 해결하기 위해 스프링은 IoC, DI, 서비스 추상화 기술을 도입해
좋은 객체지향 애플리케이션을 개발할 수 있도록 했다.

// EJB 에서만 동작하는 기술에 종속된 코드
public class Client {
  public callService() {
    Context jndiContext = getInitialContext();

    Object ref = jndiContext.look("MyserviceHomeRemote");
    MyServiceHomeRemote home = (MyServiceHomeRemote) PortableRemoteObject.narrow(ref, MyServiceHomeRemoate.class);

    MyServiceRemote myService = home.create();

    myService.service()
  }
}

2-2. 두 번째 위기

자바 언어에 대한 발전 요구와 호환성(.NET)

새롭게 개발된 닷넷과 같은 언어에 비해 제공하는 기능이 부족해 자바 언어(~1.4 버전)의 발전이 요구되었다.
자바는 이전 버전과의 호환성을 지키면서 제네릭스 애노테이션 등 다양한 기능을 추가한 1.5 버전을 개발했다.
즉, 이전 버전으로 작성된 바이트 코드를 다시 컴파일 할 필요 없이 실행할 수 있다.

2-3. 세 번째 위기

간경한 코드와 관례로 무장한 기술의 습격(루비, 레일즈)

애노테이션 기반 프로그래밍과 영리한 설정으로 간결하게 애플리케이션을 만들 수 있는 언어와 프레임워크가 등장했다.
설정을 최소화 하고 관례를 우선한 루비와 레일즈는 15분 만에 블로그를 만들 수 있었다.

스프링은 이 문제를 애노테이션 기반의 메타프로그래밍과
영리한 디폴트로 무장한 관례를 적극 도입한 스프링부트를 통해 극복했다.

@Controller
public class HelloWorldController {
  @RequestMapping("/helloWorld")
  public String helloWorld(Model module) {
    model.addAttribute("message", "Hello World!");
    return "helloWorld";
  }
}

2-4. 네 번째 위기

함수형 프로그래밍과 비동기 논 블로킹 개발의 도전

스칼라, 자바스크립트 같은 함수형 언어와 비동기 논블로킹에 최적화된 Node.js 의 등장했다.
그리고 대용량 비동기 분산 시스템 개발에 적합한 함수형 프로그래밍 필요성이 대두 되었다.

함수형 프로그래밍 스타일의 Java 8 과 비동기 논블록킹을 지원하는 서블릿을 사용하는 스프링이 등장했다.
Java 8 은 함수형 인터페이스와 람다식, 메소드 레퍼런스, 디폴트 메소드, CompletableFuture 을 지원한다.
Servlet 3.0 은 비동기 웹 요청 처리 방식을 지원하고 비동기 논블로킹 IO 를 지원한다.

@GetMapping("/service")
DeferredResult<String> service() {
  DeferredResult dr = new DeferredResult();

  ListenableFuture<String> lf = myService.async();
  lf.addCallback(r -> dr.setResult(r), e -> dr.setErrorResult(e));

  return dr;
}