如何确定我需要使用 @Bean 进行注解。

huangapple 未分类评论56阅读模式
标题翻译

How do I determine if I need to annotate with @Bean

问题

代码部分不要翻译,只返回翻译好的内容:

如何在Spring Integration中确定需要使用 @Bean 注解?

例如,让我们看一个 @Transformer 注解。

考虑以下代码片段:

    @AllArgsConstructor
    @Getter
    @Setter
    @ToString
    private static class Person {
        private String firstName;
        private String lastName;
        private String phone;
    }

    @Override
    public void run(ApplicationArguments args) {
        firstChannel.send(MessageBuilder.withPayload(new Person("s", "f", null)).build());
    }

    // without bean
    @Transformer(inputChannel = FIRST_CHANNEL, outputChannel = SECOND_CHANNEL)
    public ContentEnricher contentEnricher() {
        ContentEnricher contentEnricher = new ContentEnricher();
        contentEnricher.setPropertyExpressions(ImmutableMap.of("phone", new ValueExpression("123")));
        return contentEnricher;
    }

    @ServiceActivator(inputChannel = SECOND_CHANNEL)
    private void fromSecondChannel(Message<?> message) {
        System.out.println(message.getPayload());
    }

以及

    // with bean
    @Bean
    @Transformer(inputChannel = FIRST_CHANNEL, outputChannel = SECOND_CHANNEL)
    public HeaderEnricher headerEnricher() {
        return new HeaderEnricher(ImmutableMap.of("key1", new StaticHeaderValueMessageProcessor<>("value1")));
    }

代码片段2中不使用 @Bean 注解的输出是:

GenericMessage [payload=org.springframework.integration.transformer.HeaderEnricher@15a3b42, headers={id=76d24f2c-8b64-a254-8733-8b5911871cce, timestamp=1590856526985}]

而使用 @Bean 注解的输出是:

GenericMessage [payload=DemoApplication11.Person(firstName=s, lastName=f, phone=null), headers={key1=value1, id=55e5b4b7-9a4b-8822-4398-b42755bc7697, timestamp=1590856617667}]
英文翻译

How do I determine in spring integration, that I need to annotate with @Bean?

For example lets look at a @Transformer annotation.

Consider the following code snippets:

1.

    @AllArgsConstructor
    @Getter
    @Setter
    @ToString
    private static class Person {
        private String firstName;
        private String lastName;
        private String phone;
    }

    @Override
    public void run(ApplicationArguments args) {
        firstChannel.send(MessageBuilder.withPayload(new Person(&quot;s&quot;, &quot;f&quot;, null)).build());
    }

    // without bean
    @Transformer(inputChannel = FIRST_CHANNEL, outputChannel = SECOND_CHANNEL)
    public ContentEnricher contentEnricher() {
        ContentEnricher contentEnricher = new ContentEnricher();
        contentEnricher.setPropertyExpressions(ImmutableMap.of(&quot;phone&quot;, new ValueExpression(&quot;123&quot;)));
        return contentEnricher;
    }

    @ServiceActivator(inputChannel = SECOND_CHANNEL)
    private void fromSecondChannel(Message&lt;?&gt; message) {
        System.out.println(message.getPayload());
    }

and

2.

    // with bean
    @Bean
    @Transformer(inputChannel = FIRST_CHANNEL, outputChannel = SECOND_CHANNEL)
    public HeaderEnricher headerEnricher() {
        return new HeaderEnricher(ImmutableMap.of(&quot;key1&quot;, new StaticHeaderValueMessageProcessor&lt;&gt;(&quot;value1&quot;)));
    }

The output for the code snippet nr 2 without @Bean is :

GenericMessage [payload=org.springframework.integration.transformer.HeaderEnricher@15a3b42, headers={id=76d24f2c-8b64-a254-8733-8b5911871cce, timestamp=1590856526985}]

and with @Bean is :

GenericMessage [payload=DemoApplication11.Person(firstName=s, lastName=f, phone=null), headers={key1=value1, id=55e5b4b7-9a4b-8822-4398-b42755bc7697, timestamp=1590856617667}]

答案1

得分: 0

No @Bean意味着转换器被调用作为一个POJO方法。

@Transformer(...)
public String transform(String in) {
    return in.toUpperCase();
}

如果转换器实际上是Transformer的实现(比如头部增强器),您需要@Bean

ContentEnricher不是一个转换器,它是一个MessageHandler,所以必须用@ServiceActivator@Bean进行注解。

请参阅文档这里

>从4.0版本开始,您可以在@Configuration类中的@Bean方法定义上配置消息注解,以基于bean而不是方法生成消息端点。当@Bean定义是“开箱即用”的MessageHandler实例(AggregatingMessageHandler、DefaultMessageSplitter等),Transformer实例(JsonToObjectTransformer、ClaimCheckOutTransformer等)和MessageSource实例(FileReadingMessageSource、RedisStoreMessageSource等)时,这是非常有用的。以下示例显示了如何在@Bean注解中使用消息注解...

英文翻译

No @Bean means the transformer is called as a POJO method.

@Transformer(...)
public String transform(String in) {
    return in.toUpperCase();
}

If the transformer is actually an implementation of Transformer (such as the header enricher), you need @Bean.

The ContentEnricher is not a transformer, it is a MessageHandler, so it must be annotated with @ServiceActivator and @Bean.

See the documentation and here.

>Starting with version 4.0, you can configure messaging annotations on @Bean method definitions in @Configuration classes, to produce message endpoints based on the beans, not the methods. It is useful when @Bean definitions are “out-of-the-box” MessageHandler instances (AggregatingMessageHandler, DefaultMessageSplitter, and others), Transformer instances (JsonToObjectTransformer, ClaimCheckOutTransformer, and others), and MessageSource instances (FileReadingMessageSource, RedisStoreMessageSource, and others). The following example shows how to use messaging annotations with @Bean annotations ...

答案2

得分: 0

"@Bean" 在一个类上表示上下文依赖注入(CDI)容器将自动创建该类的一个实例,然后使用该实例来解析 "@Autowired" 依赖项。

"@Bean" 在一个函数上表示上下文依赖注入容器将自动调用该函数,并使用该函数返回的对象来解析 "@Autowired" 依赖项。

在大多数情况下,Spring Boot 将自动创建所需的任何配置类的默认实现,然后在需要的任何地方进行自动装配。定义自己的 "@Bean" 函数意味着您可以将该类的定制版本(可以是子类,或者只是具有一些不同参数的相同类的实例)传递给Spring Boot 框架。

我建议您了解一下什么是上下文依赖注入,以及Spring Boot 是如何实现它的。关于何时需要使用 "@Bean",没有通用答案,需要先理解 CDI。

英文翻译

@Bean on a class means the Context Dependency Injection (CDI) container will automatically create an instance of that class and then use that instance to resolve @Autowired dependencies.

@Bean on a function means the Context Dependency Injection container will automatically call that function and use the object returned by that function to resolve @Autowired dependencies.

In most cases, Spring Boot will automatically create a default implementation of any configuration classes it needs, which will then be autowired anywhere it is needed. Defining your own @Bean function means you can pass a customized version of that class (either a subclass, or just an instance of the same class with some different parameters) into the Spring Boot framework.

I recommend you read up on what Context Dependency Injection means, and how Spring Boot actually implements it. There is no general answer to "when do i need @Bean" that doesn't require understanding CDI first.

huangapple
  • 本文由 发表于 2020年5月31日 00:31:37
  • 转载请务必保留本文链接:https://java.coder-hub.com/62105493.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定