为什么调用bean方法而不是autowire?

z3yyvxxp  于 2021-07-23  发布在  Java
关注(0)|答案(1)|浏览(252)

我在关于springkafkabean声明的教程和github项目中看到过这种模式,我不明白为什么直接调用bean方法而不是autowire,
例如,
在https://www.baeldung.com/spring-kafka 第4节:

@Configuration 
public class KafkaProducerConfig {

@Bean
public ProducerFactory<String, String> producerFactory() {
    Map<String, Object> configProps = new HashMap<>();
    configProps.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapAddress);
    configProps.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class);
    configProps.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, StringSerializer.class);
    return new DefaultKafkaProducerFactory<>(configProps);
}

@Bean
public KafkaTemplate<String, String> kafkaTemplate() {
    return new KafkaTemplate<>(producerFactory());
}
}

为什么要调用方法producerfactory?
这样申报不是更好吗?

@Configuration 
public class KafkaProducerConfig {

@Bean
public ProducerFactory<String, String> producerFactory() {
    Map<String, Object> configProps = new HashMap<>();
    configProps.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapAddress);
    configProps.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class);
    configProps.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, StringSerializer.class);
    return new DefaultKafkaProducerFactory<>(configProps);
}

@Bean
public KafkaTemplate<String, String> kafkaTemplate(ProducerFactory<String, String> producerFactory) {
    return new KafkaTemplate<>(producerFactory);
}
}

似乎创建了两个defaultkafkaproducerfactory示例,而不是一个。我错过了什么?

hvvq6cgz

hvvq6cgz1#

不,没有创建该对象的两个示例,因为 producerFactory() 由代理 BeanFactory 正是为了这个案子。
尽管我同意注入式变体更适合现代方法,尤其是当我们在启动时追求性能提升时。
看到了吗 @Configuration.proxyBeanMethods Java文档:

/**
 * Specify whether {@code @Bean} methods should get proxied in order to enforce
 * bean lifecycle behavior, e.g. to return shared singleton bean instances even
 * in case of direct {@code @Bean} method calls in user code. This feature
 * requires method interception, implemented through a runtime-generated CGLIB
 * subclass which comes with limitations such as the configuration class and
 * its methods not being allowed to declare {@code final}.
 * <p>The default is {@code true}, allowing for 'inter-bean references' via direct
 * method calls within the configuration class as well as for external calls to
 * this configuration's {@code @Bean} methods, e.g. from another configuration class.
 * If this is not needed since each of this particular configuration's {@code @Bean}
 * methods is self-contained and designed as a plain factory method for container use,
 * switch this flag to {@code false} in order to avoid CGLIB subclass processing.
 * <p>Turning off bean method interception effectively processes {@code @Bean}
 * methods individually like when declared on non-{@code @Configuration} classes,
 * a.k.a. "@Bean Lite Mode" (see {@link Bean @Bean's javadoc}). It is therefore
 * behaviorally equivalent to removing the {@code @Configuration} stereotype.
 * @since 5.2
 */
boolean proxyBeanMethods() default true;

相关问题