본문 바로가기

웹 개발/Spring

[Web_Spring] 02

 

● POJO(Plain Old Java Object) 기반의 구성

- 오래된 방식의 간단한 자바 객체

- JAVA 코드에서 일반적으로 객체를 구성하는 방식을 스프링 프레임워크에서 그대로 사용할 수 있다는 말이다.

 

 

 

● 의존성 주입(DI)을 통한 객체 간의 관계 구성

(1) 의존성(Dependency)

- 하나의 객체가 다른 객체 없이 제대로 된 역할을 할 수 없다는 것을 의미한다.

- 예를 들어 A객체가 B객체 없이 동작이 불가능한 상황을 'A가 B에 의존적이다'라고 표현한다.

 

(2) 주입(Injection)

- 외부에서 밀어 넣는 것을 의미한다.

- 예를 들어 어떤 객체에서 필요로한 객체를 외부에서 밀어 넣는 것을 의미한다.

- 주입을 받는 입장에서는 어떤 객체인지 신경 쓸 필요가 없고 어떤 객체에 의존하든 자신의 역할은 변하지 않게 된다.

 

(3) 의존성 주입

- 의존성 주입방식을 사용하기 위해서는 ???라는 존재가 필요하게 된다.

- 스프링 프레임워크에서는 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