You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

自定义PublisherMetadataSource实现:基于@Publisher传递操作类型头信息

自定义PublisherMetadataSource实现方法名驱动的消息头操作类型传递

嘿,刚好做过类似的实现,咱们通过自定义PublisherMetadataSource结合方法名命名约定,就能轻松给@Publisher注解的方法添加操作类型消息头。下面是具体步骤:

1. 核心原理理解

org.springframework.integration.aop.PublisherMetadataSource的作用是为被@Publisher标记的方法生成消息元数据(包括消息头)。我们只需要继承它的抽象实现AbstractPublisherMetadataSource,重写getHeaders方法,就能根据方法名的命名规则自动注入操作类型。

2. 自定义PublisherMetadataSource实现类

创建一个基于方法名判断操作类型的元数据源:

import org.springframework.integration.aop.AbstractPublisherMetadataSource;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

public class MethodNameBasedPublisherMetadataSource extends AbstractPublisherMetadataSource {

    // 定义消息头的key
    private static final String OPERATION_TYPE_HEADER = "OPERATION_TYPE";

    @Override
    protected Map<String, Object> getHeaders(Method method, Object[] args, Object result) {
        Map<String, Object> headers = new HashMap<>();
        String methodName = method.getName().toLowerCase();

        // 根据方法名前缀判断操作类型
        if (methodName.startsWith("create")) {
            headers.put(OPERATION_TYPE_HEADER, "CREATED");
        } else if (methodName.startsWith("update")) {
            headers.put(OPERATION_TYPE_HEADER, "UPDATED");
        } else if (methodName.startsWith("delete")) {
            headers.put(OPERATION_TYPE_HEADER, "DELETED");
        }
        // 可选:给不符合约定的方法添加默认值或者跳过
        // else {
        //     headers.put(OPERATION_TYPE_HEADER, "UNKNOWN");
        // }
        return headers;
    }
}

3. 配置Spring容器,关联自定义元数据源

需要把自定义的元数据源注册为Bean,并绑定到AnnotationPublisherAdvisor(@Publisher注解的切面处理器):

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.integration.aop.AnnotationPublisherAdvisor;
import org.springframework.integration.aop.PublisherMetadataSource;

@Configuration
public class IntegrationAopConfig {

    @Bean
    public PublisherMetadataSource customPublisherMetadataSource() {
        return new MethodNameBasedPublisherMetadataSource();
    }

    @Bean
    public AnnotationPublisherAdvisor publisherAdvisor(PublisherMetadataSource customPublisherMetadataSource) {
        AnnotationPublisherAdvisor advisor = new AnnotationPublisherAdvisor();
        advisor.setMetadataSource(customPublisherMetadataSource);
        // 可选:指定切面生效的范围,比如只扫描业务服务包
        // advisor.setPointcut(new AspectJExpressionPointcut("execution(* com.yourcompany.service..*(..))"));
        return advisor;
    }

    // 别忘了定义@Publisher中用到的消息通道
    @Bean
    public MessageChannel businessEventChannel() {
        return new org.springframework.integration.channel.DirectChannel();
    }
}

4. 在业务方法中使用@Publisher注解

按照命名约定编写方法,注解会自动触发消息头注入:

import org.springframework.integration.annotation.Publisher;
import org.springframework.stereotype.Service;

@Service
public class UserService {

    @Publisher(channel = "businessEventChannel")
    public User createUser(User user) {
        // 业务逻辑:创建用户并返回
        return savedUser;
    }

    @Publisher(channel = "businessEventChannel")
    public User updateUser(User user) {
        // 业务逻辑:更新用户并返回
        return updatedUser;
    }

    @Publisher(channel = "businessEventChannel")
    public void deleteUser(Long userId) {
        // 业务逻辑:删除用户(无返回值也不影响消息头注入)
    }
}

额外优化建议

  • 可以用正则表达式替代前缀判断,支持更灵活的方法名规则(比如createUser/userCreate都匹配CREATED)
  • 可以把操作类型定义为枚举类,避免硬编码字符串
  • 如果需要根据方法参数或返回值内容调整消息头,也可以在getHeaders方法中扩展逻辑

内容的提问来源于stack exchange,提问作者Rinat Sharipov

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 10:09:13