2-2 객체 생성과 사용하기-의존주입

코딩강사·2022년 10월 17일
post-thumbnail

2-2 객체 생성과 사용하기-의존주입

예제 Ex04SpringDI 예제를 만들어서 스프링에서 어떻게 객체생성 및 사용을 지원하는지 살펴보겠습니다.

start.spring.io사이트에서 이전 설정과 동일하게 하고 Gropu은 com.study이고, Artifact와 Name을 Ex04SpringDI로 입력합니다. Package Name을 com.study.springboot로 설정해줍니다. Dependencies는 동일하게 Spring Web, Spring Boot Devtools, Lombok를 추가해줍니다. 생성(GENERATE) 버튼을 클릭하여 zip파일을 다운로드하고 동일하게 내문서>springboot폴더에 복사 후 여기서 풀기하고 인텔리제이에서 열기를 하면 됩니다.

resources폴더의 application.properties에 다음 내용을 추가하고 저장합니다.

server.port=8090

Ex04SpringDiApplication.java를 살펴보겠습니다.
@SpringBootApplication 어노테이션이 제일 먼저 눈에 띄입니다.
SpringApplication.run(Ex04SpringDiApplication.class, args)은 스프링 웹 애플리케이션을 실제 실행해주는 역할을 합니다.

package com.study.Ex04SpringDI;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Ex04SpringDiApplication {

	public static void main(String[] args) {
		SpringApplication.run(Ex04SpringDiApplication.class, args);
	}

}

@SpringBootApplication은 다음 3가지 어노테이션 기능을 하나로 묶어서 제공하는 어노테이션입니다.

  1. @ComponentScan
  2. @EnableAutoConfiguration :
  3. @SpringBootConfiguration :

@ComponentScan은 @Component가 붙은 클래스를 Bean으로 등록합니다. @Component는 주로 개발자가 직접 만든 해당클래스를 빈(Bean)으로 만들때 사용합니다. @Component은 주로 @Configuration, @Controller, @Service, @Repository의 내부에 들어가 있는 어노테이션입니다. 각각의 어노테이션은 나중에 설명하겠습니다.

@EnableAutoConfiguration : 스프링 프레임워크의 기본적인 기능을 활성화할 때 사용하는 어노테이션입니다. 애플리케이션 컨텍스트를 만들때, 자동으로 설정하는 기능을 켭니다.

@SpringBootConfiguration은 @Configuration이 등록된 자바 클래스를 스프링 애플리케이션의 설정 클래스로 등록합니다. 자바 클래스의 @Configuration과 @Bean을 통해 Bean객체를 생성할 수도 있습니다. @Configuration은 앱 설정을 담당하는 자바 클래스에 등록하고, 필요한 유틸리티 메서드나 필드에 @Bean을 등록해 사용합니다.

빈(Bean)이란? : 스프링 프레임워크가 관리하는 자바 객체를 말한다. 자동생성과 싱글톤, 의존주입을 지원한다.

Member 클래스와 AppConfig 클래스 파일을 만들어보겠습니다. 파일 구조는 이렇게 됩니다.

예제 Ex03DI과 동일하게 com.study.springboot 폴더에 Member 자바 클래스를 추가해줍니다. 코드는 동일합니다. 예제 URL은 https://bit.ly/3T3F1M2 입니다.

//회원정보 클래스
public class Member {
    private String name;

