본문 바로가기
학습/SPRING

04. 스프링 DI : 생성자 방식

by Elfen Lied 2022. 12. 21.
반응형

03번 글( https://simfairy.tistory.com/279 ) 코드와 이어짐

 

 

- 정리

1. 실습예제
	- MemberDao : selectAll() : 모든 회원정보조회
	
	- MemberPrinter : print() : 회원정보출력
	
	- MemberListPrinter : printAll()
		- MemberDao 생성자 주입
		- MemberPrinter 생성자 주입
		 
	- 애너테이션 방식
	- config.AppCtx : 스프링빈 설정
		- MemberPrinter
		- MemberListPrinter : MemberPrinter와 MemberDao 생성자 주입

	- main.MainForSpring
		- processListCommand()
		
	- XML 방식
	- src/main/resources/appCtx.xml : 스프링빈 설정
		- MemberPrinter
		- MemberListPrinter : MemberPrinter와 MemberDao 생성자 주입
		
	- main.MainForSpring
		- GenericXmlApplicationContext로 교체

 

 

- test 패키지 TestMain 클래스 생성

package test;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

public class TestMain {
	public static void main(String[] args) {
		Map<String, Integer	> map = new HashMap<String, Integer>();
		map.put("일번", 1);
		map.put("이번", 2);
		map.put("삼번", 3);
		map.put("사번", 4);
		
		Set<String> keySet = map.keySet();
		System.out.println(keySet);
		
		Collection<Integer> values = map.values();
		System.out.println(values);
		
		Set<Entry<String,Integer>> entrySet = map.entrySet();
		System.out.println(entrySet);
		
	}
}

 

 

 

- TestMain2 생성

package test;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.function.Consumer;

public class TestMain2 {
	public static void main(String[] args) {
		List<String> list = new ArrayList<String>();
		list.add("홍길동");
		list.add("이순신");
		list.add("김유신");
		list.add("임꺽정");
		
		// 익명구현객체 - 람다식으로 변환가능
//		Consumer<String> c = new Consumer<String>() {
//			@Override
//			public void accept(String t) {
//				System.out.println(t);
//			}
//		};
//		list.forEach(c);
		
		
		list.forEach(t->System.out.println(t));
		
	}
}

 

- spring 패키지 MemberDao

package spring;

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

public class MemberDao { 

	private static long nextId = 0; // 시퀀스
	
	private Map<String, Member> map = new HashMap<>(); // 데이터베이스 테이블
	
	public Member selectByEmail(String email) {
		return map.get(email);
	}

	public void insert(Member member) {
		member.setId(++nextId);
		map.put(member.getEmail(), member);
	}

	public void update(Member member) {
		map.put(member.getEmail(), member);
	}

	public Collection<Member> selectAll() {
		return map.values();
	}
}

 

 

- spring 패키지 MemberPrinter 클래스 생성

package spring;

public class MemberPrinter {

	public void print(Member member) {
		System.out.printf(
				"회원 정보: 아이디=%d, 이메일=%s, 이름=%s, 등록일=%tF\n", 
				member.getId(), member.getEmail(),
				member.getName(), member.getRegisterDateTime());
	}

}

 

 

- spring 패키지 MemberListPrinter 클래스 생성

package spring;

import java.util.Collection;

public class MemberListPrinter {
	private MemberDao memberDao;
	private MemberPrinter printer;
	
	// 생성자 주입
	public MemberListPrinter(MemberDao memberDao, MemberPrinter printer) {
		this.memberDao = memberDao;
		this.printer = printer;
	}
	
	public void printAll() {
		Collection<Member> members = memberDao.selectAll();
		members.forEach(m->printer.print(m));
	}
}

 

 

- config 패키지 AppCtx

package config;

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

import spring.ChangePasswordService;
import spring.MemberDao;
import spring.MemberListPrinter;
import spring.MemberPrinter;
import spring.MemberRegisterService;

@Configuration
public class AppCtx {
	
	@Bean
	public MemberDao memberDao() {
		return new MemberDao();
	}
	
	@Bean
	public MemberRegisterService memberRegSvc() {
		return new MemberRegisterService(memberDao()); // 생성자 주입
	}
	
	@Bean
	public ChangePasswordService changePwdSvc() {
		ChangePasswordService pwdSvc = new ChangePasswordService();
		pwdSvc.setMemberDao(memberDao()); // 세터(수정자) 주입
		return pwdSvc;
	}
	
	@Bean
	public MemberPrinter memberPrinter() {
		return new MemberPrinter();
	}
	
	@Bean
	public MemberListPrinter memberListPrinter() {
		// 생성자 주입
		return new MemberListPrinter(memberDao(), memberPrinter());
	}
}

 

 

- main 패키지 MainForSpring

package main;

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

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

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

public class MainForSpring {
	
	// 애노테이션 방식, XML 방식 두가지 다 사용하기 위해서 선언함
	// 애노테이션 방식만 쓸거면 작성할 필요없음
	private static ApplicationContext ctx = null;

	public static void main(String[] args) throws IOException {
		
		// 애노테이션 방식
		ctx = new AnnotationConfigApplicationContext(AppCtx.class);
		
		// XML 방식
//		ctx = new GenericXmlApplicationContext("classpath:appCtx.xml");
		
		BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
		while (true) {
			System.out.println("명령어를 입력하세요");
			String command = reader.readLine(); // 예외는 던지기
			if(command.equalsIgnoreCase("exit")) {
				System.out.println("프로그램이 종료됩니다");
				break;
			} else if(command.startsWith("new ")) { // 회원가입
				processNewCommand(command.split(" "));
			} else if(command.startsWith("change ")) { // 비밀번호 변경
				processChangeCommand(command.split(" "));
			} else if(command.equals("list")) { // 모든 회원 목록
				processListCommand();
			}
			
			else {
				printHelp(); // 사용법
			}
				
		}
	}


	private static void processNewCommand(String[] arg) { // 회원가입
		if(arg.length != 5) {
			printHelp();
			return;
		}
		
		// {new, 이메일, 이름, 암호, 암호확인}
		RegisterRequest req = new RegisterRequest();
		req.setEmail(arg[1]);
		req.setName(arg[2]);
		req.setPassword(arg[3]);
		req.setConfirmPassword(arg[4]);
		
		// 스프링 컨테이너에서 MemberRegisterService 객체를 가져옴
		MemberRegisterService regSvc = ctx.getBean("memberRegSvc", MemberRegisterService.class);
		
		// 비밀번호 일치 확인
		if(!req.isPasswordEqualToConfirmPassword()) { // 암호와 암호확인이 일치하면
			System.out.println("암호와 암호확인이 일치하지 않습니다");
			return;
		}
		try {
			regSvc.register(req);
			System.out.println("등록했습니다.\n");
		} catch (DuplicateMemberException e) {
			System.out.println("이미 존재하는 이메일입니다");
		}
	}

	private static void processChangeCommand(String[] arg) { // 비밀번호 변경
		if(arg.length != 4) {
			printHelp();
			return;
		}
		// {change, 이메일, 현재비번, 변경비번}
		// 어셈블러 컨테이너에서 ChangePasswordService 객체를 가져옴
		ChangePasswordService pwdSvc = ctx.getBean("changePwdSvc", ChangePasswordService.class);
		try {
			pwdSvc.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();
	}
	
	private static void processListCommand() {
		MemberListPrinter listPrinter = ctx.getBean("memberListPrinter", MemberListPrinter.class);
		listPrinter.printAll();
	}
}

실행해서 데이터 3개 정도 입력후 list 입력해서 확인

 

 

- appCtx.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

	<bean id="memberDao" class="spring.MemberDao" />
	
	<bean id="memberRegSvc" class="spring.MemberRegisterService">
		<constructor-arg ref="memberDao" />
	</bean>
	
	<bean id="changePwdSvc" class="spring.ChangePasswordService">
		<property name="memberDao" ref="memberDao" />
	</bean>
	
	<bean id="memberPrinter" class="spring.MemberPrinter" />
	
	<bean id="memberListPrinter" class="spring.MemberListPrinter">
		<constructor-arg ref="memberDao" />
		<constructor-arg ref="memberPrinter" />
	</bean>
</beans>

 

 

다시 MainForSpring 에서 ACAC 코드를 주석걸고

XML 방식의 코드 주석을 풀어준다.

그리고 실행

 

반응형

댓글