Spring Bean,의존객체 자동 주입

정원·2022년 6월 3일
0

Spring

목록 보기
3/11

22.06.03

빈(Bean)의 범위

  • 싱글톤(Singleton)
    :스프링 컨테이너에서 생성된 빈(Bean)객체의 경우 동일한 타입에 대해서는 기본적으로 한 개만 생성이 되며,
    getBean() 메서드로 호출될 때 동일한 객체가 반환 된다.
    기본적으로 싱글톤 패턴
  • 프로토타입(Prototype)
    :싱글톤 범위와 반대의 개념도 있는데 이를 프로토타입(Prototype) 범위라고 한다.
    프로토타입의 경우 개발자는 별도로 설정을 해줘야 하는데, 스프링 설정 파일에서
    빈 (Bean)객체을 정의할 때 scope속성을 명시해 주면 된다.
<bean id="good" class="day01.SpringTest" 
scope="prototype"/
  • Person class
<script>
public class Person {
	private String name;
	private int age;
	
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	
	
}
</script>
  • prototype-confog.xml
<bean id="person" class="basic.ex03.Person">
		<property name="name" value="홍길동"/>
		<property name="age" value="20"/>
	</bean>
  • MainClass class
    DI는 기본적으로 싱글톤패턴이기 때문에 아무리 객체를 새로 받아와도 똑같은 하나의 객체를 참조한다.
<script>
public class MainClass {

	public static void main(String[] args) {
		
		GenericXmlApplicationContext ct =
				new GenericXmlApplicationContext("classpath:prototype-config.xml");
		
		Person hong = ct.getBean("person", Person.class);
		
		//새로운 객체를 받아왔으니 주소값이 다르지 않을까?
		Person kim = ct.getBean("person", Person.class);
		kim.setAge(30);
		kim.setName("김철수");
		
		System.out.println("hong의 주소값:" + hong);//Person@210366b4
		System.out.println("kim의 주소값:" + kim);//Person@210366b4
		System.out.println("hong과 kim은 같은 객체인가??" + (hong == kim));//true
		
		//kim을 변경하면 hong과 kim둘다 변경되고 같은 값이 나온다!!	
		System.out.println("hong의 이름:" + hong.getName());//김철수
		System.out.println("hong의 나이:" + hong.getAge());//30
		System.out.println("kim의 이름:" + kim.getName());//김철수
		System.out.println("kim의 나이:" + kim.getAge());//30
	}
}
</script>

객체를 부를때마다 새로운 객체를 받고 싶을때는 어떻게 할까?
prototype-confog.xml에 scope를 추가한다!

<bean id="person" class="basic.ex03.Person" scope="prototype">

의존객체 자동 주입 @Autowired

의존 객체 자동 주입이란?
스프링 설정 파일에서 의존 객체를 주입할 때
<constructor-org> 또는 <property> 태그로 의존 대상 객체를 명시하지 않아도
스프링 컨테이너가 자동으로 필요한 의존 대상 객체를 찾아서
의존 대상 객체가 필요한 객체에 주입해 주는 기능이다.
구현 방법은 @Autowired@Resource 어노테이션을 이용해서 쉽게 구현할 수 있다.

@Autowired

  • 객체를 자동 주입할 때 사용하는 아노테이션입니다.
    - 스캔 명령을 통해 객체를 찾아 주입하는데, 타입 이름으로 검색합니다.
    - 타입을 찾아내지 못하면 이름(id 속성값)을 통해 검색합니다.
    - 생성자, 메서드, 필드에 적용 가능합니다.

기존방식

  • Paper class
<script>
public class Paper {
	
	public String[] data = {
			"스프링 프레임워크", "자동 객체 주입",
			"Autowired는 객체의 타입을 검색하여 자동 주입"
	};
}
</script>
  • Printer class
<script>
public class Printer {

private Paper paper;
	
	public void setPaper(Paper paper) {
		this.paper = paper;
	}
	
	public void showPaperInfo() {
		for(String info : paper.data) {
			System.out.println(info);
		}
	}
}
</script>
  • auto-config.xml
<bean id="paper" class="basic.ex04.Paper" />
	
<bean id="prt" class="basic.ex04.Printer">
	<property name="paper" ref="paper"/>
</bean>
  • MainClass class
<script>
public class MainClass {

	public static void main(String[] args) {

		GenericXmlApplicationContext ct = 
				new GenericXmlApplicationContext("classpath:auto-config.xml");
		
		Printer printer = ct.getBean("prt", Printer.class);
		printer.showPaperInfo();
        ct.close();
	}
}
</script>

의존객체 자동 주입

1.mxl파일에 설정 추가자동스캔 명령 추가 <context:annotation-config/>

	<!-- 자동 스캔 명령 추가 -->
	<context:annotation-config/>	
	
	<bean id="paper" class="basic.ex04.Paper" />
	
	<bean id="prt" class="basic.ex04.Printer" />
	<!-- 자동스캔 이용하면 필요없음  property name="paper" ref="paper"-->

2.Printer class에 어노테이션 추가
변수,생성자,setter위에 @Autowired 추가하면 자동 호출이 가능하다.

@Autowired	
private Paper paper;

@Qualifier

: Autowired를 사용할 때 동일 타입의 빈이 여러 개 있는 경우
어떤 빈을 중비해야 하는 지 선택해 주는 추가 아노테이션입니다. 단독으로 사용불가

만약 .xml파일에서 동일한 객체가 2개 이상인 경우 스프링 컨테이너는
자동 주입 대상 객체를 판단하지 못해서 Exception을 발생시킨다.

<bean id="paper1" class="basic.ex04.Paper" />
<bean id="paper2" class="basic.ex04.Paper" />
<!-- expected single matching bean but found 2: paper1,paper2 에러 -->

해결방법은 @Autowired 와 함께 @Qualifier("Bean id")추가해주면 된다.

//xml에 같은 타입이 2개일때 어떤 타입을 사용할지 지정할때
	@Autowired	
	@Qualifier("paper2")
	private Paper paper;

변수에 하나하나 @Autowired 걸어도 되고
모든 필드값을 받는 생성자를 하나 만들어서 @Autowired 하면 한번에 걸수있음.

	//@Autowired
	private Keyboard keyboard;
	//@Autowired
	private Mouse mouse;
	//@Autowired
	private Monitor monitor;
	
	@Autowired
	public Computer(Keyboard keyboard, Mouse mouse, Monitor monitor) {
		super();
		this.keyboard = keyboard;
		this.mouse = mouse;
		this.monitor = monitor;
	}

@Resource

  • @Autowired 과 같은 기능.
  • 빈을 자동으로 주입하는 아노테이션 입니다.
  • 필드, 메서드에만 적용이 가능하며, 생성자에는 적용이 불가능합니다.
  • name 속성을 통해 특정 bean의 id를 지목할 수 있습니다.
  • 타입이 겹치지 않을 때도 name 속성을 작성해줘야 한다.
  • java 라이브러리에서 제공 (8버전이후에는 사용불가)

연습

  • auto-config.xml
<!-- java 라이브러리가 제공하는 자동 스캔 명령 이용 -->
	<bean id="book" class="basic.ex04.Book"/>
  • Book class
<script>
public class Book {
	
	//스프링 제공 자동스캔
	@Autowired
	@Qualifier("paper1")
	//자바에서 제공 자동스캔
	@Resource(name="paper1")
	private Paper paper;
    
	public void setPaper(Paper paper) {
		this.paper = paper;
	}
	
	public Paper getPaper() {
		return paper;
	}	
}
</script>

0개의 댓글