IT/Spring

Spring Boot 란

최고영회 2019. 12. 13. 13:11
728x90
반응형
SMALL

EJB의 몰락과 Spring Framework 의 등장


J2EE 기반의 EJB(Enterprise Java Beans)는 너무 좋은 설계를 가지고 있음에도 너무 어렵다는 이유로 외면 당하고 있었다.
이때 등장한 것이 Spring Framework 이며 EJB 프로젝트와는 다르게 쉽고, 경량성을 강조하면서 가볍게 동작하도록 제작된 Framework 으로 각광을 받았다.
 - Spring의 핵심기술: POJO, DI, IoC, AOP, PSA
표준인 EJB는 외면당했고 비표준인 오픈 프레임워크인 Spring을 환영 받으면서 Spring 이 마치 표준처럼 사용되기 시작한다.
Java로 Back-end를 개발하기 위해서는 Spring Framework는 거의 필수가 되었다.

 

Spring Boot의 등장


Spring은 지원하는 라이브러리, 하위프로젝트들이 늘어나면서 무거워지고 있으며 초기 설정이 많아 초보자가 처음 프로젝트를 구성하는 데 많은 어려움이 있다.
ex) 웹어플리케이션을 개발하고자 할 때 어느 라이브러리를 추가해줘야 하는가?
유지보수하기에는 문제가 없으나 초기 개발 환경설정이 너무 힘들어졌고 한번 구성해 놓은 프로젝트의 구성을 그대로 Copy/Paste 하는 일이 발생하게 된다.

Spring Boot는 자주 사용하는 프로젝트 조합을 미리 만들어 놓아서 Spring을 더욱 쉽고 간단하게 사용하기 위해 만들어 졌으며 최소한의 초기 Spring 구성으로 가능한 빠르게 시작하고 실행할 수 있도록 설계 되었다. 

 

Spring Boot의 특징


CoC (Convention over Configuration)

"설정보다는 관례"
웹어플리케이션을 개발하고자 할 때 어느 라이브러리를 추가해줘야 하는가?
일일히 관련 라이브러리를 찾아 추가할 필요 없이 spring-boot-starter-web을 추가해 주면 관련 라이브러리를 받아온다.
많은 Framework(Spring, Ruby on Rails, Symphony 등)이 CoC 패러다임을 사용하고 있다.

설정 자동화

초기에 @EnableAutoConfiruation 이 있었고 이는 SpringBoot의 마법이라고 불리운다. (알아서 설정해 주니까..)
현재는 @EnableAutoConfiguration + @SpringBootConfiguration + @ComponentScan 으로 구성되어 있는 @SpringApplication 이라는 더욱 강력해진 어노테이션을 사용한다.

@SpringBootApplication @EnableAsync public class Decide7Application { public static void main(String[] args) { SpringApplication.run(Decide7Application.class, args); } }

@SpringBootApplication 
@EnableAsync 
public class Decide7Application { 
  public static void main(String[] args) { 
    SpringApplication.run(Decide7Application.class, args); 
  } 
}

 

