프로필사진
DI(2) - Annotation사용하기

2019. 11. 13. 10:32🔴 Spring

300x250

Annotation : 클래스, 필드, 메소드의 선언부에 적용 가능 = 도움말기능

 

@Scope (value=" ") : 추가적인 어노테이션, default = singleton

 

@Required : setter주입방식 이용, 필수 프로퍼티 명시

XML설정에 context:annotation-config/추가
false = null값 O
true = null값 X


@Autowired : by type → bean 찾아 주입
자동 주입 대상에 @Autowired사용 + XML설정에 context:annotation-config/추가

  1. 타입 같은 Bean객체 검색 → 한 개이면 사용
  2. @Qualifier가 있으면 → 해당 값을 갖는 Bean객체 사용
  3. 타입 같은 Bean이 두 개이면 → @Qualifier로 찾음
  4. 그 외, 이름(value)이 같은 Bean객체 사용

+ @Qualifier : 사용할 의존객체를 선택
설정에서 Bean의 한정자 설정
@Autowired 적용된 주입 대상에 → @Qualifier 설정 (한정자 사용)

@Resource : by name → bean 찾아 주입
자동 주입 대상에 @Resource사용 + XML설정에 context:annotation-config/추가

  1. name에 지정한 Bean 객체 검색 → 사용
  2. name속성이 없으면 → 동일한 타입갖는 Bean 객체 검색
  3. name속성 없고 동일한 타입인 Bean이 두 개 이상 → 같은 이름의 Bean 검색
  4. 그 외, @Qualifier로 찾음

*** 자동주입 & 명시적 의존 주입 함께일때 : 명시적 의존 주입설정 우선임!!

*** 흐름 :
1) java파일 토대로 xml이 Bean을 생성, 주입
2) MainMethod에서 "new GenericXmlApplicationContext"으로 스프링 컨테이너 생성

 

<appCtx6.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"
	xmlns:p="http://www.springframework.org/schema/p"
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd">
	
	<context:annotation-config />		

	<!-- @Autowired : 자동 주입 대상 by type -> MemberDao -->
	<!-- @Resource(name="memberdao2") : 빈의 이름을 이용해서 주입할 객체 검색 -> <암호변경> MemberDao -->
	<bean id="memberDao2" class="member.MemberDao" />
	
	<!-- @Qualifier("sys") : 사용할 의존 객체 선택 -> MemberDao -->
	<!-- !! @Autowired 적용된 주입 대상에 설정해야함, 한정자 설정해야함 -->
	<!-- @Resource(name="memberdao1") : 빈의 이름을 이용해서 주입할 객체 검색 -> <회원가입> MemberDao -->
	<bean id="memberDao1" class="member.MemberDao" >
		<qualifier value="sys" />
	</bean>
	
	<bean id="boardDao" class="member.BoardDao"/>

	<bean id="registService" class="member.MemberRegisterService"></bean>

	<bean id="changePwService" class="member.ChangePasswordService"></bean>

</beans>

<MemberRegisterService.java>

package member;
// 회원가입 처리 
import java.util.Date;

import javax.annotation.Resource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

@Service
public class MemberRegisterService {
	
	@Autowired(required = false)
	@Qualifier("sys")
	//@Resource(name="memberdao1")
	private MemberDao memberDao;
	
	// setter 방식 (property사용)
//	public void setMemberDao(MemberDao memberDao) {
//		this.memberDao = memberDao;
//	}
	/*
	 * public MemberRegisterService(MemberDao memberDao) { this.memberDao =
	 * memberDao; }
	 */

	public void regist(RegisterRequest request) throws AlreadyExistingMemberException {
		
		// 사용자가 입력한 email -> 기존 저장된 데이터에 있는지 찾기
		Member member = memberDao.selectByEmail(request.getEmail());

		if (member != null) {
			throw new AlreadyExistingMemberException();
		}
		
		// 겹치는 데이터가 없으면 회원가입 실행
		Member newMember = new Member(request.getEmail(), request.getPassword(), request.getName(), new Date());
		
		// + id도 같이 생성
		memberDao.insert(newMember);

	}

}

<ChangePasswordService.java>

package member;

import javax.annotation.Resource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

//@Service

// 암호변경 
public class ChangePasswordService {

	@Autowired
	@Qualifier("sys")
	//@Resource(name="memberdao2")
	//@Resource(name = "boardDao")
	private MemberDao memberDao;
	
	/*
	 * public ChangePasswordService(MemberDao dao) {
	 * 
	 * memberDao = dao;
	 * 
	 * }
	 */

	// setter 방식 (property사용)
	/*
	 * public void setMemberDao(MemberDao memberDao) { this.memberDao = memberDao; }
	 */

