标题翻译
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("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());
}
and
2.
// with bean
@Bean
@Transformer(inputChannel = FIRST_CHANNEL, outputChannel = SECOND_CHANNEL)
public HeaderEnricher headerEnricher() {
return new HeaderEnricher(ImmutableMap.of("key1", new StaticHeaderValueMessageProcessor<>("value1")));
}
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.
专注分享java语言的经验与见解,让所有开发者获益!
评论