@Target(ElementType.TYPE) 
@Retention(RetentionPolicy.RUNTIME) 
@Documented 
@Inherited 
@SpringBootConfiguration 
@EnableAutoConfiguration 
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class), @Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) }) 
public @interface SpringBootApplication { 
  /*** Exclude specific auto-configuration classes such that they will never be applied. 
     * @return the classes to exclude 
  */ 
  @AliasFor(annotation = EnableAutoConfiguration.class) 
  Class<?>[] exclude() default {};
  

 

서버 내장

Tomcat, Undertow, Jetty 와 같은 서버를 내장하여 SpringApplication.run(App.class, args); 명령어로 서버를 시작할 수 있다.

 

자동 설정 이해하기

팩토리 로딩 매커니즘 - 스프링프레임워크 내부


SpringApplication에서는 스프링프레임워크의 팩토리 로딩 매커니즘을 사용해서 단계별 필요한 객체들을 생성을 하고 Order 를 통해서 각 객체간 순서를 조정한다.

클래스 로더내에서 여러 jar 파일들의 클래스패스상에 있는 META-INF/spring.factories에 파일들을 로딩 후 지정된 타입에 맞는 팩토리 클래스를 획득

`SpringFactoriesLoader.loadFactoryNames(Class<?> factoryClass, ClassLoader classLoader); `

아래 내용은 spring-boot-xx.jar 파일의 META-INF/spring.factories의 파일 내용 일부

`# PropertySource Loaders 
org.springframework.boot.env.PropertySourceLoader=\ 
org.springframework.boot.env.PropertiesPropertySourceLoader,\ 
org.springframework.boot.env.YamlPropertySourceLoader 

# Run Listeners org.springframework.boot.SpringApplicationRunListener=\ 
org.springframework.boot.context.event.EventPublishingRunListener 

# Application Context Initializers 
org.springframework.context.ApplicationContextInitializer=\ 
org.springframework.boot.context.ConfigurationWarningsApplicationContextInitializer,\ 
org.springframework.boot.context.ContextIdApplicationContextInitializer,\ 
org.springframework.boot.context.config.DelegatingApplicationContextInitializer,\ 
org.springframework.boot.context.embedded.ServerPortInfoApplicationContextInitializer 
`

SpringApplication 란


자바 메인 메소드에서 어플리케이션(스프링기반)을 실행할 수 있는 클래스이며 대략적으로 아래와 같이 동작을 수행함.

  • ApplicationContext생성
  • 커맨드 라인 인자를 스프링 속성으로 표시하는 CommandLinePropertySource 등록
  • 모든 싱글턴 빈의 로드 및 생성
  • 모든 CommandLineRunner 빈 실행

SpringApplication은 크게 생성 및 실행단계로 나눌 수 있음.

SpringApplication 생성 및 실행 예제 코드

@SpringBootApplication 
public class Application { 
  public static void main(String[] args) throws DbxException { 
    //빌더를 이용한 방법 
    SpringApplicationBuilder applicationBuilder = new SpringApplicationBuilder(Application.class); 
    SpringApplication application = applicationBuilder.build(); 
    application.run(args); 
    
    //static 메소드를 이용한 방법 
    SpringApplication.run(Application.class,args); 
  } 
}

1.생성 단계


1.1 환경 분석

클래스로더에서 아래 타입이 로드가능한지 여부를 통해 Web 환경인지 아닌지 검사를 진행한다.
이는 향후 ApplicationContext를 생성할 때 어떤 구현체로 생성할지 여부를 결정하는 값으로 사용된다.

javax.servlet.Servlet 
org.springframework.web.context.ConfigurableWebApplicationContext

1.2 ApplicationContextInitializer 설정

스프링의 팩토리 로딩 매커니즘을 이용해서 ApplicationContextInitializer.class 타입으로 지정된 객체들을 생성한다.
상기 META-INF/spring.factories파일 기준으로 생성되는 클래스들은 아래와 같다.

  • org.springframework.boot.context.ConfigurationWarningsApplicationContextInitializer
  • org.springframework.boot.context.ContextIdApplicationContextInitializer
  • org.springframework.boot.context.config.DelegatingApplicationContextInitializer
  • org.springframework.boot.context.embedded.ServerPortInfoApplicationContextInitializer

1.3 ApplicationListener 설정

스프링의 팩토리 로딩 매커니즘을 이용해서 ApplicationListener.class 타입으로 지정된 클래스들을 생성한다.

2.실행 단계


2.1 SpringApplicationRunListener 생성

팩토리 로딩 매커니즘을 통해 SpringApplicationRunListener.class타입에 지정된 객체들을 생성한다.
SpringApplicationRunListener 는 SpringApplication.run 함수에서의 세부 단계에 대한 행동들을 정의한 인터페이스이다.

public interface SpringApplicationRunListener { 
  /** 
   * Called immediately when the run method has first started. Can be used for very 
   * early initialization. 
  */ 
  void starting(); 
  
  /** 
   * Called once the environment has been prepared, but before the 
   * {@link ApplicationContext} has been created. 
   * @param environment the environment 
  */ 
  void environmentPrepared(ConfigurableEnvironment environment); 
  
  /** 
   * Called once the {@link ApplicationContext} has been created and prepared, but 
   * before sources have been loaded. 
   * @param context the application context 
  */ 
  void contextPrepared(ConfigurableApplicationContext context); 
  
