ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Back End] Spring Core
    Web Development/부스트코스 - Back-End(Java) 2020. 3. 25. 19:20

    Spring

    • 자바 플랫폼을 위한 오픈 소스 애플리케이션 프레임워크이다.

    • 엔터프라이즈급 애플리케이션을 구축할 수 있는 가벼운 솔루션이자 One-Stop-Shop 이다.

    • 원하는 부분만 가져다 사용할 수 있도록 모듈화가 잘 되어 있다.

    • IoC 컨테이너이다.

    • 선언적으로 트랜잭션을 관리할 수 있다.

    • 완전한 기능을 갖춘 MVC Framework를 제공한다.

    • AOP를 지원한다.

    • 스프링은 도메인 논리 코드와 쉽게 분리될 수 있는 구조로 되어 있다. 

     

    Spring 프레임워크 모듈

    • 스프링 프레임워크는 약 20개의 모듈로 구성되어 있다. 필요한 모듈만 가져다 사용할 수 있다.

     

    AOP 와 Instrumentation

    • spring-AOP : AOP 얼라이언스(Alliance)와 호환되는 방법으로 AOP를 지원합니다.

    • spring-aspects : AspectJ와의 통합을 제공합니다.

    • spring-instrument : 인스트루멘테이션을 지원하는 클래스와 특정 WAS에서 사용하는 클래스로 더 구현체를 제공합니다. 참고로 BCI(Byte Code Instrumentations)은 런타임이나 로드(Load) 때 클래스의 바이트 코드에 변경을 가하는 방법을 말합니다.

    Messaging

    • spring-messaging : 스프링 프레임워크 4는 메시지 기반 어플리케이션을 작성할 수 있는 Message, MessageChannel, MessageHandler 등을 제공합니다. 또한, 해당 모듈에는 메소드에 메시지를 맵핑하기 위한 어노테이션도 포함되어 있으며, Spring MVC 어노테이션과 유사합니다.

    Data Access / Integration

    • 데이터 엑세스/통합 계층은 JDBC, ORM, OXM, JMS 및 트랜잭션 모듈로 구성되어 있다.

    • spring-jdbc : 자바 JDBC프로그래밍을 쉽게 할 수 있도록 기능을 제공합니다.

    • spring-tx : 선언적 트랜잭션 관리를 할 수 있는 기능을 제공합니다.

    • spring-orm : JPA, JDO및 Hibernate를 포함한 ORM API를 위한 통합 레이어를 제공합니다.

    • spring-oxm : JAXB, Castor, XMLBeans, JiBX 및 XStream과 같은 Object/XML 맵핑을 지원합니다.

    • spring-jms : 메시지 생성(producing) 및 사용(consuming)을 위한 기능을 제공, Spring Framework 4.1부터 spring-messaging모듈과의 통합을 제공합니다.

     

    Web

    • 웹 계층은 spring-web, spring-webmvc, spring-websocket, spring-webmvc-portlet 모듈로 구성됩니다.

    • spring-web : 멀티 파트 파일 업로드, 서블릿 리스너 등 웹 지향 통합 기능을 제공한다. HTTP클라이언트와 Spring의 원격 지원을 위한 웹 관련 부분을 제공합니다.

    • spring-webmvc : Web-Servlet 모듈이라고도 불리며, Spring MVC 및 REST 웹 서비스 구현을 포함합니다.

    • spring-websocket : 웹 소켓을 지원합니다.

    • spring-webmvc-portlet : 포틀릿 환경에서 사용할 MVC 구현을 제공합니다.

     

    Container(컨테이너)

    • 컨네이너는 인스턴스의 생명주기를 관리하며, 생성된 인스턴스에게 추가적인 기능을 제공한다.

    • 예를들어 Servlet을 실행하는 WAS는 Servlet 컨테이너를 가지고 있다고 말한다.

    • WAS는 웹 브라우저로부터 Servlet URL에 해당하는 요청을 받으면, Servlet을 메모리에 올린 후 실행한다. 

    • Servlet 컨테이너는 동일한 Servlet에 해당하는 요청을 받으면, 다시 Servlet을 메모리에 올리지 않고 기존에 메모리에 올려져있던 Servlet을 실행해서 그 결과를 웹 브라우저에게 전달한다.

    IoC(Inversion of Control)

    • 컨테이너는 코드 대신 오브젝트의 제어권을 갖고 있다. 이를 IoC(제어의 역전)이라고 한다.

    • 예를들어, Serlvet 클래스는 개발자가 만들지만 그 Servlet의 메소드를 알맞게 호출하는 것은 WAS이다.

    • 이렇게 개발자가 만든 어떤 클래스나 메소드를 다른 프로그램이 대신 실행 해주는 것을 제어의 역전이라고 한다.

    DI(Dependency Injection)

    • Dpendency란 두 클래스 간의 관계이다. 일반적으로 둘 중 하나가 다른 하나를 어떤 용도를 위해 사용한다. 

    • DI는 의존성 주입이란 뜻을 가지고 있으며, 클래스 사이의 의존 관계를 Bean 설정 정보를 바탕으로 컨테이너가 자동으로 연결 해주는 것을 말한다. 

    • DI는 객체간의 의존성을 자신이 아닌 외부에서 주입해주는 개념이다. DI를 컨테이너에게 위탁함으로서 소스 코드의 변경을 용이하게 한다. 이는 유지보수 측면에서 유용하다.

    예시 1 : DI가 적용되지 않음.  Car 클래스에서 Engine 인스터스를 직접 생성한다.

    class Engine {
    
    }
    
    class Car {
         Engine v5 = new Engine();
    }

     

     

     

    예시 2 : DI가 적용 됨. 어노테이션을 통해  spring 컨테이너가 v5 변수에 Engine 인스턴스를 자동으로 할당해준다. 

    @Component
    class Engine {
    
    }
    
    @Component
    class Car {
         @Autowired
         Engine v5;
    }

     

     

     

     

    Spring에서 제공하는 Ioc/DI 컨테이너

    • BeanFactory : IoC/DI에 대한 기본 기능을 가지고 있다.

    • ApplicationContext : BeanFactory의 모든 기능을 포함하며, 일반적으로 BeanFactory보다 추천된다. 트랜잭션처리, AOP등에 대한 처리를 할 수 있다. BeanPostProcessor, BeanFactoryPostProcessor등을 자동으로 등록하고, 국제화 처리, 어플리케이션 이벤트 등을 처리할 수 있다.

    • BeanPostProcessor : 컨테이너의 기본로직을 오버라이딩하여 인스턴스화와 의존성 처리 로직 등을 개발자가 원하는 대로 구현 할 수 있도록 한다.

    • BeanFactoryPostProcessor : 설정된 메타 데이터를 커스터마이징 할 수 있다.

    Java Bean

    • 데이터를 표현하는 것을 목적으로 하는 Java Class

    • Java Bean 규격서에 따라 작성된 자바 클래스를 말한다.

    • 일반적인 Java 클래스를 Bean 클래스라고 보통 말한다.

    • Bean class는 기본 생성자를 가지고 있다.

    • 필드는 private 하게 선언한다.

    • getter, setter 메소드를 가진다.

    • getName() setName() 메소드를 name 프로퍼티(property)라고 한다. 

    Spring Bean

    • Spring 컨테이너가 관리하는 객체를 Bean(빈)이라고 한다.

    • 직접 new 연산자를 통해 생성하는 객체는 Bean이라고 하지 않는다.

    • Spring은 Bean을 생성할 때 기본적으로 싱글톤(Singleton) 객체로 생성한다.

    • 싱글톤이란 인스턴스를 메모리에 하나만 생성한다는 것 이다.

     

    Spring에서 IoC, DI 설정하기 1 : XML 파일을 이용한 설정

     

    Engine.java

    package kr.or.connect.diexam01;
    
    public class Engine {
    	public Engine() {
    		System.out.println("Engine 생성자");
    	}
    	
    	public void exec() {
    		System.out.println("엔진이 동작합니다.");
    	}
    }

     

    Car.java

    package kr.or.connect.diexam01;
    
    public class Car {
    	Engine v8;
    	
    	public Car() {
    		System.out.println("Car 생성자");
    	}
    	
    	public void setEngine(Engine e) {
    		this.v8 = e;
    	}
    	
    	public void run() {
    		System.out.println("엔진을 이용하여 달립니다.");
    		v8.exec();
    	}
    }

     

    위의 Car 클래스가 제대로 동작하도록 하려면 보통 아래와 같은 코드가 작성되어야 한다.

    Engine e = new Engine();
    Car c = new Car();
    c.setEngine(e);
    c.run();

     

    아래와 같은 Xml 파일 설정을 통해 위 코드를 Spring 컨테이너가 처리하도록 한다.

     

    applicationContext.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
    	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    	<bean id="userBean" class="kr.or.connect.diexam01.UserBean"></bean>
    	<bean id="e" class="kr.or.connect.diexam01.Engine"></bean>
    	<bean id="c" class="kr.or.connect.diexam01.Car">
    		<property name = "engine" ref = "e"></property>
    	</bean>
    </beans>

     

    위의 XML 파일 설정은 아래와 같은 의미를 가진다.

    Engine e = new Engine();
    Car c = new Car();
    c.setEngine( e );

     

    그럼 이제 XML 파일 설정을 했으니 예제를 실행 해보자.

     

     ApplicationContextExam02.java

    package kr.or.connect.diexam01;
    
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    public class ApplicationContextExam02 {
    
    	public static void main(String[] args) {
    		ApplicationContext ac = new ClassPathXmlApplicationContext( 
    				"classpath:applicationContext.xml"); //ApplicationContext 컨테이네 사용
    
    		Car car = (Car)ac.getBean("car");
    		car.run();
    		
    	}
    }

    [결과]

     

    Spring에서 IoC, DI 설정하기 2 : Java Config를 사용한 설정(1) 

    Java Config를 사용한 설정을 위한 어노테이션

    • @Configuration : Spring 설정 클래스라는 의미를 가진다. JavaConfig로 설정할 클래스는 @Configuration이 있어야한다.

    • @Bean : bean 정의하는 어노테이션

    • @ComponentScan : @Controller, @Service, @Repository, @Component 어노테이션이 붙은 클래스를 찾아 컨테이너에 등록

    • @Component : 컴포넌트 스캔의 대상이 되는 어노테이션 중 하나. 주로 유틸, 기타 지원 클래스에 붙이는 어노테이션

    • @Autowired : 주입 대상이 되는 bean을 컨테이너에서 찾아 주입하는 어노테이션

    ApplicationConfig.java

    package kr.or.connect.diexam01;
    import org.springframework.context.annotation.*;
    
    @Configuration
    public class ApplicationConfig {
    	@Bean
    	public Car car(Engine e) {
    		Car c = new Car();
    		c.setEngine(e);
    		return c;
    	}
    	
    	@Bean
    	public Engine engine() {
    		return new Engine();
    	}
    }

    ApplicationContextExam03.java

    package kr.or.connect.diexam01;
    
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.annotation.AnnotationConfigApplicationContext;
    
    public class ApplicationContextExam03 {
    
    	public static void main(String[] args) {
    		ApplicationContext ac = new AnnotationConfigApplicationContext(ApplicationConfig.class);
    		   
    		Car car = (Car)ac.getBean("car");
    		//Car car = ac.getBean(Car.class); //이렇게도 가능
            car.run();
    	}
    }

    위와 같이 어노테이션을 사용해 XML 파일 설정없이 IoC, DI를 설정할 수 있다.

     

    [결과]

    Spring에서 IoC, DI 설정하기 2 : Java Config를 사용한 설정(2) - @ComponentScan 사용하기

     

    ApplicationConfig2.java

    package kr.or.connect.diexam01;
    import org.springframework.context.annotation.*;
    
    @Configuration
    @ComponentScan("kr.or.connect.diexam01")
    public class ApplicationConfig2 {
    }

    ApplicationConfig.java 에서 Bean을 생성하는 메소드를 모두 제거하고 @ComponentScan이라는 어노테이션을 추가했다. @ComponentScan는 @Controller, @Service, @Repository, @Component 어노테이션이 붙어 있는 클래스를 찾아 d인스턴스를 만들어서 메모리에 몽땅 올려준다.

     

    기존의 Car 클래스와 Engine 클래스 위에 @Component를 붙이자

     

    Engine.java

    package kr.or.connect.diexam01;
    
    import org.springframework.stereotype.Component;
    
    @Component
    public class Engine {
    	public Engine() {
    		System.out.println("Engine 생성자");
    	}
    	
    	public void exec() {
    		System.out.println("엔진이 동작합니다.");
    	}
    }

    Car.java

    package kr.or.connect.diexam01;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Component;
    
    @Component
    public class Car {
    	@Autowired
    	private Engine v8;
    	
    	public Car() {
    		System.out.println("Car 생성자");
    	}
    	
    	public void run() {
    		System.out.println("엔진을 이용하여 달립니다.");
    		v8.exec();
    	}
    }

    수정된 ApplicationConfig2.java 을 통해 실행하는 클래스를 보자

     

    ApplicationContextExam04.java

    package kr.or.connect.diexam01;
    
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.annotation.AnnotationConfigApplicationContext;
    
    public class ApplicationContextExam04 {
    
    	public static void main(String[] args) {
    		ApplicationContext ac = new AnnotationConfigApplicationContext(ApplicationConfig2.class);
    		   
    		Car car = ac.getBean(Car.class);
    		car.run();
    		
    	}
    }

    [결과]

     

    Spring에서 사용하기에 알맞게 @Controller, @Service, @Repository, @Component 어노테이션이 붙어 있는 객체들은 ComponentScan을 이용해서 읽어드려 메모리에 올리고 Dependency Injection을 한다. 위와 같은 어노테이션이 붙어있지 않은 객체들은 @Bean 어노테이션을 사용하는 방식으로 클래스들을 관리하면 편하다.

    'Web Development > 부스트코스 - Back-End(Java)' 카테고리의 다른 글

    [Back End] Spring MVC  (0) 2020.04.03
    [Back End] Spring JDBC  (0) 2020.03.30
    [Front End] Web UI development  (0) 2020.03.15
    [Back End] Web API  (0) 2020.03.14
    [Back End] Rest API  (0) 2020.03.14

    댓글

Designed by Tistory.