[Spring] Configuration by Annotation in Java

어노테이션을 이용한 Bean 작업

Spring에서는 xml에서 세팅했던 작업을 Java 코드 내에서 작업할 수 있도록 지원한다. Java 코드 내에서 작업하면 주입할 정보를 외부 네트워크에서 받아오거나 유연한 계산 값을 이용할 수 있는 장점이 있다. 코드는 다음과 같이 어노테이션을 이용하며 기존에 xml 에서 사용하던 태그들을 그대로 사용할 수 있다.

@Bean

  • @Bean 어노테이션은 bean 객체를 정의할 때 사용한다
  • 메서드 이름이 bean 이름이 된다
  • @Bean(name=이름) : bean 이름을 새롭게 정의한다
  • @Lazy : lazy-init 여부 지정
  • @Scope : bean socpe 설정
  • @Primary : primary 속성 지정 (동일한 클래스 타입 빈이 여러 개일 때, 한 가지를 결정)

아래에는 정리했던 어노테이션을 적용한 예시 코드다. Bean 생성할 때 사용하는 다양한 옵션들이 직관적으로 보여진다.

package com.springpractice.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy;
import org.springframework.context.annotation.Primary;
import org.springframework.context.annotation.Scope;

import com.springpractice.beans.TestBean1;

@Configuration
public class BeanConfigClass {
	
	@Lazy
	@Scope("prototype")
	@Bean(name="tb1")
	public TestBean1 java1() {
		TestBean1 t1 = new TestBean1();
		return t1;
	}
	
	@Primary
	@Bean
	public TestBean1 java2() {
		TestBean1 t1 = new TestBean1();
		return t1;
	}
}

init, destroy 메서드

빈 생명주기에 따른 init-methoddestroy-method 활용 역시 가능하다. 전달할 클래스 내부에 init methoddestroy method 둘을 정의하고 @Bean 내부에 쉼표로 구분하여 아래와 같이 적어준다. 이후 MainClass를 실행해보면 빈 객체 생성과 종료시 각각 호출되는 메서드를 확인할 수 있다.

package com.springpractice.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy;
import org.springframework.context.annotation.Primary;
import org.springframework.context.annotation.Scope;

import com.springpractice.beans.TestBean1;

@Configuration
public class BeanConfigClass {
	
	@Lazy
	@Scope("prototype")
	@Bean(name="tb1", initMethod="init", destroyMethod="destroy")
	public TestBean1 java1() {
		TestBean1 t1 = new TestBean1();
		return t1;
	}
	
	@Primary
	@Bean(initMethod="init", destroyMethod="destroy")
	public TestBean1 java2() {
		TestBean1 t1 = new TestBean1();
		return t1;
	}
}

Auto DI (Dependency Injection)

자동 주입 역시 가능하다. 오히려 Java 코드 내에서 생성자와 Setter를 다루기 때문에 더 익숙하게 느껴질 수 있다. 아래와 같이 Autowire.BY_NAME 또는 Autowire.BY_TYPE 을 사용하면 자동 주입 방법을 설정할 수 있다. 다만 해당 방법은 Spring 3.5버전 이후에는 권장되지 않는 방법이어서 Deprecated 되는 것을 볼 수 있다.

/*import ...*/

@Configuration
public class BeanConfigClass {
	
	@Bean(name="tb1")
	public TestBean1 bean1() {
		return new TestBean1(200, "생성자 이용한 주입", new DataBean1());
	}
	
	@Bean(name="tb2")
	public TestBean1 bean2() {
		TestBean1 tb2 = new TestBean1();
		tb2.setData1(120);
		tb2.setData2("Setter 이용한 주입");
		tb2.setData3(new DataBean1());
		return tb2;
	}
	
	@Bean(name="tb3", autowire=Autowire.BY_NAME)
	public TestBean2 bean3() {
		return new TestBean2();
	}
	
	// For AutoWire Test
	@Bean
	public DataBean2 data1() { return new DataBean2(); }
	@Bean
	public DataBean2 data2() { return new DataBean2(); }
}

이렇게 정의한 Bean은 아래와 같이 MainClass 코드에서 사용할 수 있다.

package com.springpractice.main;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;

import com.springpractice.beans.TestBean1;
import com.springpractice.beans.TestBean2;
import com.springpractice.config.BeanConfigClass;

public class MainClass {
	public static void main(String[] args) {
		AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(BeanConfigClass.class);
		
		TestBean1 tb1 = ctx.getBean("tb1", TestBean1.class);
		System.out.println(tb1);
		System.out.println(tb1.getData1());
		System.out.println(tb1.getData2());
		System.out.println(tb1.getData3());
		
		System.out.println("-------------------------------------");
		
		TestBean1 tb2 = ctx.getBean("tb2", TestBean1.class);
		System.out.println(tb2.getData1());
		System.out.println(tb2.getData2());
		System.out.println(tb2.getData3());
		
		System.out.println("-------------------------------------");
		
		TestBean2 tb3 = ctx.getBean("tb3", TestBean2.class);
		System.out.println(tb3.getData1());
		System.out.println(tb3.getData2());
		
		ctx.close();
	}
}

Updated:

Leave a comment