业务背景
需要不同的环境,有不同的实现。不单单是配置的变化。
一个环境
使用新的 rocket mq
原来环境
使用旧的 active mq
限制
使用同一份代码
解决问题的思路
spring 懒加载
因为消息的监听是基于 Container 监听者模式实现的,希望通过指定为特定环境指定为是否惰性加载。
后来发现行不通。
因为一般的 property 配置框架,都是监听的 spring 的属性设置事件。
lazy-init 是一个无法被替换的属性。
这个基本不可实现。
最简单粗暴的方式
同时也是最麻烦的方式。
为了让代码正常启动且不监听,就直接让两份 container 都正常初始化即可。
可以在不同环境配置不同的属性,让其兼容不存在的队列(Topic/Tag)等即可。
为了避免复杂性,建议使用这种方式。
修改 bean
直接在对象构建结束后,构建一个空的 container。
例子
对象
package com.github.houbb.spring.learn.life.model;
import lombok.Data;
/**
* @author binbin.hou
* @since 1.0.0
*/
@Data
public class User {
private String name;
}
定义对象处理
package com.github.houbb.spring.learn.life.awre;
import com.github.houbb.spring.learn.life.model.User;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.BeanPostProcessor;
/**
* @author binbin.hou
* @since 1.0.0
* @see BeanFactoryPostProcessor
* @see BeanPostProcessor
*/
public class MyBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return null;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
// 直接返回 null 是无效的
if("user".equals(beanName)) {
User user = new User();
user.setName("Process");
return user;
}
return null;
}
}
bean.xml
配置信息如下
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="user" class="com.github.houbb.spring.learn.life.model.User">
<property name="name" value="哈哈哈"/>
</bean>
<bean id="myBeanPostProcessor" class="com.github.houbb.spring.learn.life.awre.MyBeanPostProcessor">
</bean>
</beans>
测试代码
@Test
public void userTest() {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean.xml");
User user = applicationContext.getBean(User.class);
System.out.println(user);
}
- 测试结果
User(name=Process)
参考资料
- 官方
- 其他