Bean과 @Qualifier

개발새발·2021년 12월 31일
0

spring

목록 보기
1/26
post-custom-banner

Spring 수업을 듣다가 이해를 제대로 못한 부분이 있어 다시 짚어봤다.

  1. 원래 설정파일은 아래와 같았다.
package kr.co.softcampus.main;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;

import kr.co.softcampus.beans.TestBean1;
import kr.co.softcampus.beans.TestBean2;
import kr.co.softcampus.beans.TestBean3;
import kr.co.softcampus.beans.TestBean4;
import kr.co.softcampus.beans.TestBean5;
import kr.co.softcampus.beans.TestBean6;
import kr.co.softcampus.config.BeanConfigClass;

public class MainClass {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		
		AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(BeanConfigClass.class);
		
		TestBean1 obj1 = ctx.getBean("obj1", TestBean1.class);
		TestBean2 obj2 = ctx.getBean("obj2", TestBean2.class);
		
		TestBean3 obj3 = ctx.getBean("obj3", TestBean3.class);
		System.out.printf("obj3.data1 : %s\n", obj3.getData1());
		System.out.printf("obj3.data2 : %s\n", obj3.getData2());
		
		TestBean4 obj4 = ctx.getBean("obj4", TestBean4.class);
		System.out.printf("obj4.data1: %s\n", obj4.getData1());
		System.out.printf("obj4.data2: %s\n", obj4.getData2());
		
		TestBean5 obj5 = ctx.getBean("obj5", TestBean5.class);
		System.out.printf("obj5.data1: %s\n", obj5.getData1());
		System.out.printf("obj5.data2: %s\n", obj5.getData2());
		
		TestBean6 obj6 = ctx.getBean("obj6", TestBean6.class);
		System.out.printf("obj6.data100: %s\n", obj6.getData1());
		System.out.printf("obj6.data200: %s\n", obj6.getData2());
		
		ctx.close();

	}

}
package kr.co.softcampus.config;

import org.springframework.beans.factory.annotation.Autowire;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy;

import kr.co.softcampus.beans.DataBean1;
import kr.co.softcampus.beans.DataBean2;
import kr.co.softcampus.beans.TestBean1;
import kr.co.softcampus.beans.TestBean2;
import kr.co.softcampus.beans.TestBean3;
import kr.co.softcampus.beans.TestBean4;
import kr.co.softcampus.beans.TestBean5;
import kr.co.softcampus.beans.TestBean6;

@Configuration
public class BeanConfigClass {

	@Bean(initMethod="init1", destroyMethod="destroy1")
	@Lazy
	public TestBean1 obj1() {
		return new TestBean1();
	}
	
	@Bean
	@Lazy
	public TestBean2 obj2() {
		return new TestBean2();
	}
	
	@Bean
	public DataBean1 data1() {
		return new DataBean1();
	}
	
	@Bean
	public DataBean2 data2() {
		return new DataBean2();
	}
	
	@Bean(autowire = Autowire.BY_NAME)
	public TestBean3 obj3() {
		return new TestBean3();
	}
	
	@Bean
	public TestBean4 obj4() {
		return new TestBean4();
	}
	
	@Bean
	public TestBean5 obj5() {
		return new TestBean5();
	}
	
	@Bean
	public TestBean6 obj6() {
		return new TestBean6();
	}
}
package kr.co.softcampus.beans;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

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

public class TestBean4 {
	
	@Autowired
	@Qualifier("data1")
	private DataBean1 data1;
	
	@Autowired
	@Qualifier("data2")
	private DataBean2 data2;

	public DataBean1 getData1() {
		return data1;
	}

	public DataBean2 getData2() {
		return data2;
	}
	
}
package kr.co.softcampus.beans;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

public class TestBean3 {
	
	private DataBean1 data1;
	private DataBean2 data2;
	
	public DataBean1 getData1() {
		return data1;
	}
	public void setData1(DataBean1 data1) {
		this.data1 = data1;
	}
	public DataBean2 getData2() {
		return data2;
	}
	public void setData2(DataBean2 data2) {
		this.data2 = data2;
	}

}

2.TestBean4 클래스에서 DataBean2DataBean1 으로 바꿔같서 은 DataBean1 을 갖지만, @Qualifier 로 다른 이름으로 주고 싶어서 아래처럼 수정했다.

package kr.co.softcampus.config;

import org.springframework.beans.factory.annotation.Autowire;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy;