    public Member(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    //싱글톤 만들기
    private static Member m = null;
    public static Member getInstance() {
        if( m == null ) {
            m = new Member("홍길동");
        }
        return m;
    }

}

com.study.springboot 폴더에 AppConfig.java파일을 생성하고 아래와 같이 추가해줍니다.
예제 URL : https://bit.ly/3VvxvLF

package com.study.springboot;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class AppConfig {

    @Bean
    public Member member(){
        System.out.println("AppConfig.member 빈으로 등록됨.");
        return new Member("머스크");
    }

}

AppConfig 클래스 위에 @Configuration을 기술하여 이 클래스가 설정 관련 클래스임을 스프링에게 알려줍니다. @Bean은 메서드 위에 기술하여 반환되는 객체를 스프링이 관리하는 객체 풀(Pool - 스프링 컨텍스트)에 등록합니다. 이때 빈의 이름은 클래스 이름 Member에서 맨 첫글자를 소문자로하는 member입니다. 좀 있다가 사용해 보겠습니다.

스프링 컨텍스트(Spring Context) : 스프링 프레임워크에서 관리하는 자바 객체 즉 빈(Bean)들을 생성하고 관리하는 클래스이다. 문맥에 따라 애플리케이션 컨텍스트(Application Context), IoC 컨테이너(Inversion of Control Container)라고도 한다. 3가지 표현이 거의 비슷하다고 보면 된다.

Ex03SpringDiApplication 클래스에서 아래 코드를 추가해보겠습니다. 예제 URL : https://bit.ly/3yNfnTJ

package com.study.springboot;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

@SpringBootApplication
public class Ex04SpringDiApplication {

	public static void main(String[] args) {
    	//<추가된 부분
		ApplicationContext context =
				new AnnotationConfigApplicationContext(AppConfig.class);
		Member member = (Member)context.getBean("member");
		System.out.println( "ApplicationContext에서 찾은 빈 : " + member.getName() );
        //추가된 부분>

		SpringApplication.run(Ex04SpringDiApplication.class, args);
	}

}

ApplicationContext 클래스 객체를 생성해 오는데, 설정파일로 AppConfig클래스를 사용합니다. 그 다음 ApplicationContext 클래스 객체 context에서 getBean 메서드를 통해 member 객체(빈)을 찾아서 가져옵니다. 이 객체는 스프링에서 관리하는 Bean입니다.

public static void main 메서드를 한번 실행해보겠습니다.
아래 실행뷰에 아래와 같이 출력되면 정상적으로 객체(빈)을 얻어온 것입니다.

AppConfig.member 빈으로 등록됨.
ApplicationContext에서 찾은 빈 : 머스크

아래 코드를 추가해봅니다. 예제 URL : https://bit.ly/3yNfnTJ

package com.study.springboot;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

@SpringBootApplication
public class Ex04SpringDiApplication {

	public static void main(String[] args) {
		ApplicationContext context =
				new AnnotationConfigApplicationContext(AppConfig.class);
		Member member = (Member)context.getBean("member");
		System.out.println( "ApplicationContext에서 찾은 빈 : " + member.getName() );
		//<추가된 부분
		Member member2 = (Member)context.getBean("member");
		System.out.println( "member : " + member );
		System.out.println( "member2 : " + member2 );
		//추가된 부분>
		SpringApplication.run(Ex04SpringDiApplication.class, args);
	}

}

출력된 내용을 보면, getBean 메서드를 통해 얻어온 member객체 2개가 동일한 주소인 1f290aa0을 출력하는 것을 볼수 있습니다. 주소가 같다는 것은 동일한 객체라는 뜻이다. 곧 싱글톤을 유지하는 것을 알 수 있습니다.

member : com.study.springboot.Member@1f290aa0
member2 : com.study.springboot.Member@1f290aa0

이제 여러분의 스프링 프레임워크에서 제공해주는 자동 Bean 생성을 경험한 것입니다. 또한 의존주입을 이용한 것입니다.

개발자가 직접 new를 해서 사용하는 것 - 직접주입과 스프링 프레임워크에 등록해서 객체 풀(Pool)에서 사용하는 것 - 의존주입을 이제까지 함께 학습해 보았습니다.

의존주입의 장점은 아래와 같습니다.

  1. 객체의 자동 생성
  2. 싱글톤 기본 지원
  3. null 안정성 보장

이제 자바 개발자는 수많은 클래스 객체를 직접 생성하고 null 안정성을 신경쓰고, 싱글톤을 고려해야 하는 많은 수고를 덜게 되었습니다. 이외에도 스프링은 개발자를 위한 수많은 기능(데이타(DB)접근, 로그인 및 보안, 유효성체크 등등)을 지원하고 있습니다. 스프링을 한번 맛보면 다시 예전으로 돌아가기 힘듭니다. 그만큼 스프링은 고마운 존재입니다.

이제부터 본격적으로 스프링 객체생성을 이용해 보겠습니다.

profile
강의하는 개발자

0개의 댓글