@Configuration@Bean 어노테이션을 이용해서 스프링 컨테이너에 새로운 빈 객체를 제공할 수 있음

 

 

 

 

MyHome01.java

package vo;

public class MyHome01 implements MyHome {
 private String className = "MyHome01";
 private char checkYn = 'N';
 
 @Override
 public void myHomeInfo(){
  System.out.println(className + ", " + checkYn);
 }
}

 

MyHome02.java

package vo;

public class MyHome02 implements MyHome{
 private String className = "MyHome02";
 private char checkYn = 'Y';
 
 @Override
 public void myHomeInfo(){
  System.out.println(className + ", " + checkYn);
 }
}

 

SpringConfig.java

package config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import vo.MyHome01;
import vo.MyHome02;

 

@Configuration
public class SpringConfig {

 

 @Bean
 public MyHome01 myHome01(){
  return new MyHome01();
 }
 
 @Bean(name="myhome")
 public MyHome02 myHome02(){
  return new MyHome02();
 }
}

@Bean
public MyHome01 myHome01(){
return new MyHome01();
}

이 부분의 XML의 다음과 설정이 같다.

<bean id="myHome01" class="vo.MyHome01"/>

즉, @Bean이 적용된 메서드의 이름을 빈의 식별값으로 사용

만약 메서드의 이름이 아닌 다른 이름으로 빈 객체의 이름을 사용하고 싶다면 @Bean 어노테이션의 name 속성을 사용

 

AbstractServiceImpl.java

package service;

import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

 

@Component("service01")
@Scope("prototype")
public class AbstractServiceImpl implements AbstractService {
 private String name = "111";
 
 @Override
 public String getClassName() {
  // TODO Auto-generated method stub
  return "AbstractServiceImpl-" + name;
 }

}

 

AbstractServiceImpl02.java

package service;

import org.springframework.stereotype.Component;

 

@Component("service02")
public class AbstractServiceImpl02 implements AbstractService {
 private String name = "222";
 
 @Override
 public String getClassName() {
  // TODO Auto-generated method stub
  return "AbstractServiceImpl-" + name;
 }

}

 

AbstractController.java

package controller;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.ModelAndView;

import service.AbstractService;
import vo.MyHome;
import vo.MyHome01;

 

@Component
public class AbstractController extends
  org.springframework.web.servlet.mvc.AbstractController {

 

 @Resource(name="service01")
 private AbstractService service;
 
 @Resource(name="myhome")
 private MyHome myHome;
 
 @Override
 protected ModelAndView handleRequestInternal(HttpServletRequest arg0,
   HttpServletResponse arg1) throws Exception {
  // TODO Auto-generated method stub
  
  System.out.println("START >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
  System.out.println(service.getClassName());
  System.out.println("END >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
  
  myHome.myHomeInfo();
  
  return null;
 }
}

 

spring301-servlet.xml 

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:context="http://www.springframework.org/schema/context"
 xmlns:p="http://www.springframework.org/schema/p"
 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-3.0.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context-3.0.xsd">

 <context:annotation-config/>
 
 <context:component-scan base-package="controller"/>
 <context:component-scan base-package="service"/>
 <context:component-scan base-package="config"/>

 
 <!-- HandlerMapping 설정 -->
 <bean id="simpleUrlHandlerMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
  <property name="mappings">
   <props>
    <prop key="/abstract.sp">abstractController</prop>
   </props>
  </property>
 </bean>

 
 <!-- 각종 bean 설정 -->
 <!-- bean id="springConfig" class="config.SpringConfig"></bean -->
 
</beans>

@Configuration 어노테이션이 적용된 클래스는 @Component 어노테이션이 적용된 클래스와 마찬가지로 컴포넌트 스캔 대상이므로 스캔범위만 지정해주면 따로 빈을 등록할 필요가 없어짐 

<context:component-scan base-package="config"/>

 

<!-- bean id="springConfig" class="config.SpringConfig"></bean -->

//컴포넌트 스캔을 사용하지 않는다면 직접 빈을 등록해 줘야 함(위 코드에서 주석 삭제)

 

 

결과 

START >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
AbstractServiceImpl-111
END >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
MyHome02, Y

 

 

 

중요

@Configuration 어노테이션을 적용한다고 해서 스프링 컨테이너가 해당 클래스로부터 빈 정보를 구할 수 있는 것은 아님 =>

XML 설정 파일에 @Configuration 클래스를 사용하려면 ConfigurationClassPostProcessor 클래스와 @Configuration 어노테이션이 적용된 클래스를 스프링 설정 파일에 빈 객체로 등록해야 함

 

적용 방법은 다음과 같음

<bean class="org.springframework.context.annotation.ConfigurationClassPostProcessor"/>

<bean id="springConfig" class="config.SpringConfig"/> 

ConfigurationClassPostProcessor 클래스는 @Configuration 어노테이션이 적용된 빈 객체에서 @Bean 어노테이션이 적용된 메서드로부터 빈 객체를 가져와 스프링 컨테이너에 등록

 

<context:annotation-config/> 태그를 사용하면 ConfigurationClassPostProcessor를 등록하지 않아도 됨

 

@Configuration 어노테이션이 적용된 클래스로부터 생성한 빈 객체들도 다른 빈과 동일하게 @Required, @Autowired, @Resource 어노테이션을 이용해서 의존관계를 설정할 수 있음

 

 

 

[참고자료] Spring 3.0 프로그래밍 - 최범균

+ Recent posts