● POJO(Plain Old Java Object) 기반의 구성
- 오래된 방식의 간단한 자바 객체
- JAVA 코드에서 일반적으로 객체를 구성하는 방식을 스프링 프레임워크에서 그대로 사용할 수 있다는 말이다.
● 의존성 주입(DI)을 통한 객체 간의 관계 구성
(1) 의존성(Dependency)
- 하나의 객체가 다른 객체 없이 제대로 된 역할을 할 수 없다는 것을 의미한다.
- 예를 들어 A객체가 B객체 없이 동작이 불가능한 상황을 'A가 B에 의존적이다'라고 표현한다.
(2) 주입(Injection)
- 외부에서 밀어 넣는 것을 의미한다.
- 예를 들어 어떤 객체에서 필요로한 객체를 외부에서 밀어 넣는 것을 의미한다.
- 주입을 받는 입장에서는 어떤 객체인지 신경 쓸 필요가 없고 어떤 객체에 의존하든 자신의 역할은 변하지 않게 된다.
(3) 의존성 주입
![](https://blog.kakaocdn.net/dn/mDcgG/btrEtxTV6DN/ijnKcgVi63tuX1AMoCalK1/img.png)
- 의존성 주입방식을 사용하기 위해서는 ???라는 존재가 필요하게 된다.
- 스프링 프레임워크에서는 ApplicationContext가 ???라는 존재이며, 필요한 객체들을 생성하고,
필요한 객체들을 주입해주는 역할을 한다.
- 따라서 개발자들은 기존의 프로그래밍과 달리 객체와 객체를 분리해서 생성하고,
이러한 객체들을 엮는(wiring)작업의 형태로 개발하게 된다.
- ApplicationContext가 관리하는 객체들을 '빈(Bean)'이라 부른다.
- 빈과 빈 사이의 의존 관계를 처리하는 방식으로 XML, 어노테이션, JAVA 방식을 이용할 수 있다.
● AOP의 지원
- 관점 지향 프로그래밍
- 좋은 개발환경에서는 개발자가 비지니스 로직에만 집중할 수 있게 한다.
- 스프링 프레임워크는 반복적인 코드를 제거해줌으로써 핵심 비지니스 로직에만 집중할 수 있도록 해준다.
- 횡단 관심사(cross-concern) : 보안이나 로그, 트랜잭션과 같이 비지니스 로직은 아니지만, 반드시 처리가 필요한 부분
- 스프링 프레임워크는 이러한 횡단 관심사를 분리해서 제작하는 것이 가능하고,
횡단 관심사를 모듈로 분리하는 프로그래밍을 AOP라고 한다.
● AOP의 3가지 이점
1) 핵심 비지니스 로직에만 집중하여 코드 개발
2) 각 프로젝트마다 다른 관심사 적용 시 코드 수정 최소화
3) 원하는 관심사의 유지보수가 수월한 코드 구성 가능
실습(의존성 주입)
1. Plugin 설치
- File > Settings > 좌측에서 Plugins 클릭 > Lombok 검색하여 설치
2. src/main/java/com.example.ex00/dependency/Coding.java
package com.example.ex00.dependency;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component // 해당 객체를 Spring에서 관리하도록 설정
@Data
//@NoArgsConstructor
//@AllArgsConstructor //모든 필드를 초기화 할 수 있는 생성자 선언
@RequiredArgsConstructor // final 또는 @NonNull이 사용된 필드만 초기화 할 수 있는 생성자 선언
public class Coding {
// 필드 주입
// 굉장히 편하게 주입할 수 있다.
// 다른 곳에서 바로 변형이 가능하기 때문에 값이 변할 수 있는 심각한 문제가 생길 수 있다.
// @Autowired
private final Computer computer;
// 생성자 주입
// 메모리에 필드를 할당하면서 초기값이 주입되므로 final 키워드를 사용할 수 있다.
// 주입이 되지 않으면 객체 자체가 생성이 안되므로, NPE를 방지할 수 있다.
// @Autowired
// public Coding(Computer computer) {
// this.computer = computer;
// }
}
3. src/main/java/com.example.ex00/dependency/Computer.java
package com.example.ex00.dependency;
import lombok.*;
import org.springframework.stereotype.Component;
@Component
@ToString
public class Computer {
}
4. src/test/java/com.example.ex00/dependency/DependencyTests.java
package com.example.ex00.dependency;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest //현재 클래스는 단위 테스트 클래스임을 나타내고, JUnit 라이브러리를 통해 독립적으로 단위 테스트가 가능해진다.
@Slf4j //로그 출력 라이브러리
public class DependencyTests {
@Autowired //단위 테스트에서는 필드 주입만 가능하다.
private Coding coding;
@Test
public void dependencyInjectionTest(){
log.info("----------------------------");
log.info("coding : " + coding);
log.info("computer : " + coding.getComputer());
log.info("----------------------------");
}
}
5. src/main/java/com.example.ex00/dependency/qualifier/Computer.java
package com.example.ex00.dependency.qualifier;
/*
* @Qualifier
*
* @Autowired를 통해 객체를 주입할 때 같은 타입의 객체가 여러 개 있다면, 구분할 수 없다.
* 이 때, @Qualifier를 통해 식별자를 부여하면 원하는 객체를 주입 받을 수 있다.
*
* */
public interface Computer {
public int getScreenWidth();
}
6. src/main/java/com.example.ex00/dependency/qualifier/Laptop.java
package com.example.ex00.dependency.qualifier;
import lombok.ToString;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
@Component
@Qualifier("laptop")
@ToString
public class Laptop implements Computer{
@Override
public int getScreenWidth() {
return 1280;
}
}
7. src/main/java/com.example.ex00/dependency/qualifier/Desktop.java
package com.example.ex00.dependency.qualifier;
import lombok.ToString;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Component;
@Component
@Qualifier("desktop")
@ToString
public @Primary /*default로 설정*/ class Desktop implements Computer{
@Override
public int getScreenWidth() {
return 1920;
}
}
8. src/test/java/com.example.ex00/dependency/QualifierTests.java
package com.example.ex00.dependency;
import com.example.ex00.dependency.qualifier.Computer;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
@Slf4j
public class QualifierTests {
@Autowired
@Qualifier("desktop")
private Computer desktop;
@Autowired
@Qualifier("laptop")
private Computer laptop;
@Autowired
private Computer computer;
@Test
public void computerTest(){
log.info("------------------------------");
log.info("desktop : " + desktop);
log.info("------------------------------");
log.info("------------------------------");
log.info("laptop : " + laptop);
log.info("------------------------------");
log.info("------------------------------");
log.info("computer : " + computer);
log.info("------------------------------");
}
}
'웹 개발 > Spring' 카테고리의 다른 글
[Web_Spring] 07 (0) | 2022.06.19 |
---|---|
[Web_Spring] 06 (0) | 2022.06.18 |
[Web_Spring] 05 (0) | 2022.06.17 |
[Web_Spring] 03 (0) | 2022.06.15 |
[Web_Spring] 01 (0) | 2022.06.13 |