봄이란? Java 용 구성 요소 기반 개발

Spring은 아마도 21 세기에 등장한 컴포넌트 기반 프레임 워크 중 최고 일 것입니다. 개발자가 Java 기반 애플리케이션에서 인프라 코드를 작성하고 제공하는 방식을 크게 향상시킵니다. 처음부터 Spring은 엔터프라이즈 Java 개발을위한 선도적 인 프레임 워크로 인식되어 왔습니다. 종단 간 애플리케이션 프레임 워크 인 Spring은 Java EE 기능 중 일부를 미러링하지만 다른 곳에서는 찾을 수없는 기능과 프로그래밍 규칙의 조합을 제공합니다.

이 기사에서는 Spring과 핵심 프로그래밍 철학 및 방법론 인 Inversion of Control 및 종속성 주입을 소개합니다. 또한 Spring 주석과 몇 가지 실습 코딩 예제로 시작합니다.

의존성 주입 및 제어 반전

Spring의 핵심 아이디어는 객체 관계를 직접 관리하는 대신 프레임 워크로 오프로드한다는 것입니다. IOC (Inversion of Control)는 개체 관계를 관리하는 데 사용되는 방법입니다. 의존성 주입은 IOC를 구현하는 메커니즘입니다. 이 두 개념은 서로 관련이 있지만 다르므로 좀 더 자세히 살펴 보겠습니다.

  • IOC ( Inversion of Control )는 이름이 말하는대로 수행합니다. 즉, 객체 관계를 충족하기 위해 기존의 제어 계층을 뒤집습니다. 응용 프로그램 코드에 의존하여 개체가 서로 관련되는 방식을 정의하는 대신 프레임 워크에서 관계를 정의합니다. 방법론으로서 IOC는 객체 관계에 일관성과 예측 가능성을 도입하지만 개발자로서 세밀한 제어를 포기해야합니다.
  • DI ( 종속성 주입 )는 프레임 워크가 종속성을 앱에 "주입"하는 메커니즘입니다. IOC의 실제 구현입니다. 종속성 주입은 참조 유형의 이행이 프레임 워크의 구성에 따라 변경 될 수 있다는 점에서 다형성에 달려 있습니다. 프레임 워크는 변수 참조를 응용 프로그램 코드에서 수동으로 수행하지 않고 주입합니다.

JSR-330

자바 세계에서와 마찬가지로, 야생의 혁신 인 Spring으로 시작된 것이 부분적으로 표준 사양에 흡수되었습니다. 이 경우 JSR-330이 Java 표준입니다. JSR-330 사양의 좋은 점은 다른 곳에서 사용할 수 있으며 Spring을 넘어 다른 곳에서도 사용할 수 있다는 것입니다. Spring을 사용하지 않고 사용할 수 있습니다. 그러나 Spring은 훨씬 더 많은 것을 제공합니다.

예제 # 1 : Spring 의존성 주입

Inversion of control과 의존성 주입은 그것들을 사용함으로써 가장 잘 이해할 수 있으므로 빠른 프로그래밍 예제로 시작하겠습니다.

자동차를 모델링한다고 가정 해 보겠습니다. 일반 Java로 모델링하는 경우 목록 1에 표시된 것처럼 인터페이스 Car를 참조하기 위해 클래스 에 인터페이스 멤버가있을 수 있습니다 Engine.

Listing 1. 평범한 오래된 자바의 객체 관계

 public Interface Engine() { ... } public class Car { private Engine engine; public Engine getEngine() { ... } public void setEngine(Engine engine) { ... } } 

목록 1 것은위한 인터페이스가 포함되어 Engine유형 및 콘크리트에 대한 클래스 Car참조 유형을 Engine. (실제 프로그래밍 시나리오에서 이들은 별도의 파일에있을 것입니다.) 이제 Car인스턴스를 생성 할 때 목록 2에 표시된대로 연결을 설정합니다.

Listing 2. 엔진 인터페이스로 자동차 만들기

 // ... Car newCar = new Car(); Engine sixCylEngine = new InlineSixCylinderEngine(); newCar.setEngine(sixCylEngine ); // Do stuff with the car 

Car먼저 개체 를 만듭니다 . 그런 다음 Engine인터페이스 를 충족하는 새 개체를 만들고 수동으로 Car개체에 할당 합니다. 이것이 객체 연관이 평범한 오래된 Java에서 작동하는 방식입니다.

