diff --git a/hzims-biz-common/src/main/java/com/hnac/hzims/common/config/RedisMessageConfig.java b/hzims-biz-common/src/main/java/com/hnac/hzims/common/config/RedisMessageConfig.java new file mode 100644 index 0000000..50055b4 --- /dev/null +++ b/hzims-biz-common/src/main/java/com/hnac/hzims/common/config/RedisMessageConfig.java @@ -0,0 +1,75 @@ +package com.hnac.hzims.common.config; + +import com.google.common.collect.Lists; +import lombok.AllArgsConstructor; +import lombok.RequiredArgsConstructor; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.ApplicationArguments; +import org.springframework.boot.ApplicationRunner; +import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.support.GenericApplicationContext; +import org.springframework.core.annotation.AnnotationUtils; +import org.springframework.data.redis.connection.RedisConnectionFactory; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.data.redis.listener.PatternTopic; +import org.springframework.data.redis.listener.RedisMessageListenerContainer; +import org.springframework.data.redis.listener.adapter.MessageListenerAdapter; +import org.springframework.stereotype.Component; +import org.springframework.util.ReflectionUtils; + +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Objects; +import java.util.concurrent.atomic.AtomicLong; + +/** + * @author hx + * @version 1.0 + * @date 2023/3/12 15:27 + */ + +@Component +public class RedisMessageConfig implements ApplicationRunner { + + /**AtomicLong 可以理解为加了synchronized的long类型**/ + private AtomicLong counter = new AtomicLong(0); + + @Autowired + private ApplicationContext context; + + @Bean + RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory) { + RedisMessageListenerContainer container = new RedisMessageListenerContainer(); + container.setConnectionFactory(connectionFactory); + return container; + } + + + @Override + public void run(ApplicationArguments args) throws Exception { + // 获取Redis的消息监听容器 + RedisMessageListenerContainer container = context.getBean(RedisMessageListenerContainer.class); + + // 扫描注册所有的 @RedisMessageListener 的方法,添加到容器中 + for (String beanName : context.getBeanNamesForType(Object.class)) { + ReflectionUtils.doWithMethods(Objects.requireNonNull(context.getType(beanName)), + method -> { + ReflectionUtils.makeAccessible(method); + Object target = context.getBean(beanName); + RedisMessageListener annotation = AnnotationUtils.findAnnotation(method, RedisMessageListener.class); + MessageListenerAdapter adapter = registerBean((GenericApplicationContext) context, target, method); + container.addMessageListener(adapter, new PatternTopic(annotation.topic())); + }, + method -> !method.isSynthetic() && method.getParameterTypes().length == 1 + && AnnotationUtils.findAnnotation(method, RedisMessageListener.class) != null); + } + } + + private MessageListenerAdapter registerBean(GenericApplicationContext context, Object target, Method method) { + String containerBeanName = String.format("%s_%s", MessageListenerAdapter.class.getName(), counter.incrementAndGet()); + context.registerBean(containerBeanName, MessageListenerAdapter.class, () -> new MessageListenerAdapter(target, method.getName())); + return context.getBean(containerBeanName, MessageListenerAdapter.class); + } +} diff --git a/hzims-biz-common/src/main/java/com/hnac/hzims/common/config/RedisMessageListener.java b/hzims-biz-common/src/main/java/com/hnac/hzims/common/config/RedisMessageListener.java new file mode 100644 index 0000000..775fc57 --- /dev/null +++ b/hzims-biz-common/src/main/java/com/hnac/hzims/common/config/RedisMessageListener.java @@ -0,0 +1,16 @@ +package com.hnac.hzims.common.config; + +import java.lang.annotation.*; + +/** + * @author hx + * @version 1.0 + * @date 2023/3/12 17:01 + */ +@Target({ElementType.METHOD}) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface RedisMessageListener { + /**事件主题**/ + String topic(); +}