import kr.co.softcampus.beans.DataBean1;
import kr.co.softcampus.beans.DataBean2;
import kr.co.softcampus.beans.TestBean1;
import kr.co.softcampus.beans.TestBean2;
import kr.co.softcampus.beans.TestBean3;
import kr.co.softcampus.beans.TestBean4;
import kr.co.softcampus.beans.TestBean5;
import kr.co.softcampus.beans.TestBean6;

@Configuration
public class BeanConfigClass {

	@Bean(initMethod="init1", destroyMethod="destroy1")
	@Lazy
	public TestBean1 obj1() {
		return new TestBean1();
	}
	
	@Bean
	@Lazy
	public TestBean2 obj2() {
		return new TestBean2();
	}
	
	@Bean
	public DataBean1 data1() {
		return new DataBean1();
	}
	
	@Bean
	public DataBean1 data2() {
		return new DataBean1();
	}
	
	@Bean(autowire = Autowire.BY_NAME)
	public TestBean3 obj3() {
		return new TestBean3();
	}
	
	@Bean
	public TestBean4 obj4() {
		return new TestBean4();
	}
	
	@Bean
	public TestBean5 obj5() {
		return new TestBean5();
	}
	
	@Bean
	public TestBean6 obj6() {
		return new TestBean6();
	}
}
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;

public class TestBean4 {
	
	@Autowired
	@Qualifier("data1")
	private DataBean1 data1;
	
	@Autowired
	@Qualifier("data2")
	private DataBean2 data2;

	public DataBean1 getData1() {
		return data1;
	}

	public DataBean1 getData2() {
		return data2;
	}
	
}

  1. 그랬더니 아래와 같은 오류가 났다.. ㅎ 대충보니 obj3 의 클래스인 TestBean3data2 property 를 가져오는데 문제가 있다는 얘기였는데... 이때 난 TestBean4 만 건들였는데 왜 TestBean3 에서 문제가 일어나지 라는 생각뿐이였다. 그런데 알고보니... 내가 그냥 수업을 제대로 안 듣고 있었다는 말씀 ^^

🚫 Exception in thread "main"org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'obj3' defined in kr.co.softcampus.config.BeanConfigClass: Initialization of bean failed; nested exception is org.springframework.beans.ConversionNotSupportedException: Failed to convert property value of type 'kr.co.softcampus.beans.DataBean1' to required type 'kr.co.softcampus.beans.DataBean2' for property 'data2'; nested exception is java.lang.IllegalStateException: Cannot convert value of type 'kr.co.softcampus.beans.DataBean1' to required type 'kr.co.softcampus.beans.DataBean2' for property 'data2': no matching editors or conversion strategy found


  1. 수정된 아래 BeanConfigClass 에서 data2 메소드도 DataBean1 클래스를 리턴하도록 해뒀는데, 이 메소드를 모든 클래스에서 공유해서 사용하고 있었던 것이다. 그치.. BeanConfigClassBean.xml 같은 아이니까... 즉, 다른 obj 클래스들도 data2 라는 property가 있다면 모두 DataBean1 타입으로 수정을 해줘야한다.
package kr.co.softcampus.config;

import org.springframework.beans.factory.annotation.Autowire;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy;

import kr.co.softcampus.beans.DataBean1;
import kr.co.softcampus.beans.DataBean2;
import kr.co.softcampus.beans.TestBean1;
import kr.co.softcampus.beans.TestBean2;
import kr.co.softcampus.beans.TestBean3;
import kr.co.softcampus.beans.TestBean4;
import kr.co.softcampus.beans.TestBean5;
import kr.co.softcampus.beans.TestBean6;

@Configuration
public class BeanConfigClass {

	@Bean(initMethod="init1", destroyMethod="destroy1")
	@Lazy
	public TestBean1 obj1() {
		return new TestBean1();
	}
	
	@Bean
	@Lazy
	public TestBean2 obj2() {
		return new TestBean2();
	}
	
	@Bean
	public DataBean1 data1() {
		return new DataBean1();
	}
	
  // 이 부분을 수정함
	@Bean
	public DataBean1 data2() {
		return new DataBean1();
	}
	
	@Bean(autowire = Autowire.BY_NAME)
	public TestBean3 obj3() {
		return new TestBean3();
	}
	
	@Bean
	public TestBean4 obj4() {
		return new TestBean4();
	}
	
	@Bean
	public TestBean5 obj5() {
		return new TestBean5();
	}
	
	@Bean
	public TestBean6 obj6() {
		return new TestBean6();
	}
}
profile
발새발개
post-custom-banner

0개의 댓글