Spring에서 클래스와 객체 모델링

이제 Spring에서 동일한 예제를 살펴 보겠습니다. 여기에서 목록 3에 표시된 것과 같은 작업을 수행 할 수 있습니다. Car클래스로 시작 하지만이 경우에는 주석을 추가합니다 @Inject..

Listing 3. Spring에서 @Inject 어노테이션을 사용하는 예

 public class Car { @Inject private Engine engine; // ... } 

@Inject주석 (또는 @Autowired원하는 경우)을 사용하면 Spring이 컨텍스트를 검색하고 규칙 세트에 따라 자동으로 객체를 참조에 주입하도록 지시합니다.

다음 @Component으로 목록 4에 표시된 주석을 고려하십시오 .

목록 4. @Component 주석

 @Component public class InlineSixCylinderEngine implements Engine{ //... } 

클래스에 주석 @Component을 달면 주입을 수행 할 수 있음을 Spring 에 알립니다. 이 경우 InlineSixCylEngine사용할 수 있고 연결의 인터페이스 요구 사항을 충족하므로이 삽입됩니다. Spring에서는이를 "autowired"주입이라고합니다. (Spring의 @Autowired주석 에 대한 자세한 내용은 아래를 참조하십시오 .)

디자인 원칙으로서의 디커플링

종속성 주입을 사용한 제어 반전은 코드에서 구체적인 종속성 소스를 제거합니다. 프로그램 어디에도 Engine구현에 대한 하드 코딩 된 참조가 없습니다 . 이것은 소프트웨어 설계 원칙으로서의 디커플링 의 예입니다 . 구현에서 애플리케이션 코드를 분리하면 코드를보다 쉽게 ​​관리하고 유지 관리 할 수 ​​있습니다. 응용 프로그램은 해당 부분이 어떻게 결합되는지에 대해서는 잘 모르지만 응용 프로그램 수명주기의 어느 시점에서든 변경하는 것이 훨씬 쉽습니다.

@Autowired 대 @Inject

@Autowired그리고 @Inject같은 일을합니다. 그러나 @InjectJava 표준 주석이지만 @AutowiredSpring에만 해당됩니다. 둘 다 DI 엔진에 필드 또는 메서드를 일치하는 개체로 주입하도록 지시하는 동일한 목적을 수행합니다. Spring에서 둘 중 하나를 사용할 수 있습니다.

Spring 프레임 워크 개요

이제 Spring 코드를 살펴 보았으므로 프레임 워크와 해당 구성 요소에 대한 개요를 살펴 보겠습니다. 보시다시피 프레임 워크는 패키지로 나누어 진 4 개의 주요 모듈로 구성됩니다. Spring은 사용할 모듈에 상당한 유연성을 제공합니다.

  • 핵심 컨테이너
    • 핵심
    • 문맥
    • 표현 언어
  • 측면 지향 프로그래밍 (AOP)
    • AOP
    • 상들
    • 수단
  • 데이터 액세스 및 통합
    • JDBC
    • JPA / ORM
    • JMS
    • 업무
  • 편물
    • 웹 / 휴식
    • 서블릿
    • 스트럿

여기에서 모든 것을 다루기보다 더 일반적으로 사용되는 두 가지 Spring 기능을 시작하겠습니다.

새 프로젝트 시작 : Spring Boot

We'll use Spring Boot to create an example project, which we'll use to demo Spring features. Spring Boot makes starting new projects much easier, as you'll see for yourself. To begin, take a look at the main class shown below. In Spring Boot, we can take a main class with a main() method, and then choose to run it standalone, or package for deployment in a container like Tomcat.

Listing 5 has the outlines of our main class, which will live at the standard src/main/java/hello location.

Listing 5. Main class with Spring Boot

 package hello; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } } 

Note two things about the above code: First, all of the work is abstracted into the framework. The main class boots up the app, but it doesn't know anything about how the app works or delivers its functionality. Second, the SpringApplication.run() does the actual job of booting the app and passing in the Application class itself. Again, the work the app does is not apparent here.

The @SpringBootApplication annotation wraps up a few standard annotations and tells Spring to look at the package where the main class exists for components. In our previous example, with the car and engine, this would allow Spring to find all classes annotated with @Component and @Inject. The process itself, called component scanning, is highly customizable.

