开发者社区> 问答> 正文

在 Spring 生态中玩转 RocketMQ中春波特还提出了哪两点建议?

在 Spring 生态中玩转 RocketMQ中春波特还提出了哪两点建议?

展开
收起
vncamyi27xznk 2021-11-11 10:29:11 454 0
1 条回答
写回答
取消 提交回答
  • " @Configuration public class ListenerContainerConfiguration implements ApplicationContextAware, SmartI nitializingSingleton { private ObjectMapper objectMapper = new ObjectMapper(); ~~春波特: 性能上考虑,不要 初始化这个成员变量,既然这个成员是在构造/setter 方法里设置的,就不要在这里初始化,尤其是当它的构造成本很高的时候。 private void registerContainer(String beanName, Object bean) { Class<?> clazz = AopUtils.g etTargetClass(bean); if(!RocketMQListener.class.isAssignableFrom(bean.getClass())){ throw new IllegalStateException(clazz + "" is not instance of "" + RocketMQListener.class. getName()); } RocketMQListener rocketMQListener = (RocketMQListener) bean; RocketMQMessageListe ner annotation = clazz.getAnnotation(RocketMQMessageListener.class); validate(annotation); ~~春波特: 下面的这种手工注册 Bean 的方式是 Spring 4.x 里提供能,可以考虑使用 Spring5.0 里提供的 GenericApplicationContext.registerBean 的方法,通过 supplier 调用 ew 来构造 Bean 实例 [3] BeanDefinitionBuilder beanBuilder = BeanDefinitionBuilder.rootBeanDefinition(DefaultRock etMQListenerContainer.class); beanBuilder.addPropertyValue(PROP_NAMESERVER, rocketMQProperties.getNameServer()); ... beanBuilder.setDestroyMethodName(METHOD_DESTROY); String containerBeanName = String.format(""%s_%s"", DefaultRocketMQListenerContainer.c lass.getName(), counter.incrementAndGet()); DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) applicationContext. getBeanFactory(); beanFactory.registerBeanDefinition(containerBeanName, beanBuilder.getBeanDefinition()); DefaultRocketMQListenerContainer container = beanFactory.getBean(containerBeanNam e, DefaultRocketMQListenerContainer.class); ~~春波特: 你这里的启动方法是通过 afterPropertiesS et() 调用的,这个是不建议的,应该实现 SmartLifecycle 来定义启停方法,这样在 ApplicationContex t 刷新时能够自动启动;并且避免了 context 初始化时由于底层资源问题导致的挂住(stuck)的危险 if (!container.isStarted()) { try { container.start(); } catch (Exception e) { n  log.error(""started container failed. {}"", container, e); (e); } } ... } } throw new RuntimeException 注[3]: 使用 GenericApplicationContext.registerBean 的方式 public final < T > void registerBean( Class< T > beanClass, Supplier< T > supplier, BeanDefinitionCustomizer… ustomizers) ""还有,还有"",在罗美琪采纳了春波特的意见比较大地调整了代码之后,春波特哥哥有提出了 Spring Boot 特有的几个要求:  使用 Spring 的 Assert 在传统的 Java 代码中我们使用 assert 进行断言,Spring Boot 中断言需要使用它自有的 Assert 类,如下示例: import org.springframework.util.Assert; ... Assert.hasText(nameServer, ""[rocketmq.name-server] must not be null"");  Auto Configuration 单元测试使用 Spring 2.0 提供的 ApplicationContextRunner public class RocketMQAutoConfigurationTest { private ApplicationContextRunner runner = new ApplicationContextRunner() .withConfi guration(AutoConfigurations.of(RocketMQAutoConfiguration.class)); @Test(expected = NoSuchBeanDefinitionException.class) public voidtestRocketMQAutoCo nfigurationNotCreatedByDefault() { runner.run(context -> context.getBean(RocketMQAutoConfiguration.class)); } @Test public void testDefaultMQProducerWithRelaxPropertyName() { runner.withPropertyValues(""rocketmq.name-server=127.0.0.1:9876"", ""rocketmq.prod ucer.group=spring_rocketmq""). run((context) -> { assertThat(context).hasSingleBean(DefaultMQProducer.class); assertThat(co ntext).hasSingleBean(RocketMQProperties.class); }); }  在 auto-configuration 模块的 pom.xml 文件里,加入 spring-boot-configuration- processor 注解处理器,这样它能够生成辅助元数据文件,加快启动时间。详情见 这里(https://docs.spring.io/spring-boot/docs/current/reference/html/boot-feat ures-developing-auto-configuration.html#boot-features-custom-starter-module -autoconfigure)。

    这本电子书收录开发者藏经阁,下载连接:https://developer.aliyun.com/topic/download?id=1216"

    2021-11-11 18:47:55
    赞同 展开评论 打赏
问答排行榜
最热
最新

相关电子书

更多
云栖社区特邀专家徐雷Java Spring Boot开发实战系列课程(第20讲):经典面试题与阿里等名企内部招聘求职面试技巧 立即下载
微服务架构模式与原理Spring Cloud开发实战 立即下载
阿里特邀专家徐雷Java Spring Boot开发实战系列课程(第18讲):制作Java Docker镜像与推送到DockerHub和阿里云Docker仓库 立即下载