2012-11-27 2 views
4

@Bean을 사용하여 클래스를 선언 한 다음 클래스에 대한 컴포넌트 스캔을 수행하면 스프링은 생성자를 호출하고 생성자 args를 삽입하고로 표시된 클래스를 삽입하여 클래스를 인스턴스화합니다. @ 주입. 간단하게하기 위해이 봄철 자동 건물을 호출 할 수 있습니다.스프링 애노테이션 - @ 콩팥 자동 빌드를 호출하는 @Configuration

나는 구성 요소 검사를 싫어하고 그것을 완전히 피하고자한다. (나는 그것을 좋아하지 않는 이유에 대해 토론하고 싶지 않다.) 대신 @Configuration 객체를 사용하고 싶지만 여전히 자동 빌드 기능을 사용할 수 있어야합니다. 명시 적으로 모든 @Configuration 객체에 모든 생성자 인수를 전달하지 않고 Spring에서 자동으로 객체를 빌드 할 수 있습니까?

@Configuration 
public class MyConfiguration { 
    // lets assume d1 and d2 are defined in another @Configuration 
    @Inject 
    Dependency1 d1; 

    @Inject 
    Dependency2 d2; 

    @Bean 
    public MyService myService() { 
     // I dislike how I have to explicitly call the constructor here 
     return new MyServiceImpl(d1, d2); 
    } 
} 

을하지만 지금은 내가 명시 적으로 MyServiceImpl 내가 나 자신을 너무 생성자를 호출 할 수 있었다 :

public class MyServiceImpl implements MyService { 
    public MyServiceImpl(Dependency1 d1, Dependency d2) { ... } 
    .... 
} 

내가 같이 구성 객체를 정의 할 수 있습니다 :

내가 콩이 있다고 가정하자 시간이 지남에 따라 생성자가 변경됨에 따라이를 계속 업데이트해야합니다.

@Configuration 
public abstract class MyConfiguration { 
    @Bean 
    public abstract MyServiceImpl myService(); 
} 

을하지만이 작동하지 않습니다

나는 봄 자동 건물이 일어날 수 있도록 내가 추상 메소드를 선언 할 수 있다고 기대했다. 구성 요소 검사를 사용하여없이 봄철 자동 빌드 을 호출 할 수있는 방법이 있습니까?

구글 Guice에서

,이는 바인더를 통해 수행 할 수 있습니다 http://tapestry.apache.org/ioc-cookbook-basic-services-and-injection.html#IoCCookbook-BasicServicesandInjection-SimpleServices

업데이트

spod의 기준 자료 : 태피스트리 IOC에서 https://google-guice.googlecode.com/svn/trunk/javadoc/com/google/inject/Binder.html

, 이것은 ServiceBinder를 통해 수행 할 수 있습니다 대답, 나는 내가 무엇을했는지 달성 할 수 있었다 (감사합니다!).

import java.util.Date; 
import javax.inject.Inject; 
import junit.framework.Assert; 
import org.junit.Test; 
import org.springframework.beans.factory.config.AutowireCapableBeanFactory; 
import org.springframework.context.ApplicationContext; 
import org.springframework.context.annotation.AnnotationConfigApplicationContext; 
import org.springframework.context.annotation.Bean; 
import org.springframework.context.annotation.Configuration; 

public class AutoBuildConfigurationTest { 
    @Configuration 
    public static class MyConfiguration { 
     @Inject 
     private AutowireCapableBeanFactory beanFactory; 

     @Bean 
     public Date date() { 
      return new Date(12345); 
     } 

     @Bean 
     public MyService myService() { 
      return autoBuild(MyService.class); 
     } 

     protected <T> T autoBuild(Class<T> type) { 
      return type.cast(beanFactory.createBean(type, AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR, true)); 
     } 
    } 

    public static class MyService { 
     private Date date; 

     public MyService(Date date) { 
      this.date = date; 
     } 

     public Date getDate() { 
      return date; 
     } 
    } 

    @Test 
    public void testAutoBuild() { 
     ApplicationContext appContext = new AnnotationConfigApplicationContext(MyConfiguration.class); 
     MyService myService = appContext.getBean(MyService.class); 
     Assert.assertEquals(12345, myService.getDate().getTime()); 
    } 
} 

답변

7

Java 기반 컨테이너 구성은 어떤 방식 으로든 구성 요소 검색을 수행하지 않는다는 것을 전제로합니다. XML 기반 컴포넌트 구성을위한 단지 다른 접근 방식. XML 구성을 사용하면 이미 @inject 주석이 달린 경우를 대비하여 MyServiceImpl 클래스로 bean을 선언하면됩니다. Spring은 주석을 인식하고 주석을 처리합니다.

@Configuration 
public class MyConfiguration { 

    @Autowired AutowireCapableBeanFactory beanFactory; 

    @Bean public MyService myService() { 
     return beanFactory.createBean(MyServiceImpl.class, AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR, true); 
    } 
} 
+0

I : 당신이 정말로 자신을 생성자를 호출하지 않고 @Configuration 자바 클래스 MyServiceImpl을 실체화하고 싶은 경우에, 당신은 빈 공장의 사용을 (havent 한 그냥 한번 시도해, 그것을 테스트) 만들어야 할 것 주석 설정에 구성 요소 검사가 필요하지 않지만 구성 요소 검사에서 사용하는 자동 빌드 기능을 원했습니다. 귀하의 답변으로 인해 자동 빌드를 담당하는 코드 조각으로 안내하게되었습니다. 감사! –