You can build the app with the standard mvn clean install, and you can run it with the Spring Boot goal (mvn spring-boot:run). Before doing that, let's look at this application's pom.xml file.

Listing 6. Starter pom.xml

 com.javaworld what-is-spring 1.0.0  org.springframework.boot spring-boot-starter-parent 2.1.3.RELEASE     1.8     org.springframework.boot spring-boot-maven-plugin    

Note two important features in the above code:

  1. The parent element relies on the spring-boot-starter-parent project. This parent project defines a number of useful defaults, such as the default compiler level of JDK 1.8. For the most part, you can just trust that it knows what it's doing. As an example, you can omit the version number for many common dependencies, and SpringBootParent will set the versions to be compatible. When you bump up the parent's version number, the dependency versions and defaults will also change.
  2. The spring-boot-maven-plugin allows for the executable JAR/WAR packaging and in-place run (via the mvn spring-boot:run command).

Adding Spring Web as a dependency

So far, we've been able to use spring-boot to limit how much work we put in to get an app up and running. Now let's add a dependency and see how quickly we can get something in a browser.

Listing 7. Adding Spring Web to a project

  org.springframework.boot spring-boot-starter-web  

Note

Spring will automatically detect what files have changed and compile accordingly. You can just execute mvn spring-boot:run to pickup changes.

Now that we've got a basic project setup, we're ready for our two examples.

Example #2: Building RESTful endpoints with Spring Web

We've used spring-boot-starter-web to bring in several dependencies that are useful for building web applications. Next we'll create a route handler for a URL path. Spring's web support is part of the Spring MVC (Model-View-Controller) module, but don't let that worry you: Spring Web has full and effective support for building RESTful endpoints, as well.

The class whose job it is to field URL requests is known as a controller, as shown in Listing 8.

Listing 8. Spring MVC REST controller

 package hello; 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 org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.RequestParam; @Controller public class GreetingController { @RequestMapping(value = "/hi", method = RequestMethod.GET) public String hi(@RequestParam(name="name", required=false, defaultValue="JavaWorld") String name, Model model) { return "Hello " + name; } } 

The @Controller annotation

The @Controller annotation identifies a class as a controller. A class marked as a controller is also automatically identified as a component class, which makes it a candidate for auto-wiring. Wherever this controller is needed, it will be plugged into the framework. In this case, we'll plug it into the MVC system to handle requests.

The controller is a specialized kind of component. It supports the @RequestMapping and @ResponseBody annotations that you see on the hi() method. These annotations tell the framework how to map URL requests to the app.

At this point, you can run the app with mvn spring-boot:run. When you hit the /hi URL, you'll get a response like "Hello, JavaWorld."

Notice how Spring has taken the basics of autowiring components, and delivered a whole web framework. With Spring, you don't have to explicitly connect anything together!

The @Request annotations

The @RequestMapping allows you to define a handler for a URL path. Options include defining the HTTP method you want, which is what we've done in this case. Leaving RequestMethod off would instruct the program to handle all HTTP method types.

The @RequestParam argument annotation allows us to map the request parameters directly into the method signature, including requiring certain params and defining default values as we've done here. We can even map a request body to a class with the @RequestBody argument annotation.

REST and JSON response

REST 엔드 포인트를 생성하고 메서드에서 JSON을 반환하려는 경우 메서드에 @ResponseBody. 그러면 응답이 JSON으로 자동 패키징됩니다. 이 경우 메서드에서 개체를 반환합니다.

Spring Web에서 MVC 사용

Struts와 유사하게 Spring Web 모듈은 진정한 모델-뷰-컨트롤러 설정에 쉽게 사용될 수 있습니다. 이 경우 주어진 템플릿 언어 (예 : Thymeleaf)로 매핑을 반환하고 Spring은 매핑을 해결하고 전달한 모델을 제공하고 응답을 렌더링합니다.

예제 # 3 : Spring과 JDBC

이제 요청 처리기로 더 흥미로운 작업을 수행해 보겠습니다. 데이터베이스에서 일부 데이터를 반환 해 보겠습니다. 이 예에서는 H2 데이터베이스를 사용합니다. 고맙게도 Spring Boot는 기본적으로 인 메모리 H2 DB를 지원합니다.