들어가며
스프링이란?
- 의존 주입(Dependency injection: DI) 지원
- AOP(Aspect-Oriented Programming) 지원
- MVC 웹 프레임워크 제공
- JDBC, JPA 연동, 선언적 트랜잭션 처리 등 DB 연동 지원
이외에도 스케줄링, 메시지 연동(JMS), 이메일 발송, 테스트 지원 등 자바 기반의 앱을 개발하는데 다양한 기능을 제공해주는 프레임워크이다.
스프링에 관련된 프로젝트는 다양하다. 이중에 자주 사용되는 것은 다음과 같다.
- 스프링 데이터: 적은 양의 코드로 데이터 연동을 처리할 수 있도록 도와주는 프레임워크
- 스프링 시큐리티: 인증/인가와 관련된 프레임워크로서 웹 접근 제어, 객체 접근 제어, DB · 오픈ID · LDAP 등 다양한 인증 방식, 암호화 기능을 제공
- 스프링 배치: 로깅/추적, 작업 통계, 실패 처리 등 배치 처리에 필요한 기본 기능을 제공
https://spring.io/projects ← 페이지를 들어가보면 보다 더 많은 프로젝트를 확인할 수 있다.
프로젝트 구성 및 설정
해당 책에서는 이클립스와 JDK1.8을 소개하고 있다. 하지만 나는 인텔리제이와 JDK11을 사용하고 있으므로 이대로 사용하려고 한다.
Maven과 Gradle 생성 법을 알려준다. 나는 Gradle을 쓸 생각이라 Maven은 참고용으로만 읽고 Gradle 프로젝트를 만들었다.
build.gradle를 열어보자
plugins {
id 'java'
}
group 'org.example'
version '1.0-SNAPSHOT'
repositories {
mavenCentral()
}
dependencies {
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.8.1'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.8.1'
}
test {
useJUnitPlatform()
}
내 Gradle 버전은 7.5.1이라 책과는 다르게 세팅되었다.
책에서 세팅하라는 대로 세팅해준다.
plugins {
// gradle java 플러그인을 적용한다.
id 'java'
}
group 'org.example'
version '1.0-SNAPSHOT'
// 소스와 컴파일 버전을 11로 맞춰준다.
sourceCompatibility='11'
targetCompatibility='11'
// 소스 코드 인코딩으로 UTP-8을 사용한다.
compileJava.options.encoding="UTF-8"
// 의존 모듈을 메이븐 중앙 레포지토리에서 다운로드한다.
repositories {
mavenCentral()
}
dependencies {
// spring-context모듈에대한 의존을 설정한다.
implementation group: 'org.springframework', name: 'spring-context', version: '5.2.3.RELEASE'
// 롬복
implementation 'org.projectlombok:lombok:1.18.22'
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.8.1'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.8.1'
}
test {
useJUnitPlatform()
}
그래이들 래퍼 설정도 있었으나, gradle-wrapper.properties에 대한 내용인가 싶어서 skip했다.
예제 코드 작성
Greeter
package org.example.chap02;
public class Greeter {
private String format;
public String greet(String guest) {
return String.format(format, guest);
}
public void setFormat(String format) {
this.format = format;
}
}
AppContext(@Bean, @Configuration)
package org.example.chap02;
import lombok.Getter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
// 해당 클래스를 스프링 설정 클래스로 지정한다.
@Configuration
public class AppContext {
@Bean
public Greeter greeter() {
Greeter g = new Greeter();
g.setFormat("%s,안녕하세요!") ;
return g;
}
}
💡@Configuration
: 이 애노테이션은 해당 클래스를 스프링 설정 클래스로 지정한다.
이 코드의 핵심은 @Bean 애노테이션이 달린 메서드이다. 스프링은 객체를 생성하고 초기화하는 기능을 제공하는데, 저 메서드가 객체를 생성하고 초기화하는 설정을 담고 있다.
스프링이 생성하는 객체를 빈(Bean) 객체라고 부르는데, 이 빈 객체에 대한 정보를 담고있는 메서드가 greeter()메서드이다.
@Baen 애노테이션을 메서드에 붙이면 해당 메서드가 생성한 객체를 스프링이 관리하는 빈 객체로 등록한다.
이 메서드의 이름은 빈 객체를 구분할 때 사용한다. @Baen 애노테이션을 붙인 메서드는 객체를 생성하고 알맞게 초기화 해야한다. 위 코드는 Greeter객체를 초기화하고 있다.
Main
package org.example.chap02;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class Main {
public static void main(String[] args) {
// AnnotationConfigApplicationContext 클래스는 자바 설정에서 정보를 읽어와 빈 객체를 생성하고 관리한다.
// AnnotationConfigApplicationContext 객체를 생성할 떄, 작성한 AppContext를 생성자 파라미터로 전달한다.
// AnnotationConfigApplicationContext 는 AppContext에 정의한 @Bean 설정 정보를 읽어와 Greeter 객체를 생성하고 초기화한다.
AnnotationConfigApplicationContext ctx =
new AnnotationConfigApplicationContext(AppContext.class) ;
// getBean 메서드는 AnnotationConfigApplicationContext가 자바 설정을 읽어와 생성한 빈 객체를 검색할 때 사용된다.
// getBean 메서드의 첫번째 파라미터는 @Bean 애노테이션의 메서드 이름인 빈 객체의 이름이며, 두번째 인자는 검색할 빈 객체의 타입이다.
Greeter g = ctx.getBean("greeter", Greeter.class);
String msg = g.greet("스프링");
System.out.println(msg) ;
ctx.close();
}
}
💡 AnnotationConfigApplicationContext
: 자바 설정에서 정보를 읽어와 빈 객체를 생성하고 관리, 자바 애노테이션을 이용한 클래스로부터 객체 설정 정보를 가져옴. 파라미터로 @Configuration 애노테이션이 붙은 클래스를 넘겨준다.
💡 getBean()
: @Configuration 애노테이션이 붙은 클래스에서 생성하는 빈 객체를 검색한다.
실행 결과
스프링,안녕하세요!
콘솔에 한글이 깨져 보여서 따로 설정을 또 해줬다.
Help→Edit Custom VM options…
-Xmx2024m
-Dfile.encoding=UTF-8 //작성
-Dconsole.encoding=UTF-8 // 작성
스프링은 객체 컨테이너
이 예제 코드의 핵심은 AnnotationConfigApplicationContext 클래스이다.
스프링의 핵심 기능은 객체를 생성하고 초기화 하는 것이다. 이와 관련된 기능은 ApplicationContext라는 인터페이스에 정의되어 있다.
AnnotationConfigApplicationContext 클래스는 자바 클래스에서 정보를 읽어와 객체 생성과 초기화를 수행한다.
최상위 인터페이스인 BeanFactory 인터페이스는 객체 생성과 검색에 대한 기능을 정의한다. 예를 들어 생성된 객체를 검색하는데 필요한 getBean() 메서드는 BeanFactory에 정의되어 있다. 이외에 싱글톤/프로토타입 빈인지 확인하는 기능도 제공한다.
ApplicationContext 인터페이스는 메시지, 프로필/환경 변수 등을 처리할 수 있는 기능을 추가로 정의한다.
// 1. 설정 정보를 이용해서 빈 객체를 생성
AnnotationConfigApplicationContext ctx =
new AnnotationConfigApplicationContext(AppContext.class) ;
// 2. 빈 객체를 제공
Greeter g = ctx.getBean("greeter", Greeter.class);
ApplicationContext(또는 BeanFactory)는 빈 객체의 생성, 초기화, 보관, 제거 등을 관리하고 있어서 컨테이너(Container)라고도 부른다. 앞으로는 스프링 컨테이너라고 칭하겠다.
싱글톤(Singleton) 객체
Main에 두 코드를 추가 해보자
Greeter g2 = ctx.getBean("greeter", Greeter.class);
System.out.println(g == g2);
실행결과
true
객체 두 개를 생성했는데 이 두 객체가 같다니?
스프링은 getBean 메서드로 같은 객체를 리턴받은 것이다. 별도 설정을 하지 않을 경우 스프링은 한 개의 빈 객체만을 생성한다. 이때 빈 객체는 ‘싱글톤 범위를 갖는다’라고 표현한다.
만약 두개의 객체를 받고 싶다면 다음과 같이 처리하면 된다.
// AppContext에 메서드 추가
@Bean
public Greeter greeter2() {
Greeter g = new Greeter();
g.setFormat("%s,안녕하세요!") ;
return g;
}
// Main에 greeter2()로 객체 생성
Greeter g2 = ctx.getBean("greeter2", Greeter.class);
실행결과
false
.
.
.
.
원래 토비의 스프링으로 스프링 공부를 다시 시작하려했는데, 점점 갈수록 이해가 안돼서 스프링5 프로그래밍 입문을 구매했다. 이 책을 구매하기 전에 이전에 봤던 김영환님 강의를 다시 보려고 했지만, 책이 더 편해서 책을 구매해버림....
스프링5 프로그래밍 입문은 정말 입문자에 맞춰서 알려주기 때문에 이해가 팍팍 되더라. 그래서 토비의 스프링에서 말하는 바가 뭔지 알게됐음~
Reference
초보 웹 개발자를 위한 스프링5 프로그래밍 입문
'Spring > 스프링5 프로그래밍 입문' 카테고리의 다른 글
Chapter7. AOP 프로그래밍 (0) | 2023.02.22 |
---|---|
Chapter6. 빈 라이프사이클과 범위 (0) | 2023.02.21 |
Chapter5. 컴포넌트 스캔 (0) | 2023.02.21 |
Chapter4. 의존 자동 주입 (0) | 2023.02.20 |
Chapter3. 스프링DI (0) | 2023.02.19 |