Spring IoC 예제 튜토리얼에 오신 것을 환영합니다. Spring Framework는 제어의 역전 원칙에 기반을 두고 있습니다. 의존성 주입은 응용 프로그램에서 IoC를 구현하는 기술입니다.
Spring IoC
오늘은 Spring IoC 컨테이너에 대해 알아보겠습니다. 또한 Spring Bean에 대해서도 살펴볼 것입니다. 아래는 Spring IoC 튜토리얼의 다른 섹션으로 빠르게 이동하기 위한 콘텐츠 테이블입니다.
스프링 IoC 컨테이너
Spring IoC는 객체 간의 느슨한 결합을 달성하기 위한 메커니즘입니다. 느슨한 결합과 런타임에서 객체의 동적 바인딩을 달성하기 위해, 객체 간의 의존성은 다른 조립기 객체에 의해 주입됩니다. Spring IoC 컨테이너는 의존성을 객체에 주입하고 사용할 준비를 하는 프로그램입니다. 우리는 이미 어떻게 애플리케이션에서 IoC를 구현하기 위해 Spring 의존성 주입을 사용할 수 있는지 살펴보았습니다. Spring IoC 컨테이너 클래스들은 org.springframework.beans
와 org.springframework.context
패키지의 일부입니다. Spring IoC 컨테이너는 객체 의존성을 분리하는 다양한 방법을 제공합니다. BeanFactory
는 Spring IoC 컨테이너의 루트 인터페이스입니다. ApplicationContext
는 BeanFactory
인터페이스의 하위 인터페이스로서 Spring AOP 기능, i18n 등을 제공합니다. ApplicationContext
의 일부 유용한 하위 인터페이스로는 ConfigurableApplicationContext
와 WebApplicationContext
가 있습니다. Spring 프레임워크는 우리가 Spring 컨텍스트를 가져오고 그 다음에 Spring Bean을 얻을 수 있는 여러 유용한 ApplicationContext 구현 클래스를 제공합니다. 우리가 사용할 수 있는 일부 유용한 ApplicationContext 구현체는 다음과 같습니다:
- AnnotationConfigApplicationContext: 스프링을 독립적인 자바 애플리케이션에서 사용하고 구성에 주석을 사용하는 경우, 이를 사용하여 컨테이너를 초기화하고 빈 객체를 얻을 수 있습니다.
- ClassPathXmlApplicationContext: 스프링 빈 구성 XML 파일이 독립 실행형 응용 프로그램에있는 경우,이 클래스를 사용하여 파일을로드하고 컨테이너 개체를 가져올 수 있습니다.
- FileSystemXmlApplicationContext: 이는 ClassPathXmlApplicationContext와 유사하지만 xml 구성 파일을 파일 시스템의 장소에서로드 할 수 있습니다.
- AnnotationConfigWebApplicationContext 및 XmlWebApplicationContext 웹 응용 프로그램용입니다.
일반적으로 Spring MVC 애플리케이션에서 작업하고 응용 프로그램이 Spring Framework를 사용하도록 구성되어있는 경우 응용 프로그램이 시작될 때 Spring IoC 컨테이너가 초기화되고 빈이 요청되면 종속성이 자동으로 주입됩니다. 그러나 독립 실행형 응용 프로그램의 경우 응용 프로그램의 어딘가에서 컨테이너를 초기화해야하며 그런 다음 봄 빈을 가져와야합니다.
Spring Bean
Spring Bean은 특별한 것이 아닙니다. Spring 컨테이너를 통해 초기화하는 Spring 프레임 워크의 모든 객체를 Spring Bean이라고합니다. 일반적인 Java POJO 클래스는 구성 메타 데이터 정보를 제공하여 컨테이너를 통해 초기화되도록 구성되는 경우 Spring Bean이 될 수 있습니다.
Spring Bean Scopes
다음은 Spring Beans에 대한 다섯 가지 범위가 정의되어 있습니다.
- 싱글톤 – 컨테이너마다 빈의 인스턴스가 하나만 생성됩니다. 이것은 스프링 빈의 기본 범위입니다. 이 범위를 사용할 때는 빈이 공유 인스턴스 변수를 가지지 않도록하십시오. 그렇지 않으면 데이터 일관성 문제가 발생할 수 있습니다.
- 프로토타입 – 빈이 요청될 때마다 새 인스턴스가 생성됩니다.
- 요청 – 이것은 프로토타입 범위와 동일하지만 웹 애플리케이션에서 사용하도록 설계되었습니다. 빈의 새 인스턴스가 각 HTTP 요청마다 생성됩니다.
- 세션 – 컨테이너에 의해 각 HTTP 세션에 대해 새 빈이 생성됩니다.
- 전역 세션 – 이것은 포틀릿 애플리케이션용 전역 세션 빈을 생성하는 데 사용됩니다.
스프링 프레임워크는 확장 가능하며 자체 범위를 생성할 수 있습니다. 그러나 대부분의 경우 프레임워크에서 제공하는 범위로 충분합니다.
스프링 빈 구성
스프링 프레임워크는 애플리케이션에서 사용할 빈을 구성하는 세 가지 방법을 제공합니다.
- 어노테이션 기반 구성 – @Service 또는 @Component 어노테이션을 사용하여 구성합니다. 범위 세부 정보는 @Scope 어노테이션으로 제공할 수 있습니다.
- XML 기반 구성 – Spring 구성 XML 파일을 만들어 빈을 구성합니다. Spring MVC 프레임워크를 사용하는 경우, xml 기반 구성은 web.xml 파일에 일부 보일러 플레이트 코드를 작성하여 자동으로 로드될 수 있습니다.
- 자바 기반 구성 – Spring 3.0부터 우리는 자바 프로그램을 사용하여 Spring 빈을 구성할 수 있습니다. 자바 기반 구성에 사용되는 일부 중요한 어노테이션은 @Configuration, @ComponentScan, @Bean 등입니다.
Spring IoC 및 Spring 빈 예제 프로젝트
다양한 측면에서 Spring IoC 컨테이너와 Spring Bean 구성을 살펴 보겠습니다. 간단한 Spring 프로젝트를 사용하여 예제를 만들겠습니다. 나는 Spring Tool Suite에서 Spring MVC 프로젝트를 만들고 있습니다. Spring Tool Suite와 Spring MVC에 익숙하지 않은 경우 Spring Tool Suite와 함께 Spring MVC 튜토리얼을 읽어보세요. 최종 프로젝트 구조는 아래 이미지와 같습니다. Spring IoC와 Spring Bean 프로젝트의 다양한 구성 요소를 하나씩 살펴 보겠습니다.
XML 기반 Spring Bean 구성
MyBean은 간단한 Java POJO 클래스입니다.
package com.journaldev.spring.beans;
public class MyBean {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Spring 구성 XML 파일
servlet-context.xml 코드:
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="https://www.springframework.org/schema/mvc"
xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
xmlns:beans="https://www.springframework.org/schema/beans"
xmlns:context="https://www.springframework.org/schema/context"
xsi:schemaLocation="https://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd
https://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
https://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<!-- DispatcherServlet Context: defines this servlet's request-processing infrastructure -->
<!-- Enables the Spring MVC @Controller programming model -->
<annotation-driven />
<!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources directory -->
<resources mapping="/resources/**" location="/resources/" />
<!-- Resolves views selected for rendering by @Controllers to .jsp resources in the /WEB-INF/views directory -->
<beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<beans:property name="prefix" value="/WEB-INF/views/" />
<beans:property name="suffix" value=".jsp" />
</beans:bean>
<context:component-scan base-package="com.journaldev.spring" />
<beans:bean name="myBean" class="com.journaldev.spring.beans.MyBean" scope="singleton" ></beans:bean>
</beans:beans>
MyBean이 singleton으로 구성된 bean
요소를 사용하여 구성되었음을 주목하세요.
Annotation 기반 Spring Bean 구성
package com.journaldev.spring.beans;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;
import org.springframework.web.context.WebApplicationContext;
@Service
@Scope(WebApplicationContext.SCOPE_REQUEST)
public class MyAnnotatedBean {
private int empId;
public int getEmpId() {
return empId;
}
public void setEmpId(int empId) {
this.empId = empId;
}
}
MyAnnotatedBean은 @Service를 사용하여 구성되고 범위는 Request로 설정됩니다.
Spring IoC 컨트롤러 클래스
HomeController 클래스는 응용 프로그램의 홈 페이지에 대한 HTTP 요청을 처리합니다. 우리는 이 컨트롤러 클래스에 Spring 빈을 WebApplicationContext 컨테이너를 통해 주입할 것입니다.
package com.journaldev.spring.controller;
import java.text.DateFormat;
import java.util.Date;
import java.util.Locale;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import com.journaldev.spring.beans.MyAnnotatedBean;
import com.journaldev.spring.beans.MyBean;
@Controller
@Scope("request")
public class HomeController {
private MyBean myBean;
private MyAnnotatedBean myAnnotatedBean;
@Autowired
public void setMyBean(MyBean myBean) {
this.myBean = myBean;
}
@Autowired
public void setMyAnnotatedBean(MyAnnotatedBean obj) {
this.myAnnotatedBean = obj;
}
/**
* Simply selects the home view to render by returning its name.
*/
@RequestMapping(value = "/", method = RequestMethod.GET)
public String home(Locale locale, Model model) {
System.out.println("MyBean hashcode="+myBean.hashCode());
System.out.println("MyAnnotatedBean hashcode="+myAnnotatedBean.hashCode());
Date date = new Date();
DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, locale);
String formattedDate = dateFormat.format(date);
model.addAttribute("serverTime", formattedDate );
return "home";
}
}
배포 설명자
Spring 프레임워크에 응용 프로그램을 구성해야 하므로 구성 메타데이터가 로드되고 컨텍스트가 초기화됩니다.
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="https://java.sun.com/xml/ns/javaee"
xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://java.sun.com/xml/ns/javaee https://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<!-- The definition of the Root Spring Container shared by all Servlets and Filters -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/root-context.xml</param-value>
</context-param>
<!-- Creates the Spring Container shared by all Servlets and Filters -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- Processes application requests -->
<servlet>
<servlet-name>appServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>appServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
위의 대부분의 구성은 대부분 STS 도구에서 자동으로 생성된 보일러플레이트 코드입니다.
Spring IoC Bean 예제 애플리케이션 실행
이제 웹 응용 프로그램을 실행하면 홈 페이지가 로드되고 페이지를 여러 번 새로 고칠 때 콘솔에 다음 로그가 출력됩니다.
MyBean hashcode=118267258
MyAnnotatedBean hashcode=1703899856
MyBean hashcode=118267258
MyAnnotatedBean hashcode=1115599742
MyBean hashcode=118267258
MyAnnotatedBean hashcode=516457106
MyBean이 싱글톤으로 구성되어 있으므로 컨테이너는 항상 동일한 인스턴스를 반환하며 해시 코드는 항상 동일합니다. 비슷하게, 각 요청에 대해 MyAnnotatedBean의 새로운 인스턴스가 생성되며 다른 해시 코드를 가지고 있습니다.
기반 자바 스프링 빈 구성
독립 실행형 애플리케이션의 경우, 주석 기반 및 XML 기반 구성을 모두 사용할 수 있습니다. 유일한 요구 사항은 프로그램에서 사용하기 전에 어딘가에서 컨텍스트를 초기화하는 것입니다.
package com.journaldev.spring.main;
import java.util.Date;
public class MyService {
public void log(String msg){
System.out.println(new Date()+"::"+msg);
}
}
MyService는 일부 메서드가 있는 간단한 자바 클래스입니다.
package com.journaldev.spring.main;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@ComponentScan(value="com.journaldev.spring.main")
public class MyConfiguration {
@Bean
public MyService getService(){
return new MyService();
}
}
스프링 컨테이너를 초기화하는 데 사용되는 주석 기반 구성 클래스입니다.
package com.journaldev.spring.main;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class MyMainClass {
public static void main(String[] args) {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(
MyConfiguration.class);
MyService service = ctx.getBean(MyService.class);
service.log("Hi");
MyService newService = ctx.getBean(MyService.class);
System.out.println("service hashcode="+service.hashCode());
System.out.println("newService hashcode="+newService.hashCode());
ctx.close();
}
}
A simple test program where we are initializing the AnnotationConfigApplicationContext
context and then using getBean()
method to get the instance of MyService. Notice that I am calling getBean method two times and printing the hashcode. Since there is no scope defined for MyService, it should be a singleton and hence hashcode should be the same for both the instances. When we run the above application, we get following console output confirming our understanding.
Sat Dec 28 22:49:18 PST 2013::Hi
service hashcode=678984726
newService hashcode=678984726
XML 기반 구성을 찾고 있다면, 스프링 XML 구성 파일을 작성한 다음 다음 코드 스니펫을 사용하여 컨텍스트를 초기화하십시오.
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
"applicationContext.xml");
MyService app = context.getBean(MyService.class);
이것으로 스프링 IoC 예제 튜토리얼, 스프링 빈 범위 및 구성 세부 정보는 모두입니다. 아래 링크에서 스프링 IoC 및 스프링 빈 예제 프로젝트를 다운로드하고 이해를 돕기 위해 실험해보세요.
Source:
https://www.digitalocean.com/community/tutorials/spring-ioc-bean-example-tutorial