이 글에서는 스프링에 대한 기본적인 몇몇 특징과 의존성 주입에 대해서 간략하게 알아볼 것이다.
이 내용은 '코드로 배우는 스프링 웹 프로젝트(구멍가게 코딩단)'을 보고 공부한 내용을 간략하게 정리한 것이다.
스프링 프레임워크는 말 그대로 프레임워크이다. 프레임워크는 뼈대나 근간을 이루는 코드들의 묶음 즉, 큰 틀을 제공하고 내 코드는 프레임워크의 틀 안에 맞춰서 작성하는 것이다.
프레임워크는 프로그램의 기본 흐름이나 구조가 이미 정해져 있어서 개발자 간의 능력 차이를 메워준다. 이미 구조가 구현돼 있기에 반쯤 완성된 상태에서 필요한 부분을 조립하는 형태의 개발이 가능하다는 점이다.
이는 품질이 보장된 결과와 개발 시간 단축이라는 장점이 있다.
2000년대 초반 여러 프레임워크가 나와있지만 스프링은 가장 성공적인 '경량(light-weight) 프레임 워크'이다.
스프링이 다른 프레임워크들과 다른 점은 다음과 같다.
- 복잡성을 해결하는 경량화된 프레임워크 - 일반적인 Java의 클래스와 인터페이스를 이용하는 구조이기에 진입장벽이 낮고 복잡한 프레임워크에 비해 가벼운 장점이 잇다.
- 전체 구조를 설계하는 프레임워크 - 웹, 데이터베이스 등 특정 전문적인 영역만을 지원하는 다른 프레임워크들과 달리 스프링은 한 분야에 집중하지 않고, 전체를 설계하는 용도로 사용된다는 장점이 있다. 사실 스프링이 대부분 Web이라는 제한된 영역에서 많이 사용되곤 하지만, OOP 구조를 뒷받침하고 구조를 설계하는 근본적인 사상은 변하지 않는다.
- 다른 프레임워크와의 쉬운 통합 - 스프링의 최대 장점은 기본 뼈대를 흔들지 않고, 여러 종류의 프레임워크를 혼용해서 사용할 수 있다는 점이다.
- 개발 생산성과 개발도구의 지원 - 스프링은 이론적으로 개발자가 제대로 이해해야 하는 부분이 많았지만, 코드의 양은 줄었고, 유지보수도 XML의 설정 등을 이용해서 환영받을 수 있었다. STS나 EClipse, Intellij 등의 플러그인 지원으로 빠른 업데이트가 돼서 별도의 새로운 개발도구에 대한 적응 없이 개발이 가능했다.
스프링은 버전에 따라 큰 변화를 겪어왔다.
- Spring 2.5 버전: 어노테이션을 활용하는 설정이 도입
- Spring 3.0 버전: 별도의 설정(XML) 없이 자바 클래스만으로 설정 파일을 대신할 수 있게 지원
- Spring 4.0 버전: 모바일 환경과 웹 환경에서 많이 사용되는 REST 방식의 컨트롤러 지원
- Spring 5.0 버전: Reactor를 이용한 Reactive 스타일의 개발 환경 지원
자바 클래스만으로 설정 파일을 대신할 수 있다는 것을 간단히 알아보자면 일반적으로 XML 기반으로 스프링 관련 설정을 하도록 되어있다. 스프링 3 버전 이후에는 Java 클래스 파일을 이용하는 설정을 지원하는데, XML과 별개로 Java를 이용하는 설정이 점점 증가하고 있다. 이는 Java Configuration을 통해 진행할 수 있다. 이는 @Configuration 어노테이션을 통해 가능하다. 이를 통해 XML에 복잡하게 적어야 하는 것을 간단하게 Java 클래스 파일에 설정할 수 있게 되었다. 빈 설정 또한 쉽게 할 수 있게 되었으며 자세한 설명은
https://mangkyu.tistory.com/75
를 참고하길 바란다.
스프링의 주요 특징이라고 하면 주로 다음과 같다.
- POJO(Plain Old Java Object) 기반의 구성
- 의존성 주입(DI)을 통한 객체 간의 관계 구성
- AOP(Aspect-Oriented-Programming) 지원
- 편리한 MVC 구조
- WAS의 종속적이지 않은 개발 환경
POJO(Plain Old Java Object) 기반의 구성
스프링은 객체 간의 관계를 구성할 수 있는 특징이 있다. 이 관계를 구성할 때 별도의 API를 사용하지 않는 POJO의 구성만으로 가능하도록 되어있다. 즉, Java 코드를 이용한 객체 구성 방식 그대로 스프링에서 사용할 수 있다는 것이다. 이는 특정 라이브러리나 컨테이너에 종속적이지 않고 가장 일반적인 형태로 코드를 작성하고 실행할 수 있기에 생산성에 유리하고 유연한 테스트가 가능하다는 것이다.
의존성 주입(DI)과 스프링
의존성 주입은 스프링에서 가장 중요한 개념이다. 의존성은 하나의 객체가 다른 객체에 의해 영향을 받는 것을 의미한다. 이러한 의존성을 주입하다는 것은 어떤 객체가 필요한 객체를 외부에서 밀어 넣는 것이다. 의존성 주입이 사용되는 이유는 단순하게 주입받는 어떤 객체에 대해 생각하지 않고 자신의 역할에 집중할 수 있기 때문이다. 즉, 각 객체가 자신의 역할을 온전히 수행하도록 하기 위해 의존성 주입이 사용되는 것이다.
의존성 주입이 사용되려면 의존성이 필요한 객체에 필요한 객체를 찾아서 주입하는 역할이 필요하다. 스프링에서는 'ApplicationContext'라는 존재(스프링이 사용하는 메모리 영역)가 필요한 객체를 생성하고, 필요한 객체들을 주입하는 역할을 해 주는 구조이다. 따라서 스프링을 이용하면 개발자들은 기조노의 프로그래밍과 달리 객체와 객체를 분리해서 생성하고, 이러한 객체들을 엮는(Wiring) 작업을 하는 형태의 개발을 하게 된다. ApplicationContext가 관리하는 객체들을 '빈(Bean)'이라고 하고 빈과 빈 사이의 의존관계를 처리하는 방식은 XML 설정, 어노테이션 설정, Java 설정을 이용할 수 있다. Application Context에 빈객체가 등록되고 의존성이 연결되는 것이다.
다음은 간단하게 빈을 등록하고 의존성 주입을 하는 예시 코드이다.(XML이 아닌 Java 설정을 이용하는 의존성 주입에 대해서만 설명하겠다)
@Component
@Data
public class Chef {
}
@Component
@Data
public class Restaurant {
@Setter(onMethod_ = @Autowired)
private Chef chef;
}
@Configuration
@ComponentScan(basePakages= {"org.test.sample"}) // 의존성 주입이 발생되는 패키지 경로
public class RootConfig {
}
@Component는 빈으로 등록할 객체라는 것을 표시하는 어노테이션이다. Restaurant 객체에서 setter로 chef를 설정하였고 이로 인해 Chef 객체 의존성을 주입하였다.
의존성 주입 방식은 크게 생성자를 통한 방법(@Allargsconstructor, @Requiredargsconstructor), setter를 통한 방법, @Autowired를 통한 방법이 있다. (참고로 @Requiredargsconstructor는 @NotNull이나 final이 붙여진 변수들을 가지고만 생성자가 만들어진다)
이렇게 객체 안에 설정을 한 후 @ComponentScan으로 패키지를 지정하여 이 어노테이션을 통해 해당 패키지에 있는 클래스들을 조사하면서 @Component가 존재하는 클래스들을 객체로 생성해서 빈으로 관리하게 된다. 그리고 의존성을 확인하여 의존성을 주입한다.
참고로 스프링 부트에서는 하나의 패키지 안에만 만들면 @ComponentScan을 사용할 필요가 없다. 이에 대한 자세한 설명은
https://oingdaddy.tistory.com/254
를 참고하길 바란다.
AOP 지원
좋은 개발환경의 중요 원칙은 '개발자가 비즈니스 로직에만 집중할 수 있게 한다'이다. 대부분의 시스템이 공통으로 가지고 있는 보안, 로그 , 트랜잭션과 같이 비즈니스 로직은 아니지만, 반드시 처리가 필요한 부분을 스프링에서는 '횡단 관심사(cross-concern)'라고 한다. AOP는 이러한 횡단 관심사를 모듈로 분리하는 프로그래밍의 패러다임이다.
이 외에도 스프링은 복잡한 트랜잭션 처리, 관리를 어노테이션이나 XML로 설정할 수 있기에 매번 상황에 맞는 코드를 작성할 필요가 없도록 설계돼있는 등 많은 장점과 특징을 가지고 있다.
참고
코드로 배우는 스프링 웹 프로젝트 - 구멍가게 코딩단
https://mangkyu.tistory.com/75
https://oingdaddy.tistory.com/254
'Spring' 카테고리의 다른 글
Spring Controller를 REST 방식으로 변화 - Rest API (0) | 2022.02.23 |
---|---|
스프링 MVC에 대한 간단 정리 (0) | 2022.02.09 |
스프링 @ExceptionHandler 를 통한 예외 처리 (0) | 2021.10.02 |
springboot 이미지파일을 aws 서버에 보관하고 가져오기(s3) (0) | 2021.09.16 |
SpringBoot Controller Test 작성 및 spring-security에서의 test (0) | 2021.08.31 |