본문 바로가기
IT/Spring

[Spring][전문가를 위한 스프링 5] CH2. 스프링 시작하기

by 강천구 2022. 8. 15.

전문가를 위한 스프링 5(Pro Spring 5) - Ch 2. 스프링 시작하기

2.1 스프링 프레임워크 가져오기

Maven, Gradle 같은 빌드 도구를 사용 || Github에서 Spring Library Checkout 후 사용

사용하려는 Spring에 적절한 JDK 사용하기

JVM(Java Virtual Machine) : 구현이 필요한 abstract machine, 자바 바이트 코드가 실행될 수 있는 실행 환경 제공하는 사양

JRE(Java Runtime Environment) : 실행 환경을 제공하는데 사용, JVM의 실제 구현체

JDK(Java Development Kit) : JRE, 메뉴얼 및 자바 도구들을 담고 있는 것

JDK12 이상, Spring 5.1.8 사용


2.2 스프링 모듈 이해하기

Spring 5.1.x.RELEASE는 21개의 모듈 제공

(aop, aspects, beans, beans-groovy, context, context-indexer, context-support, core, expression, instrument, jcl, jdbc, jms, messaging, orm, oxm, test, tx, web, webflux, web-mvc, websocket)

 

Maven

리소스 처리, 컴파일, 테스트, 패키징 등 application의 모든 빌드 라이프사이클 관리

 

Maven Pom.xml 예제

<project xmlns="http://maven.apache.org/POM/4.0.0"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
   http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.apress.prospring5.ch02</groupId>
  <artifactId>hello-world</artifactId>
  <packaging>jar</packaging>
  <version>5.0-SNAPSHOT</version>
  <name>hello-world</name>
 
<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <spring.version>5.0.0.RELEASE</spring.version>
  </properties>
  <dependencies>
      <!-- https://mvnrepository.com/artifact/log4j/log4j -->
        <dependency>
                <groupId>log4j</groupId>
                <artifactId>log4j</artifactId>
                <version>1.2.17</version>
        </dependency>
  </dependencies>
  <build>
    <plugins>
    	<plugin> 
        ...
        </plugin>
    </plugins>
  </build>
</project>

 

디렉토리 구조도

 

Gradle

Gradle build.gradle 예제

group 'com.apress.prospring5.ch02'
version '5.0-SNAPSHOT'
apply plugin: 'java'
repositories {
    mavenCentral()
}
ext{
        springVersion = '5.0.0.RELEASE'
}
tasks.withType(JavaCompile) {
    options.encoding = "UTF-8"
}
dependencies {
    compile group: 'log4j', name: 'log4j', version: '1.2.17'
... }

 

반응형

 

2.3 스프링 문서 사용하기

스프링의 모든 기능이 자바독으로 완전히 문서화될 뿐만 아니라 각 배포판에 포함된 레퍼런스 매뉴얼에도 모든 기능이 담겨져 있다.


2.4 스프링으로 Hello World 애플리케이션 만들기

1. 단순 hello world 출력 

package com.apress.prospring5.ch2;

public class HelloWorld {
    public static void main(String... args) {
        System.out.println("Hello World!");
    }
}

2. 명령줄 인자로 메시지 내용 전달

package com.apress.prospring5.ch2;

public class HelloWorldWithCommandLine {
    public static void main(String... args) {
        if (args.length > 0) {
            System.out.println(args[0]);
        } else {
            System.out.println("Hello World!");
        }
    }
}

3-1. Message 출력 및 가져오는 로직 리팩토링 후 각각의 컴포넌트로 분리

package com.apress.prospring5.ch2.decoupled;

public interface MessageProvider {
    String getMessage();
}
package com.apress.prospring5.ch2.decoupled;

public interface MessageRenderer {
    void render();
    void setMessageProvider(MessageProvider provider);
    MessageProvider getMessageProvider();
}

3-2. 인터페이스 구현체

package com.apress.prospring5.ch2.decoupled;

public class HelloWorldMessageProvider implements MessageProvider {
    @Override
    public String getMessage() {
        return "Hello World!";
    }
}
package com.apress.prospring5.ch2.decoupled;

public class StandardOutMessageRenderer implements MessageRenderer {
    private MessageProvider messageProvider;
    @Override
    public void render() {
        if (messageProvider == null) {
            throw new RuntimeException(
                "You must set the property messageProvider of class:"
                + StandardOutMessageRenderer.class.getName());
        }
        System.out.println(messageProvider.getMessage());
    }
    
    @Override
    public void setMessageProvider(MessageProvider provider) {
        this.messageProvider = provider;
    }
    
    @Override
    public MessageProvider getMessageProvider() {
        return this.messageProvider;
    }
}

3-3. 로직 분리한 메인 함수 

package com.apress.prospring5.ch2.decoupled;

