자바 웹을 다루는 기술 CH18,19

Jayde·2023년 1월 3일
0

2023-1 studySpring

목록 보기
1/1
post-thumbnail

CH18. 스프링 프레임워크

  • 프레임워크
    : 어느 정도 완성된 상태로 제공하는 기능
    개발 생산성과 품질이 보장된 애플리케이션 개발 가능

  • 스프링 프레임워크
    애플리케이션에서 사용되는 여러 빈(클래스 객체)을 스프링이 권한을 가지고 직접 관리
    <특징>
    - 가벼움
    - 제어 역행(IoC) 기술 이용 → 애플리케이션 간 느슨한 결합 제어
    - 의존성 주입(DI) 기능 지원
    - 관점 지향(AOP) 기능으로 자원 관리
    - 영속성과 관련된 다양한 서비스 지원
    - 다양한 라이브러리와 연동 기능 지원

    제어 역행 : 서블릿이나 빈 등을 프레임워크가 직접 수행
    의존성 주입 : 클래스 객체를 프레임워크가 생성 및 사용
    관점 지향 : 핵심 기능과 부수 기능 분리 구현 → 모듈성 증가

    <기능>
    - Core : 다른 기능을 수행하는 데 필요한 기반 기능 및 IoC 기능 제공
    - Context : 스프링의 기본 기능, 빈에 대한 접근 방법 제공
    - DAO : JDBC 편리하게 사용할 수 있도록
    - ORM : 영속성 관련 프레임워크와 연동된 기능 제공
    - AOP : 관점 지향 기능 제공
    - Web : 웹 애플리케이션 개발에 필요한 기능 제공
    - WebMVC : 스프링에서 MVC 구현 관련 기능 제공


