TIL(2022.04.05)

138849 단어 TILJavaJava

스프링5 입문

스프링의 DI 설정

  • 스프링은 필요한 객체를 생성하고 생성한 객체에 의존을 주입한다.

스프링을 이용한 객체 조립과 사용

package config;

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

import com.jisung.spring.ChangePasswordService;
import com.jisung.spring.MemberDao;
import com.jisung.spring.MemberRegisterService;

@Configuration // 이 클래스를 스프링 설정 클래스로 사용하겠다.
public class AppCtx {
	
	//@Bean
	// - 해당 메서드가 생성한 객체를 스프링 빈이라고 설정
	// - 메서드 이름을 빈 객체의 이름으로 사용하겠다.
	
	@Bean
	public MemberDao memberDao() {
		return new MemberDao();
	}
	
	@Bean
	public MemberRegisterService memberRegSvc() {
		//memberDao()가 생성한 객체를 주입
		return new MemberRegisterService(memberDao());
	}
	
	@Bean
	public ChangePasswordService changePwdSvc() {
		ChangePasswordService pwdSvc = new ChangePasswordService();
		pwdSvc.setMemberDao(memberDao());
		return pwdSvc;
	}
}
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 com.jisung.spring.ChangePasswordService;
import com.jisung.spring.DuplicateMemberException;
import com.jisung.spring.MemberNotFoundException;
import com.jisung.spring.MemberRegisterService;
import com.jisung.spring.RegisterRequest;
import com.jisung.spring.WrongIdPasswordException;

import assembler.Assembler;
import config.AppCtx;

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

		//스프링 컨테이너를 생성한다. 
		//스프링 컨테이너는 객체를 생성하고 의존 객체를 주입
		// AppCtx.class(설정파일)로부터 생성할 객체와 의존주입대상을 정한다.
		ctx = new AnnotationConfigApplicationContext(config.AppCtx.class);
		
		
		BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
		while(true) {
			System.out.println("명령어를 입력하세요 ");
			String command = reader.readLine(); // 한줄입력
			//exit입력받으면 종료
			if(command.equalsIgnoreCase("exit")) {
				System.out.println("종료합니다.");
				break;
			}
			//new로 시작하면 
			if(command.startsWith("new ")) {
				processNewCommand(command.split(" "));
				continue;
			}
			//change로 시작하면..
			if(command.startsWith("change ")) {
				processChangeCommand(command.split(" "));
				continue;
			}
			printHelp();
		}
	}
	
	private static void processNewCommand(String[] arg) {
		if(arg.length != 5) {
			printHelp();
			return;
		}
		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("일치하지 않음");
			return;
		}
		
		try {
			regSvc.regist(req);
			System.out.println("등록했습니다.");
			
		} catch (DuplicateMemberException e) {
			System.out.println("이미 존재하는 이메일 입니다.");
		}
	}
	
	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("암호 변경완료");
			
		} catch (MemberNotFoundException e) {
			System.out.println("존재하지 않은 이메일입니다.");
		} catch (WrongIdPasswordException e) {
			System.out.println("이메일과 암호가 일치하지 않습니다.");
		}
	}
	
	private static void printHelp() {
		System.out.println("잘못된 명령입니다!");
	}
}

DI방식 1 - 생성자 방식

  • 스프링 자바 설정에서는 생성자를 이용해서 의존 객체를 주입하기 위해 해당 설정을 담은 메서드를 호출
	// 의존 객체를 전달 받아서 주입
	// 생성자를 통해 의존하고있는 객체를 주입 받은 것
	public MemberRegisterService(MemberDao memberDao) {
		this.memberDao = memberDao;
	}
	
	public Long regist(RegisterRequest req) {
		//이메일로 회원 데이터 조회
		// 주입받은 의존 객체의 메서드를 사용
		Member member = memberDao.selectByEmail(req.getEmail());

생성자에 전달할 의존 객체가 두 개 이상

package com.jisung.spring;

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

//회원 정보 저장
public class MemberDao {
	.
    .
    .
    생략
	public Collection<Member> selectAll(){
		return map.values();
	}
}
package com.jisung.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()
		);
	}
}
package com.jisung.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));
	}
}
package config;

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

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

@Configuration // 이 클래스를 스프링 설정 클래스로 사용하겠다.
public class AppCtx {
.
.
.
.

	
	@Bean
	public MemberPrinter memberPrinter() {
		return new MemberPrinter();
	}
	