public class HelloWorldDecoupled {
    public static void main(String... args) {
        MessageRenderer mr = new StandardOutMessageRenderer();
        MessageProvider mp = new HelloWorldMessageProvider();
        mr.setMessageProvider(mp);
        mr.render();
    }
}

변경된 추상 스키마

4-1. 속성파일에서 가져다 인스턴스로 만드는 팩터리 클래스 및 속성 파일(msf.properties)

package com.apress.prospring5.ch2.decoupled;
import java.util.Properties;

public class MessageSupportFactory {
    private static MessageSupportFactory instance;
    private Properties props;
    private MessageRenderer renderer;
    private MessageProvider provider;
    private MessageSupportFactory() {
        props = new Properties();
        try {
            props.load(this.getClass().getResourceAsStream("/msf.properties"));
            String rendererClass = props.getProperty("renderer.class");
            String providerClass = props.getProperty("provider.class");
            renderer = (MessageRenderer) Class.forName(rendererClass).newInstance();
            provider = (MessageProvider) Class.forName(providerClass).newInstance();
        } catch (Exception ex) {
            ex.printStackTrace();
        }
	}
    static {
        instance = new MessageSupportFactory();
	}
    
    public static MessageSupportFactory getInstance() {
    	return instance;
    }

	public MessageRenderer getMessageRenderer() {
    	return renderer;
    }
    
    public MessageProvider getMessageProvider() {
    	return provider;
    }
}
renderer.class=com.apress.prospring5.ch2.decoupled.StandardOutMessageRenderer
provider.class=com.apress.prospring5.ch2.decoupled.HelloWorldMessageProvider

4-2.  변경에 따른 main 함수 변경

package com.apress.prospring5.ch2.decoupled;

public class HelloWorldDecoupledWithFactory {
    public static void main(String... args) {
        MessageRenderer mr =
              MessageSupportFactory.getInstance().getMessageRenderer();
        MessageProvider mp =
              MessageSupportFactory.getInstance().getMessageProvider();
        mr.setMessageProvider(mp);
        mr.render();
    }
}

 

5. 스프링으로 리팩토링 및 spring 구성 파일(app-context.xml)

package com.apress.prospring5.ch2;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class HelloWorldSpringDI {
	public static void main(String args) {
    	ApplicationContext ctx = new ClassPathXmlApplicationContext("spring/app-context.xml");
		MessageRenderer mr = ctx.getBean("renderer", MessageRenderer.class);
		mr.render();
	}
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:p="http://www.springframework.org/schema/p"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd">
  <bean id="provider"
        class="com.apress.prospring5.ch2.decoupled.HelloWorldMessageProvider"/>
  <bean id="renderer"
        class="com.apress.prospring5.ch2.decoupled.StandardOutMessageRenderer"
        p:messageProvider-ref="provider"/>
</beans>

6. annotation을 사용한 구성

package com.apress.prospring5.ch2.annotated;

import com.apress.prospring5.ch2.decoupled.HelloWorldMessageProvider;
import com.apress.prospring5.ch2.decoupled.MessageProvider;
import com.apress.prospring5.ch2.decoupled.MessageRenderer;
import com.apress.prospring5.ch2.decoupled.StandardOutMessageRenderer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class HelloWorldConfiguration {
	// equivalent to <bean id="provider" class=".."/>
    @Bean
    public MessageProvider provider() {
        return new HelloWorldMessageProvider();
    }
    
    // equivalent to  <bean id="renderer" class=".."/>
    @Bean
    public MessageRenderer renderer(){
        MessageRenderer renderer = new StandardOutMessageRenderer();
        renderer.setMessageProvider(provider());
        return renderer;
    }
}
package com.apress.prospring5.ch2.annotated;

import com.apress.prospring5.ch2.decoupled.MessageRenderer;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class HelloWorldSpringAnnotated {
	public static void main(String... args) {
    	ApplicationContext ctx = new AnnotationConfigApplicationContext(HelloWorldConfiguration.class);
        MessageRenderer mr = ctx.getBean("renderer", MessageRenderer.class);
        mr.render();
    }
}

 

Github : https://github.com/Apress/pro-spring-5/tree/master/chapter02

 

GitHub - Apress/pro-spring-5: Source code for 'Pro Spring 5' by Iuliana Cosmina, Rob Harrop, Chris Schaefer, and Clarence Ho

Source code for 'Pro Spring 5' by Iuliana Cosmina, Rob Harrop, Chris Schaefer, and Clarence Ho - GitHub - Apress/pro-spring-5: Source code for 'Pro Spring 5' by Iuliana Cosmina, Rob...

github.com

 


2.5 정리

스프링 DI를 이용하여 전통적인 애플리케이션을 결합도를 낮추고, 확장 가능한 애플리케이션으로 변경

반응형

댓글