CH19. 스프링 의존성 주입과 제어 역전 기능

  • 의존성 주입
    : 사용할 클래스와 사용될 클래스의 관계를 컨테이너가 직접 규정하는 것
    의존성 주입 시 직접적인 연관 관계 발생 X → 클래스 변경이 자유로움( 약한 결합 )

    강한 결합과 약한 결합
    강한 결합 : 변경 사항 발생 시 다른 클래스 수정 필요
    약한 결합 : 변경 사항 발생해도 다른 클래스 수정 불필요
    서로 관련 있는 기능은 강하게, 관련 없는 기능은 약하게 결합해야 좋은 프로그램!

    애플리케이션은 각 기능을 담당하는 컴포넌트로, 컴포넌트는 세부 기능을 수행하는 클래스로 이루어짐.

    클래스가 다른 클래스의 기능 사용할 때, 다른 클래스의 생성자를 호출해 사용
    → 구현 과정에서 다른 변경 사항 발생 시 관련 있는 모든 클래스의 소스 코드 수정 필요
    → 빠른 대처 어려움

    스프링 프레임워크에서 설정을 통해 맺어줌 → 클래스들이 연관 관계 갖지 않게 구현

  • 의존성 주입 사용 X

    //BoardService
    public class BoardService {
        BoardDAO boardDAO;
        public BoardService() {
            boardDAO = new BoardDAO(); //BoardDAO 객체를 코드에서 직접 생성
        }
    ...
  • 인터페이스 적용
    <계층 구조>
    BoardController <-- BoardControllerImpl
    BoardService <-- BoardServiceImpl
    BoardDAO <-- BoardOracleDAOImpl

    //BoardServiceImpl
    public class BoardServiceImpl implements BoardService{
        BoardDAO boardDAO;
        public BoardService(){
            boardDAO = new BoardOracleDAOImpl(); //인터페이스를 이용해 하위 클래스 객체 생성 후, 오라클 DB와 연동
        }

    여기서 MySQL과 연동하는 새로운 기능이 생겼다고 해도 기존의 BoardOracleDAOImpl 클래스를 변경할 필요 X
    BoardDAO 인터페이스를 구현한 또 다른 BoardMySqlDAOImpl 클래스 구현 후 사용하면 됨

    //BoardServiceImpl
    public class BoardServiceImpl implements BoardService{
        BoardDAO boardDAO;
        public BoardService(){
            boardDAO = new BoardMySqlDAOImpl(); //인터페이스를 이용해 하위 클래스 객체 생성 후, MySQL과 연동
        }

    인터페이스를 이용해 각 클래스 구현 후 각 클래스 객체 사용할 때는 인터페이스 타입으로 선언한 참조 변수로 접근해 사용
    → 완전하진 않아도 의존 관계가 약해짐 But, BoardServiceImpl은 여전히 직접 수정 필요

  • 의존성 주입 적용
    XML / 애너테이션을 이용해 객체 주입해 객체 간 의존 관계를 맺어줌
    <장점>
    ➖ 클래스들 간 의존 관계 최소화 → 코드 단순화
    ➖ 쉬운 유지 및 관리
    ➖ 객체의 생성, 소멸과 객체 간의 의존 관계를 컨테이너가 제어

    제어 역전 : 원래는 개발자가 직접 객체를 제어하던 것을 스프링이 직접 담당하는 것


    1. 생성자를 이용해 주입하는 방식

    //BoardServiceImpl
    public class BoardServiceImpl implements BoardService{
    	private BoardDAO boardDAO;
        public BoardServiceImpl(BoardDAO boardDAO){
        	this.boardDAO = boardDAO;
        }
    ...

    BoardService 클래스는 의존하는 BoardDAOImpl 객체를 전달받기 위해 생성자를 호출할 때 외부에서 객체를 주입 받아 사용
    BoardSErviceImpl 생성자를 호출할 때 컨테이너에 의해 주입되는 객체로 boardDAO 변수를 초기화한 것

    2. setter를 이용하여 주입하는 방식

    //BoardServiceImpl
    public class BoardServiceImpl implements BoardService{
    	private BoardDAO boardDAO;
        public void setBoardDAO(BoardDAO boardDAO){
        	this.boardDAO = boardDAO;
        }
    ...
  • 실습
    1. setter를 이용한 DI 기능
    <계층 구조>
    TestService <-- TestServiceImpl

    <bean 태그 속성>

    속성 이름설명
    id빈 객체의 고유 이름, id를 이용해 접근
    name객체의 별칭
    class생성할 클래스, 패키지 이름까지 입력해야 함
    constructor-arg생성자를 이용해 값을 주입할 때 사용
    propertysetter를 이용해 값을 주입할 때 사용

    new를 이용해 직접 객체를 생성하던 것을 person.xml에서 설정

    //person.xml
    <bean id="personService" class="com.spring.ex01.PersonServiceImpl">
        <property name="name">
        	//PersonServiceImpl 객체의 속성 name 값을 <value> 태그를 이용해 '홍길동'으로 초기화
           <value>홍길동</value> 
        </property>
    </bean>
    // PersonServiceImpl
    public void setName(String name){
    	this.name = name; //person.xml에서 지정한 value값을 매개 name에 넣음
    }

    2. 생성자를 이용한 DI 기능

    //person.xml
    //인자가 1개인 생성자에 매개값을 value값으로 초기화
    <bean id="personService1" class="com.spring.ex02.PersonServiceImpl">
      <constructor-arg   value="이순신" />
    </bean>
    
    //인자가 2개인 생성자에 매개값들을 value값으로 초기화
    <bean id="personService2" class="com.spring.ex02.PersonServiceImpl">
      <constructor-arg   value="손흥민"  />
      <constructor-arg   value="23"  />
    </bean>

    3. 빈에 주입되는 값이 의존 관계에 있는 다른 빈을 주입하는 경우
    <계층 구조>
    MemberServiceImpl --> MemberService
    ↓ 의존관계
    MemberDAOImpl --> MemberDAO

    //member.xml
    //빈을 만들면서 setter 주입 방식으로 id가 memberDAO인 빈을 자신의 속성에 주입
    <bean id="memberService" class="com.spring.ex03.MemberServiceImpl">
    			<property name="memberDAO" ref="memberDAO" />
    </bean>
    <bean id="memberDAO" class="com.spring.ex03.MemberDAOImpl" />

    기본형 데이터가 아닌 참조형 데이터는 ref 속성 이용해서 주입해야 함

    기본형 데이터 vs 참조형 데이터
    기본형: 실제 리터럴 값 저장(boolean, char, byte, short, int, long, float, double)
    참조형: 객체의 주소 저장(String, 배열, 클래스, 인터페이스 등 기본형을 제외한 모든 것)

profile
가장 높이 빛난 별 잡아보일게

0개의 댓글