	public void changePassword(String email, String oldPassword, String newPassword)
			throws MemberNotFoundException, IdPasswordNotMatchingException {

		Member member = memberDao.selectByEmail(email);

		if (member == null) {
			throw new MemberNotFoundException();
		}

		member.changePassword(oldPassword, newPassword);

		memberDao.update(member);

	}

}

<MainForSpring.java>

package member;

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

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

public class MainForSpring {

	// private static Assembler assembler = new Assembler();

	// 스프링 컨테이너 생성 : 
  // 조립기 설정파일 appCtx.xml, main method안에서 불러야 하니깐 static으로
	private static ApplicationContext ctx =
			new GenericXmlApplicationContext("classpath:appCtx7.xml");

	public static void main(String[] args) throws IOException {

		// 사용자가 입력한 문자열 -> reader 읽어오기
		BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));

		while (true) {

			System.out.println("명령어를 입력해주세요.");

			String command = reader.readLine(); // 한줄 단위로 읽어오기

			// 3. 종료
			if (command.equalsIgnoreCase("exit")) {
				System.out.println("종료합니다.");
				break;
			}

			// 1. 회원가입
			// new kkangdda 1111 1111 daeun -> 띄어쓰기 split
			if (command.startsWith("new ")) {
				processNewCommand(command.split(" "));
			}

			// 2. 암호변경
			if (command.startsWith("change ")) {
				processChangeCommand(command.split(" "));
			}
		}
	}
	
	// -- 1. 회원가입
	private static void processNewCommand(String[] args) {
		// 잘라져서 들어오는 문자열의 배열이 5개인지 확인
		if (args.length != 5) {
			printHelp();
			return;
		}

		// 객체는 조립기에서 보관하고있음, 조립기에서 가져오기! (의존성 낮춤)
		// 여기서 new로 새로운 객체를 생성할 필요가 없다는 말!!!
		// MemberRegisterService service = assembler.getRegisterService();
										// 컨테이너에게 bean객체 반환을 요청하는 것, 
										// xml에서 memberDao를 주입하고 반환시킨다 !!
										// 반환 타입은 MemberRegisterService class타입으로
		MemberRegisterService service = ctx.getBean("registService", MemberRegisterService.class);
				
		RegisterRequest request = new RegisterRequest();

		// ex) new 이메일 사용자이름 암호 암호확인 -> 이메일 = index(1)
		request.setEmail(args[1]);
		request.setName(args[2]);
		request.setPassword(args[3]);
		request.setConfirmPassword(args[4]);

		if (!request.isPasswordEqualToConfirmPassword()) {
			System.out.println("암호 확인이 일치하지 않습니다.");
		}

		try {
			service.regist(request);
			System.out.println("등록되었습니다.");
		} catch (AlreadyExistingMemberException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			System.out.println("이미 존재하는 이메일입니다.");
		}

	}

	// -- 2. 암호변경
	private static void processChangeCommand(String[] args) {
		if (args.length != 4) {
			printHelp();
			return;
		}

		// ChangePasswordService service = assembler.getPwService();
		ChangePasswordService service = ctx.getBean("changePwService", ChangePasswordService.class);

		try {
			service.changePassword(args[1], args[2], args[3]);
			System.out.println("암호가 변경되었습니다.");
		} catch (MemberNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			System.out.println("존재하지 않는 이메일입니다.");
		} catch (IdPasswordNotMatchingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			System.out.println("이메일과 암호가 일치하지 않습니다.");
		}
	}

	// -- 잘못된 방식으로 입력했을 때 출력 :
	private static void printHelp() {
		System.out.println("");
		System.out.println("잘못된 명령입니다, 아래 명령사용법을 확인하세요");
		System.out.println("new 이메일 사용자이름 암호 암호확인");
		System.out.println("change 이메일 현재암호 새로운암호");
	}

}

@Component : 자동으로 bean으로 등록, bean 스캐닝 기능

스프링 설정 파일 (servlet-context.xml)에 <context:component-scan base-package=" ">태그 추가
→ 어노테이션이 적용된 클래스를 빈으로 등록
XML문서와 같이 한곳에 명시적으로 선언 X → Bean으로 사용될 클래스에 붙여서 자동으로 등록

클래스 선언구 부분에 위치
Bean으로 클래스 등록 : 클래스 이름 → Bean의 이름으로 사용 (첫글자 소문자)
기본범위 = singleton

 

<appCtx8.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"
	xmlns:p="http://www.springframework.org/schema/p"
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd">
	
	<context:annotation-config/>
	
	<!-- @Component : 해당 어노테이션이 붙은 클래스를 자동으로 빈으로 등록 -> MemberDao -->
	<context:component-scan base-package="member"/>
	
	+<context:include-filer>, <context:exclude-filter> -> 스캔 대상 제한 (=AOP)
	
</beans>
@Service("changePasswordService")
// 암호변경 
public class ChangePasswordService2 {

...

@Service("registService")
public class MemberRegisterService2 {
300x250