Java/Spring

[Spring] 08. <bean> 속성 사용하기 - Autowire

담크 2021. 6. 23. 17:30

오늘은 spring의 bean속성 중 autowire라는 기능에 대해 정리해보려고 합니다.

새로운 프로젝트부터 만들러 가볼까요?

(프로젝트는 그냥 큰 구분을 위한 것일 뿐 굳이 새로 안 만들어도 상관없습니다.)

Spring04로 자바프로젝트 만들고 convert to maven project 해주시고 평소와 같이 spring-core와 spring-context를 pom.xml에 붙여줍니다.

그다음 패키지 만들러 가봅시다!

Food.java

package com.test02;

public class Food {
	
	private String name;
	private int price;
	
	public Food() {
	}
	public Food(String name, int price) {
		this.name = name;
		this.price = price;
	}
	public void setName(String name) {
		this.name = name;
	}
	public void setPrice(int price) {
		this.price = price;
	}
	@Override
	public String toString() {
		return "Food [name=" + name + ", price=" + price + "]";
	}
}

MyFood.java

package com.test02;

public class MyFood {
	
	private Food favoriteFood;
	private Food unFavoriteFood;
	
	public MyFood() {
	}
	public MyFood(Food favoriteFood, Food unFavoriteFood) {
		this.favoriteFood = favoriteFood;
		this.unFavoriteFood = unFavoriteFood;
	}

	public Food getFavoriteFood() {
		return favoriteFood;
	}
	public void setFavoriteFood(Food favoriteFood) {
		this.favoriteFood = favoriteFood;
	}
	public Food getUnFavoriteFood() {
		return unFavoriteFood;
	}
	public void setUnFavoriteFood(Food unFavoriteFood) {
		this.unFavoriteFood = unFavoriteFood;
	}
	@Override
	public String toString() {
		return "favorite : " + favoriteFood + "\nunFavorite : " + unFavoriteFood;
	}
}

MTest.java

package com.test02;

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

public class MTest {
	
	public static void main(String[] args) {
		
		ApplicationContext factory = new ClassPathXmlApplicationContext("com/test02/applicationContext.xml");
		
		MyFood my = factory.getBean("myFood", MyFood.class);
		System.out.println(my);
	}
}

applicationContext.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="favoriteFood" name="favoriteFood" class="com.test02.Food">
		<property name="name" value="치킨" />
		<property name="price" value="20000" />
	</bean>
	
	<bean id="unFavoriteFood" name="unFavoriteFood" class="com.test02.Food">
		<constructor-arg value="해물찜" />
		<constructor-arg value="40000" />
	</bean>
	
	<bean id="myFood" class="com.test02.MyFood">
		<property name="favoriteFood" ref="favoriteFood" />
		<property name="unFavoriteFood" ref="unFavoriteFood"></property>
	</bean>
</beans>

코드 실행결과

 

autowire를 사용하기전엔 <property> 혹은 <constructor-arg>를 사용해야 객체를 가져와서 사용할 수 있었습니다.

먼저 autowire엔 4가지 속성이 있는데 하나하나 살펴보겠습니다.

(no를 포함하면 5가지지만 no는 안쓰는것과 같으므로 따로 정리하진 않습니다.)

 

1. byName : setter와 같은 이름의 bean (id/name) 이 있으면 자동 할당

현재 MyFood의 setter와 같은 이름인 favoriteFood와 unFavoriteFood가 있으므로 자동 할당됩니다.

결과 잘나오죠 ㅎㅎ

그렇다면 favoriteFood에서 Food를 뺀다면 어떻게 될까요?

그렇게 된다면 setter와 같은 이름의 favoriteFood의 값이 없으므로 자동할당 할 수 없게 됩니다. 따라서

이런 결과가 나옵니다.

 


2. byType : setter의 parameterType과 같은 type의 bean이 있으면 자동 할당

현재 여기서 byType을 넣으면 error가 발생하는 것이 정상입니다.

이유는 applicationContext에 Food타입 객체의 값이 2개가 있기 때문인데요(favoriteFood, unFavoriteFood)

이렇게 2개 이상의 값이 있을 때 타입을 따로 지정해준 게 아니기 때문에 컴퓨터에서도 자동으로 어떤 값을 할당해야 할지 모르기 때문에 에러가 발생합니다.

 


3. constructor : 생성자와 같은 이름의 bean이 있으면 자동 할당

현재 MyFood의 생성자는 기본 생성자와 파라미터 2개짜리 생성자가 있다.

그냥 여기서 autowire="constructor"하게되면 값이 잘 나오는 것을 알 수 있는데 이때,

favoriteFood에서 Food를 지우게 되면 favorite와 unFavoriteFood가 되는데 2개 모두 일치하는 생성자가 없으므로 기본생성자가 출력됩니다. (현재는 기본생성자에 값이 없으므로 null이 나온다.)

 


4. default : 생성자에 할당할 수 있는지 확인 후 -> 없으면 setter에서 확인하여 할당
                기본생성자가 있으면 기본생성자 호출!