  /** 
   * Called once the application context has been loaded but before it has been 
   * refreshed. 
   * @param context the application context 
  */ 
  void contextLoaded(ConfigurableApplicationContext context); 
  
  /** 
   * Called immediately before the run method finishes. 
   * @param context the application context or null if a failure occurred before the 
   * context was created 
   * @param exception any run exception or null if run completed successfully. 
  */ 
  void finished(ConfigurableApplicationContext context, Throwable exception); 
}

2.2 환경 수집

실행인자로 주어진 아큐먼트에서 프로퍼티 값 수집 후 SpringApplicationRunListener.environmentPrepared 메소드를 실행한다.

2.3 ApplicationContext 생성

생성할 ApplicationContext이 지정되어 있지 않으면, 생성단계에서 판단한 WEB환경 여부에 따라 아래와 같이 ApplicationContext를 생성한다.

  • WEB 환경이면 org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext
  • WEB 환경이 아니면 org.springframework.context.annotation.AnnotationConfigApplicationContext

2.4 prepareContext

  • ApplicationContextInitializer 들의 초기화 메소드 호출
  • SpringApplicationRunListener.contextPrepared 호출
  • SpringBoot 전용 하기 Bean생성
    • "springApplicationArguments","springBootBanner"
  • BeanDefinitionLoader 생성 후 load() 함수 호출
  • SpringApplicationRunListener.contextLoaded 호출

2.5 refreshContext

  • 실제 Bean 생성이 되는 부분
    • 정확하게 알지는 못하지만 BeanDefinitionLoader를 통해서 BeanDefinition 생성
    • BeanDefinition 에 있는 Bean 생성을 위한 정보를 토대로 Bean을 생성함

2.6 afterRefresh

  • 생성된 ApplicationContext에 생성된 Runner타입(아래 항목)에 해당되는 Bean을 획득 후 실행
    • ApplicationRunner.class
    • CommandLineRunner.class
  • Runner Bean 들은 Order로 설정된 순서대로 실행된다

 

기타사항


  • SpringApplicationBuilder를 이용하면 SpringApplication의 세부 사항들을 조절 할 수 있다. ApplicationContext의 구현체를 지정하거나 ApplicationListener 등도 조정 가능하다.
  • 스프링부트의 AutoConfiguration 기능은 여러 오픈 소스들을 지원하고 기본적인 설정등을 해준다.
    • 서비스에 적용하려면 이 부분을 개발자가 커스텀 할 수 있어야 한다.(스프링부트에서는 커스텀 할 수 있는 방법을 제공을 한다)
  • 많은 스프링 프로젝트들은 스프링부트의 AutoConfiguration을 지원하기 위해 META-INF/spring.factories 파일에 해당 내용을 정의하고 있다.(아래는 예시)
`# Auto Configure 
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ 
org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,\ 
.... 
org.springframework.boot.autoconfigure.data.cassandra.CassandraDataAutoConfiguration,\ 
org.springframework.boot.autoconfigure.data.cassandra.CassandraRepositoriesAutoConfiguration,\ 
org.springframework.boot.autoconfigure.data.couchbase.CouchbaseDataAutoConfiguration,\ 
org.springframework.boot.autoconfigure.data.couchbase.CouchbaseRepositoriesAutoConfiguration,\ 
org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchAutoConfiguration,\ 
org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchDataAutoConfiguration,\ 
org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchRepositoriesAutoConfiguration,\ 
org.springframework.boot.autoconfigure.data.jpa.JpaRepositoriesAutoConfiguration,\ 
org.springframework.boot.autoconfigure.data.ldap.LdapDataAutoConfiguration,\ 
org.springframework.boot.autoconfigure.data.ldap.LdapRepositoriesAutoConfiguration,\ 
org.springframework.boot.autoconfigure.data.mongo.MongoDataAutoConfiguration,\ 
.... 
`
  • 스프링부트의 actuator 는 어플리케이션의 상태 및 모니터링에 대한 여러 기능을 제공을 한다.
    어플리케이션에 상태 체크에 이용시 유용하다.
728x90
반응형
LIST