	@Bean
	public MemberListPrinter listPrinter() {
		return new MemberListPrinter(memberDao(), memberPrinter());
	}
}
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 com.jisung.spring.ChangePasswordService;
import com.jisung.spring.DuplicateMemberException;
import com.jisung.spring.MemberListPrinter;
import com.jisung.spring.MemberNotFoundException;
import com.jisung.spring.MemberRegisterService;
import com.jisung.spring.RegisterRequest;
import com.jisung.spring.WrongIdPasswordException;

import assembler.Assembler;
import config.AppCtx;

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

		//스프링 컨테이너를 생성한다. 
		//스프링 컨테이너는 객체를 생성하고 의존 객체를 주입
		// AppCtx.class(설정파일)로부터 생성할 객체와 의존주입대상을 정한다.
		ctx = new AnnotationConfigApplicationContext(config.AppCtx.class);
		
		
		BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
		while(true) {
			System.out.println("명령어를 입력하세요 ");
			String command = reader.readLine(); // 한줄입력
			//exit입력받으면 종료
			if(command.equalsIgnoreCase("exit")) {
				System.out.println("종료합니다.");
				break;
			}
			//new로 시작하면 
			if(command.startsWith("new ")) {
				processNewCommand(command.split(" "));
				continue;
			}
			//change로 시작하면..
			else if(command.startsWith("change ")) {
				processChangeCommand(command.split(" "));
				continue;
			}
			else if(command.equals("list")) {
				processListCommand();
				continue;
			}
		
			printHelp();
		}
	}
	
	private static void processNewCommand(String[] arg) {
		if(arg.length != 5) {
			printHelp();
			return;
		}
		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("일치하지 않음");
			return;
		}
		
		try {
			regSvc.regist(req);
			System.out.println("등록했습니다.");
			
		} catch (DuplicateMemberException e) {
			System.out.println("이미 존재하는 이메일 입니다.");
		}
	}
	
	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("암호 변경완료");
			
		} catch (MemberNotFoundException e) {
			System.out.println("존재하지 않은 이메일입니다.");
		} catch (WrongIdPasswordException e) {
			System.out.println("이메일과 암호가 일치하지 않습니다.");
		}
	}
	
	private static void printHelp() {
		System.out.println("잘못된 명령입니다!");
	}
	
	private static void processListCommand() {
		MemberListPrinter listPrinter = ctx.getBean("listPrinter", MemberListPrinter.class);
		listPrinter.printAll();
	}
}

DI방식 2 - 세터 메서드 방식

  • 생성자 외에 세터 메서드를 이용해서 객체를 주입
    • 메서드 이름이 set으로 시작해야한다
    • set 뒤에 첫 글자는 대문자로 시작해야한다
    • 파라미터가 1개이다
    • 리턴 타입이 void이다.
package com.jisung.spring;

//지정한 이메일을 갖는 member를 찾아서 정보를 콘솔에 출력
public class MemberInfoPrinter {
	private MemberDao memberDao;
	private MemberPrinter memberPrinter;
	
	public void printMemberInfo(String email) {
		Member member = memberDao.selectByEmail(email);
		if(member == null) {
			System.out.println("데이터 없음\n");
			return;
		}
		memberPrinter.print(member);
		System.out.println();
	}

	//세터 메서드를 이용해서 의존성 주입
	
	public void setMemberDao(MemberDao memberDao) {
		this.memberDao = memberDao;
	}

	public void setMemberPrinter(MemberPrinter memberPrinter) {
		this.memberPrinter = memberPrinter;
	}
	
}
package config;

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

import com.jisung.spring.ChangePasswordService;
import com.jisung.spring.MemberDao;
import com.jisung.spring.MemberInfoPrinter;
import com.jisung.spring.MemberListPrinter;
import com.jisung.spring.MemberPrinter;
import com.jisung.spring.MemberRegisterService;

@Configuration // 이 클래스를 스프링 설정 클래스로 사용하겠다.
public class AppCtx {
	
	//@Bean
	// - 해당 메서드가 생성한 객체를 스프링 빈이라고 설정
	// - 메서드 이름을 빈 객체의 이름으로 사용하겠다.
	
	@Bean
	public MemberDao memberDao() {
		return new MemberDao();
	}
	
