프로그래밍/Spring & Spring boot

07 Spring : Annotation 을 통해 의존성 주입하기/ @Autowired

pupu91 2022. 9. 1. 20:06
반응형

 

필드에 @ Annotation

 

  • DTO 생성
package com.greedy.section01.fieldinjection.javaconfig;

import java.util.Date;

public class BookDTO {
	
	
	private int sequence;
	private int isbm;
	private String title;
	private String author;
	private String publisher;
	private java.util.Date createdDate;
	
	public BookDTO() {}

	public BookDTO(int sequence, int isbm, String title, String author, String publisher, Date createdDate) {
		super();
		this.sequence = sequence;
		this.isbm = isbm;
		this.title = title;
		this.author = author;
		this.publisher = publisher;
		this.createdDate = createdDate;
	}

	public int getSequence() {
		return sequence;
	}

	public void setSequence(int sequence) {
		this.sequence = sequence;
	}

	public int getIsbm() {
		return isbm;
	}

	public void setIsbm(int isbm) {
		this.isbm = isbm;
	}

	public String getTitle() {
		return title;
	}

	public void setTitle(String title) {
		this.title = title;
	}

	public String getAuthor() {
		return author;
	}

	public void setAuthor(String author) {
		this.author = author;
	}

	public String getPublisher() {
		return publisher;
	}

	public void setPublisher(String publisher) {
		this.publisher = publisher;
	}

	public java.util.Date getCreatedDate() {
		return createdDate;
	}

	public void setCreatedDate(java.util.Date createdDate) {
		this.createdDate = createdDate;
	}

	@Override
	public String toString() {
		return "BookDTO [sequence=" + sequence + ", isbm=" + isbm + ", title=" + title + ", author=" + author
				+ ", publisher=" + publisher + ", createdDate=" + createdDate + "]";
	}
	
	
}

 

 

 

 

  • Interface 생성
package com.greedy.section01.fieldinjection.javaconfig;

import java.util.List;

public interface BookDAO {
	
    도서 목록 전체 조회
    List<BookDTO> selectBookList();
   
    도서 번호로 도서 조회
    BookDTO selectOneBook(int sequence);
}

 

 

 

 

 

 

  • 상속받은 class 생성
@Repository("bookDAO") 이름 작성하지 않으면 class이름으로 자동 설정됨
public class BookDAOImpl implements BookDAO{
	
    private Map<Integer, BookDTO> bookList;
    
    public BookDAOImpl(){
    	bookList = new HashMap<>;
        bookList.put(1, new BookDTO(1, new BookDTO(1, 123456, "자바의정석", "남궁성", "도우출판", new java.util.Date()));
        bookList.put(1, new BookDTO(2, 654321, "칭찬은 고래도 춤추게 한다", "고래", "바다출판", new java.util.Date()));
        	}
	
    @Override
	public List<BookDTO> selectBookList() {
		
		return new ArrayList<BookDTO>(bookList.values()); 
        selectBookList요청했을 때 ArrayList객체를 생성해서 bookListt의 value값만 넣어주세요
	}

	@Override
	public BookDTO selectOneBook(int sequence) {
		
		return bookList.get(sequence); 
	}

}

 

 

 

 

 

 

반응형
  • Service class 생성

       : service 계층에서는 @Service 어노테이션을 사용 (bean 등록)

public class BookService {

	@Autowired
    private BookDAO bookDAO
    
    public List<BookDTO> selectAllBooks{
    
    	return bookDAO.selectBookList();
    }

	public BookDTO searchBookBySequence(int sequence){
    	return bookDAO.selectOneBook(sequence)
    }
    
}

 

 

 

 

 

 

  • 출력하기 
package com.greedy.section01.fieldinjection.javaconfig;

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

public class Application {

	public static void main(String[] args) {
		
		
		ApplicationContext context = new AnnotationConfigApplicationContext("com.greedy.section01.fieldinjection.javaconfig"); 
        베이스패키지를 따로 설정 클래스가 아닌 문자열로 전달하는것도 가능함.
		
		
		BookService bookService = context.getBean("bookService", BookService.class);
		
		전체 목록 조회
		for(BookDTO book : bookService.selectAllBooks()) {
			System.out.println(book);
		}
		
		시퀀스로 검색
		System.out.println(bookService.searchBookBySequence(2));
			
	}

}

출력결과
전체 목록 조회 : BookDTO [sequence=1, isbm=123456, title=자바의정석, author=남궁성, publisher=도우출판, createdDate=Thu Sep 01 19:14:45 KST 2022]
전체 목록 조회 : BookDTO [sequence=2, isbm=654321, title=칭찬은 고래도 춤추게 한다, author=고래, publisher=바다출판, createdDate=Thu Sep 01 19:14:45 KST 2022]
시퀀스로 검색 : BookDTO [sequence=2, isbm=654321, title=칭찬은 고래도 춤추게 한다, author=고래, publisher=바다출판, createdDate=Thu Sep 01 19:14:45 KST 2022]

 

 

 

 

 

생성자에 @Annotation

장점

1) 필드에 final 키워드 사용이 가능해지므로 변경 불가능하게 사용할 수 있다.

