객체간의 의존성이 존재할 경우
개발자가 직접 객체를 생성하거나 제어하는 것이 아니라, 제어 반전
에 의하여 특정 객체에 필요한 다른 객체
를 프레임워크
가 자동으로 연결시켜주는 것
을 말한다.
개발자는 자신에게 필요한 객체를 직접 할당하지 않고
, 인터페이스를 통해 선언한 객체
에 스프링 프레임워크에 의해 주입받아
사용할 수 있기 때문에, 비지니스 로직에만 집중할 수 있다.
개발자는 객체를 선언만 할 뿐
, 할당은 프레임워크에서 자동
으로 이루어진다.
@Controller public class MemberController { // Controller가 Service에 의존한다라고 표현 // Service는 여러 Controller에서 가져다 쓸 수 있기 때문에 // Spring Container에 등록을 해야한다. // 스프링스럽게 작업하기 // Service는 Spring Container에 하나만 생성 및 등록해서 // 같이 공유해서 쓸 수 있다. private final MemberService memberService; @Autowired public MemberController(MemberService memberService) { this.memberService = memberService; } }
@Controller
어노테이션은 서버가 올라갈 때, Spring Container
에 MemberController 객체를 생성한다.
MemberController 객체를 생성하는데, 생성자에 파라미터로 MemberService가 필요하다.
즉, MemberController 의 객체를 생성하기 위해서 MemberService 객체 생성까지 강제되는 것이다.
결론적으로 서버가 올라갈 때, Controller 객체 생성 시, Service 객체까지 Spring이 생성해주고, @Autowired
어노테이션을 통해 , 컨트롤러와 서비스의 연결고리를 맺어준다.
만약 객체 생성이나, 연결고리 에서 이슈가 생긴다면, 서버가 올라가지 않게 된다. 기존에는 로직을 테스트하면서 에러를 찾아냈다면, 스프링부트에서는
서버가 올라갈 때 문제가 있음을 파악
할 수 있다는 것이 중요하다.
🗝️ 서비스가 필요할 경우
Controller
->(의존) Service
->(의존) Repository
🗝️서비스가 필요 없을 경우
Controller
->(의존) Repository
@Service public class MemberService { private final MemberRepository memberRepository; public MemberService(MemberRepository memberRepository) { this.memberRepository = memberRepository; }
@Repository public class MemoryMemberRepository implements MemberRepository{}
개발자가 프레임워크의 기능을 호출하는 형태가 아니라,
프레임워크가 개발자의 코드를 호출
하기 때문에, 개발자는 직접 구현하지 않고 자신의 코드를 부분적으로 "끼워넣기"
하는 형태로 구현할 수 있다.
프레임워크
가 객체의 생성
, 소멸과 같은 라이프 사이클을 관리
하며
스프링으로부터 필요한 객체를 얻어올 수 있다.
객체의 의존성
을 역전
시켜 객체 간의 결합도를 줄이고, 유연한 코드를 작성할 수 있게 하여 가독성 및 코드 중복
, 유지 보수를 편하게
할 수 있게 된다.
스프링 컨테이너
는 자바 객체의 생명 주기를 관리
하며,
생성된 자바 객체들에게 추가적인 기능을 제공
하는 역할을 합니다.
여기서 말하는 자바 객체
를 스프링에서는 빈(Bean)
이라고 부릅니다.
개발자는 객체를 생성하고 소멸
할 수 있는데, 스프링 컨테이너
가 이 역할을 대신해 준다. 즉, 제어의 흐름을 외부에서 관리
하는 것.
또한, 객체들 간의 의존관계
를 스프링 컨테이너가
런타임 과정에서 알아서 만들어 준다.
스프링 실행시 객체(Bean)들을 담고
있는 Container
가 있다.
스프링은 스프링 컨테이너
에 스프링 빈(객체)을 등록
할 때,
기본으로 싱글톤으로 등록
한다.
Plain Old Java Object
, 단순한 자바 오브젝트
진정한 POJO란 객체지향적인 원리에 충실하면서, 환경과 기술에 종속되지 않고 필요에 따라 재활용될 수 있는 방식으로 설계된 오브젝트를 말한다.
특정 '기술'에 종속되어 동작하는 것이 아닌 순수한 자바 객체를 말하는 것이다.
예를들어 ORM(Object Relationship Mapping) 기술을 사용하고 싶다면 ORM 프레임워크를 사용해야 한다. (대표적으로 Hibernate 프레임워크가 있다.)
만약 자바 객체가 ORM기술을 사용하기 위하여 Hibernate 프레임워크를 직접 의존하는 순간, 특정 '기술'에 종속되었기 때문에 POJO라고 할 수 없다.
POJO를 지향해야하는 이유는 특정 기술과 환경에 종속되어 의존하게 된 자바 코드는 가독성이 떨어져 유지보수에 어려움이 생기고, 특정 기술의 클래스를 상속받거나,
직접 의존하게 되어 확장성이 매우 떨어지는 단점이 있었기 때문이다. 이 말은 객체지향의 화신인 자바가 객체지향 설계의 장점들을 잃어버리게 된 것으로 볼 수 있다.
하지만 Hibernate는 스프링에서 많이 사용하고 있는 기술이다. 특정 기술에 종속적이면 POJO가 아닌데, 스프링에서 POJO가 가능한 이유는 스프링에서 정한 표준 인터페이스가 있기 때문이다.
예를들어, ORM 기술을 사용하기 위해서 JPA라는 표준 인터페이스를 정해두었고, 여러 ORM 프레임워크들은 이 JPA라는 표준 인터페이스 아래에서 구현되어 실행된다.
이것이 스프링이 새로운 엔터프라이즈 기술을 도입하면서도 POJO를 유지하는 방법이다. 이러한 방법을 PSA라고 한다.