	@Bean
	public MemberRegisterService memberRegSvc() {
		//memberDao()가 생성한 객체를 주입
		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 listPrinter() {
		return new MemberListPrinter(memberDao(), memberPrinter());
	}
	
	@Bean
	public MemberInfoPrinter infoPrinter() {
		MemberInfoPrinter infoPrinter = new MemberInfoPrinter();
		//빈 주입
		infoPrinter.setMemberDao(memberDao());
		infoPrinter.setMemberPrinter(memberPrinter());
		return infoPrinter;
	}
}
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 com.jisung.spring.ChangePasswordService;
import com.jisung.spring.DuplicateMemberException;
import com.jisung.spring.MemberInfoPrinter;
import com.jisung.spring.MemberListPrinter;
import com.jisung.spring.MemberNotFoundException;
import com.jisung.spring.MemberRegisterService;
import com.jisung.spring.RegisterRequest;
import com.jisung.spring.WrongIdPasswordException;

import assembler.Assembler;
import config.AppCtx;

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

		//스프링 컨테이너를 생성한다. 
		//스프링 컨테이너는 객체를 생성하고 의존 객체를 주입
		// AppCtx.class(설정파일)로부터 생성할 객체와 의존주입대상을 정한다.
		ctx = new AnnotationConfigApplicationContext(config.AppCtx.class);
		
		
		BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
		while(true) {
			System.out.println("명령어를 입력하세요 ");
			String command = reader.readLine(); // 한줄입력
			//exit입력받으면 종료
			if(command.equalsIgnoreCase("exit")) {
				System.out.println("종료합니다.");
				break;
			}
			//new로 시작하면 
			if(command.startsWith("new ")) {
				processNewCommand(command.split(" "));
				continue;
			}
			//change로 시작하면..
			else if(command.startsWith("change ")) {
				processChangeCommand(command.split(" "));
				continue;
			}
			else if(command.equals("list")) {
				processListCommand();
				continue;
			}
			else if(command.startsWith("info ")) {
				processInfoCommand(command.split(" "));
				continue;
			}
		
			printHelp();
		}
	}
	
	private static void processNewCommand(String[] arg) {
		if(arg.length != 5) {
			printHelp();
			return;
		}
		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("일치하지 않음");
			return;
		}
		
		try {
			regSvc.regist(req);
			System.out.println("등록했습니다.");
			
		} catch (DuplicateMemberException e) {
			System.out.println("이미 존재하는 이메일 입니다.");
		}
	}
	
	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("암호 변경완료");
			
		} catch (MemberNotFoundException e) {
			System.out.println("존재하지 않은 이메일입니다.");
		} catch (WrongIdPasswordException e) {
			System.out.println("이메일과 암호가 일치하지 않습니다.");
		}
	}
	
	private static void printHelp() {
		System.out.println("잘못된 명령입니다!");
	}
	
	private static void processListCommand() {
		MemberListPrinter listPrinter = ctx.getBean("listPrinter", MemberListPrinter.class);
		listPrinter.printAll();
	}
	
	private static void processInfoCommand(String[] arg) {
		MemberInfoPrinter infoPrinter = ctx.getBean("infoPrinter",MemberInfoPrinter.class);
		infoPrinter.printMemberInfo(arg[1]);
	}
}

생성자 vs 세터 메서드

  • 생성자 방식
    빈 객체를 생성하는 시점에 모든 의존 객체가 주입
  • 설정 메서드 방식
    세터 메서드 이름을 통해 어떤 의존 객체가 주입되는지 알 수 있다.

기본 데이터 타입 값 설정

package com.jisung.spring;


//두 개의 int 타입 값을 세터 메서드로 전달받는다.
public class VersionPrinter {
	
	private int majorVersion;
	private int minorVersion;
	
	public void setMajorVersion(int majorVersion) {
		this.majorVersion = majorVersion;
	}
	public void setMinorVersion(int minorVersion) {
		this.minorVersion = minorVersion;
	}
	
	public void print() {
		System.out.printf("이 프로그램의 버전은 %d.%d입니다\n\n",majorVersion,minorVersion);
	}
	
}	
package config;

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

import com.jisung.spring.ChangePasswordService;
import com.jisung.spring.MemberDao;
import com.jisung.spring.MemberInfoPrinter;
import com.jisung.spring.MemberListPrinter;
import com.jisung.spring.MemberPrinter;
import com.jisung.spring.MemberRegisterService;
import com.jisung.spring.VersionPrinter;