2) 순환 참조 방지(필드 주입이나 세터 주입은 메소드 실행 시점에만 오류가 발생하지만 생성자 주입의 경우 어플리케이션 실행 시점에서 확인 가능)

3) DI 컨테이너와의 결합도가 낮기 때문에 테스트 하기 좋음(스프링 컨테이너 없이 테스트 가능)

 

 

 

@Configuration
@ComponentScan("com.greedy.section02.constinjection.javaconfig")
public class ContextConfiguration {
	
	@Bean
	public RandomGenerator randomGenerator() throws Exception {
		
		return new RandomNumberGenerator(1, 10);
	}
	
}

 

 

 

  • interface 생성
public interface RandomGenerator {
	
	난수 발생시키는 메소드
	int getRandomNumber();
	
	난수 시작 값 가져오는 메소드
	int getStartNum();
	
	난수 종료 값 가져오는 메소드
	int getEndNum();
}

 

 

 

 

 

  • 상속받는 class 생성
public class RandomNumberGenerator implements RandomGenerator {
	
	private int startNum;
	private int endNum;
	
	public RandomNumberGenerator(int startNum, int endNum) throws Exception {
		
		if(startNum >= endNum) {
			throw new Exception("시작 값이 종료 값보다 클 수 없습니다.");
		} else if(startNum <= 0 && endNum <= 0){
			throw new Exception("양의 정수만 입력해주세요");
		}
		
		this.startNum = startNum;
		this.endNum = endNum;
	}

	@Override
	public int getRandomNumber() {
		return (int)(Math.random() * (endNum - startNum + 1)) + startNum;
	}

	@Override
	public int getStartNum() {
		return startNum;
	}

	@Override
	public int getEndNum() {
		return endNum;
	}
	

}

 

 

 

 

 

  • 생성자에 @Autowired 사용

       : 생성자가 1개일 때는 @Autowired 생략해도 자동으로 주입해줌

 

@Component
public class MakeRandomString {
	
    private RandomGenerator random;
    
    @Autowired 
    public MakeRandomString(RandomGenerator random) {
		this.random = random; 
	}
    => (전달할 bean객체) 이 값이 this.random에 넣어주는 생성자
    
    
    public String getRandomLengthString() {
		
		StringBuilder sb = new StringBuilder();
        => 재할당이 이러나지 않도록 StringBuilder 사용
		
		int randomNumber = random.getRandomNumber(); 
		for(int i = random.getStartNum(); i <= randomNumber; i++) {
			sb.append("*");
		
		
	} 
		return sb.toString();
        => 랜덤한 길이의 문자열을 만드는 메소드를 리턴값으로 설정
	}
 }

 

 

 

 

 

 

  • Setter 메소드에서도 사용가능  
@Component
public class MakeRandomString {
	
	
	private RandomGenerator random;
	
	@Autowired
	public void setRandom(RandomGenerator random) {
		this.random = random;
	}
	
	
    public String getRandomLengthString() {
		
		StringBuilder sb = new StringBuilder(); 
		
		int randomNumber = random.getRandomNumber();
		for(int i = random.getStartNum(); i <= randomNumber; i++) {
			sb.append("*");	
	} 
		return sb.toString();
	}

 

 

 

 

  • 출력하기
public class Application {

	public static void main(String[] args) {
		
		ApplicationContext context = new AnnotationConfigApplicationContext(ContextConfiguration.class);
		
		MakeRandomString randomString = context.getBean(MakeRandomString.class);
		
		System.out.println(randomString.getRandomLengthString());
		System.out.println(randomString.getRandomLengthString());
		System.out.println(randomString.getRandomLengthString());
		System.out.println(randomString.getRandomLengthString());
		System.out.println(randomString.getRandomLengthString());
		System.out.println(randomString.getRandomLengthString());

	}

}

출력 결과
*********
**
*****
**
******
*****

 

반응형