Web

Ch03. Spring Container, ApplicationContext 설정 파일

tose33 2022. 6. 1. 17:00

- 스프링은 객체를 관리하는 컨테이너다. 

 

- ApplicationContext 클래스에 객체 생성 초기화 관련 기능이 정의되어 있고, 그 아래 여러 클래스들이 존재한다.

 

- AnnotationConfigApplicationContext 클래스는 그 중 하나로, 자바 클래스에서 정보를 읽어와 객체 생성과 초기화를 수행한다.

 

 

https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/context/annotation/AnnotationConfigApplicationContext.html

 

AnnotationConfigApplicationContext (Spring Framework 5.3.21 API)

 void registerBean(String beanName, Class  beanClass, Supplier  supplier, BeanDefinitionCustomizer... customizers) Register a bean from the given bean class, using the given supplier for obtaining a new instance (typically declared as a lambda express

docs.spring.io

레퍼런스를 보면 AnnotationConfigApplicationContext : accepting component classes as input — in

particular @Configuration-annotated classes

라고 되있다.

 

즉 AnnotationConfigApplicationContext는 ApplicationContext 인터페이스를 구현하는 클래스이고, 

@Configuration이 붙은 클래스, 즉 설정 클래스를 받아 빈 컨테이너를 생성한다는 것.

 

 

스프링 설정 파일 (클래스)

package config;

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

import spring.ChangePasswordService;
import spring.MemberDao;
import spring.MemberRegisterService;

@Configuration 
public class AppCtx 
{
	@Bean 
	public MemberDao memberDao() 
	{
		return new MemberDao();
	}
	
	@Bean 
	public MemberRegisterService memberRegSvc() 
	{
		return new MemberRegisterService(memberDao()); // DI 
	}
	
	@Bean 
	public ChangePasswordService changePwdSvc() 
	{
		ChangePasswordService pwdSvc = new ChangePasswordService();
		pwdSvc.setMemberDao(memberDao()); // setter 
		return pwdSvc; 
	}
}

클래스에 @Configuration 을 명시해줘야 해당 클래스가 스프링 설정 클래스가 된다.

총 3개의 Bean 객체가 생성됐다. 

 

 

Main

package main;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

import assembler.Assembler;
import config.AppCtx;
import spring.ChangePasswordService;
import spring.DuplicateMemberException;
import spring.MemberNotFoundException;
import spring.MemberRegisterService;
import spring.RegisterRequest;
import spring.WrongIdPasswordException;

public class MainForSpring 
{
	// spring container 
	private static ApplicationContext ctx = null; 
	
	public static void main(String[] args) throws IOException  
	{
		ctx = new AnnotationConfigApplicationContext(AppCtx.class);
		BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
		
		while(true) 
		{
			System.out.println("명령어를 입력하세요: "); 
			String command = reader.readLine();
			
			if(command.equalsIgnoreCase("exit")) // exit 
			{
				System.out.println("종료 ");
				break;
			}
			if(command.startsWith("new ")) // new  
			{
				processNewCommand(command.split(" "));
				continue;
			}
			else if(command.startsWith("change ")) // change  
			{
				processChangeCommand(command.split(" "));
				continue;		
			}
			printHelp();
		}
	}
	

	private static void processNewCommand(String[] arg) 
	{
		if(arg.length != 5) // 부적절한 input 
		{
			printHelp();
			return; 
		}
		
		// get Bean object 
		MemberRegisterService regSvc = ctx.getBean("memberRegSvc", MemberRegisterService.class);
		RegisterRequest req = new RegisterRequest(); 
		req.setEmail(arg[1]);
		req.setName(arg[2]);
		req.setPassword(arg[3]);
		req.setConfirmPassword(arg[4]);
		
		if(!req.isPasswordEqualToConfirmPassword())
		{
			System.out.println("암호와 확인이 일치하지 않습니다. \n");
			return; 
		}
		try 
		{
			regSvc.regist(req);
			System.out.println("등록했습니다 \n");		
		} catch (DuplicateMemberException e) 
		{
			System.out.println("이미 존재하는 이메일입니다 \n");
		}
	}
	
	private static void processChangeCommand(String[] arg) 
	{
		if(arg.length != 4)
		{
			printHelp();
			return;
		}
		
		ChangePasswordService changePwdSvc = ctx.getBean("changePwdSvc", ChangePasswordService.class);
		try 
		{
			changePwdSvc.changePassword(arg[1], arg[2], arg[3]);
			System.out.println("암호를 변경했습니다 \n");
		}
		catch (MemberNotFoundException e) 
		{
			System.out.println("존재하지 않는 이메일입니다 \n");
		}
		catch (WrongIdPasswordException e) 
		{
			System.out.println("이메일과 암호가 일치하지 않습니다 \n");
		}
	}
	
	private static void printHelp() 
	{
		System.out.println();
		System.out.println("잘못된 명령어입니다. 아래 명령어 사용법을 확인하세요 "); 
		System.out.println("명령어 사용법: ");
		System.out.println("new 이메일 이름 암호 암호확인 ");
		System.out.println("change 이메일 현재비번 변경비번 ");
		System.out.println();
	}
}

 

 

 

메인 클래스를 보면 다음과 같이 ApplicationContext 클래스를 AnnotationConfigApplicationContext 생성자로 초기화하고 있고, 설정파일인 AppCtx 클래스를 전달하고 있다. 

private static ApplicationContext ctx = null; 
	
	public static void main(String[] args) throws IOException  
	{
		ctx = new AnnotationConfigApplicationContext(AppCtx.class);

이렇게 함으로서 설정 파일 AppCtx 클래스에 따라 스프링 컨테이너가 생성됐다.

 

그리고 아래와 같이 스프링 컨테이너로 부터 Bean 객체를 갖고온다.

MemberRegisterService regSvc = ctx.getBean("memberRegSvc", MemberRegisterService.class);

 

 

 

 

 

출처: 스프링5 프로그래밍 입문 (최범균 저)