@Configuration // 이 클래스를 스프링 설정 클래스로 사용하겠다.
public class AppCtx {
	
	//@Bean
	// - 해당 메서드가 생성한 객체를 스프링 빈이라고 설정
	// - 메서드 이름을 빈 객체의 이름으로 사용하겠다.
	
	@Bean
	public MemberDao memberDao() {
		return new MemberDao();
	}
	
	@Bean
	public MemberRegisterService memberRegSvc() {
		//memberDao()가 생성한 객체를 주입
		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 listPrinter() {
		return new MemberListPrinter(memberDao(), memberPrinter());
	}
	
	@Bean
	public MemberInfoPrinter infoPrinter() {
		MemberInfoPrinter infoPrinter = new MemberInfoPrinter();
		//빈 주입
		infoPrinter.setMemberDao(memberDao());
		infoPrinter.setMemberPrinter(memberPrinter());
		return infoPrinter;
	}
	
	@Bean
	public VersionPrinter versionPrinter() {
		VersionPrinter versionPrinter = new VersionPrinter();
		versionPrinter.setMajorVersion(5);
		versionPrinter.setMinorVersion(0);
		return versionPrinter;
	}
}
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 com.jisung.spring.ChangePasswordService;
import com.jisung.spring.DuplicateMemberException;
import com.jisung.spring.MemberInfoPrinter;
import com.jisung.spring.MemberListPrinter;
import com.jisung.spring.MemberNotFoundException;
import com.jisung.spring.MemberRegisterService;
import com.jisung.spring.RegisterRequest;
import com.jisung.spring.VersionPrinter;
import com.jisung.spring.WrongIdPasswordException;

import assembler.Assembler;
import config.AppCtx;

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

		//스프링 컨테이너를 생성한다. 
		//스프링 컨테이너는 객체를 생성하고 의존 객체를 주입
		// AppCtx.class(설정파일)로부터 생성할 객체와 의존주입대상을 정한다.
		ctx = new AnnotationConfigApplicationContext(config.AppCtx.class);
		
		
		BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
		while(true) {
			System.out.println("명령어를 입력하세요 ");
			String command = reader.readLine(); // 한줄입력
			//exit입력받으면 종료
			if(command.equalsIgnoreCase("exit")) {
				System.out.println("종료합니다.");
				break;
			}
			//new로 시작하면 
			if(command.startsWith("new ")) {
				processNewCommand(command.split(" "));
				continue;
			}
			//change로 시작하면..
			else if(command.startsWith("change ")) {
				processChangeCommand(command.split(" "));
				continue;
			}
			else if(command.equals("list")) {
				processListCommand();
				continue;
			}
			else if(command.startsWith("info ")) {
				processInfoCommand(command.split(" "));
				continue;
			}
			else if(command.equals("version")) {
				processVersionCommand();
				continue;
			}
		
			printHelp();
		}
	}
	
	private static void processNewCommand(String[] arg) {
		if(arg.length != 5) {
			printHelp();
			return;
		}
		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("일치하지 않음");
			return;
		}
		
		try {
			regSvc.regist(req);
			System.out.println("등록했습니다.");
			
		} catch (DuplicateMemberException e) {
			System.out.println("이미 존재하는 이메일 입니다.");
		}
	}
	
	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("암호 변경완료");
			
		} catch (MemberNotFoundException e) {
			System.out.println("존재하지 않은 이메일입니다.");
		} catch (WrongIdPasswordException e) {
			System.out.println("이메일과 암호가 일치하지 않습니다.");
		}
	}
	
	private static void printHelp() {
		System.out.println("잘못된 명령입니다!");
	}
	
	private static void processListCommand() {
		MemberListPrinter listPrinter = ctx.getBean("listPrinter", MemberListPrinter.class);
		listPrinter.printAll();
	}
	
	private static void processInfoCommand(String[] arg) {
		MemberInfoPrinter infoPrinter = ctx.getBean("infoPrinter",MemberInfoPrinter.class);
		infoPrinter.printMemberInfo(arg[1]);
	}
	
	private static void processVersionCommand() {
		VersionPrinter versionPrinter = ctx.getBean("versionPrinter", VersionPrinter.class);
		versionPrinter.print();
	}
}

좋은 웹페이지 즐겨찾기