Spring注解-@Configuration调用spring bean自动构建

2024-04-04

如果我使用 @Bean 声明一个类,然后对该类进行组件扫描,spring 将通过调用它的构造函数并注入构造函数参数并注入任何标记有 @Inject 的字段来实例化该类。为了简单起见,我们将这个 Spring 自动构建称为 Spring 自动构建。

我不喜欢组件扫描并希望完全避免它(我不想讨论我不喜欢它的原因)。我想改用 @Configuration 对象,但仍然希望拥有可用的自动构建功能。是否可以调用 spring 自动构建我的对象,而不是显式地传递 @Configuration 对象中的所有构造函数参数?

假设我有一个豆子:

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

我可以像这样定义一个配置对象:

@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 构造函数,因此当我的构造函数随着时间的推移而发生变化时,我必须不断更新它。

我希望我可以声明一个抽象方法,以便可以进行 Spring 自动构建:

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

但这行不通。有没有一种方法可以调用 spring 自动构建without使用组件扫描?

在 Google Guice 中,这可以通过 Binder 完成:https://google-guice.googlecode.com/svn/trunk/javadoc/com/google/inject/Binder.html https://google-guice.googlecode.com/svn/trunk/javadoc/com/google/inject/Binder.html

在 Tapestry IOC 中,这可以通过 ServiceBinder 完成:http://tapestry.apache.org/ioc-cookbook-basic-services-and-injection.html#IoCCookbook-BasicServicesandInjection-SimpleServices http://tapestry.apache.org/ioc-cookbook-basic-services-and-injection.html#IoCCookbook-BasicServicesandInjection-SimpleServices

Update

根据spod的回答,我能够实现我所追求的目标(谢谢!)。为任何想要做同样事情的人提供测试用例:

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());
    }
}

基于 java 的容器配置不依赖于以任何方式进行组件扫描。它只是基于 XML 的组件配置的不同方法。使用 XML 配置,您只需使用 MyServiceImpl 类声明您的 bean,以防它已经带有 @inject 注释。 Spring 会识别注释并处理它们。如果您确实想从 @Configuration java 类实例化 MyServiceImpl 而不自己调用构造函数,那么您必须使用 bean 工厂(尚未测试它,只需尝试一下):

@Configuration
public class MyConfiguration {

    @Autowired AutowireCapableBeanFactory beanFactory;

    @Bean public MyService myService() { 
        return beanFactory.createBean(MyServiceImpl.class, AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR, true);
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Spring注解-@Configuration调用spring bean自动构建 的相关文章

随机推荐