spring原始碼閱讀-使用例子
阿新 • • 發佈:2020-10-26
說明
這裡定義在原始碼中看到的各個介面使用例子
BeanFactoryPostProcessor
1.在bean建立載入為beanDefinition之後 初始化之前執行,我們可以通過改變beanDefinition或者動態注入
/** * @author liqiang * @date 2020/10/23 17:53 * @Description: (what)實現動態註冊Car 可以通過配置XML或者註解 注入到Spring * (why) * (how) */ public class AutoConfigBeanFactoryPostProcessor implements BeanFactoryPostProcessor { @Overridepublic void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { RootBeanDefinition beanDefinition=new RootBeanDefinition(); beanDefinition.setBeanClass(Car.class); beanDefinition.setBeanClassName("org.springframework.lq.beanFactory.Car"); BeanDefinitionHolder beanDefinitionHolder=new BeanDefinitionHolder(beanDefinition,"car"); // 我們把這步叫做 註冊Bean 實現了BeanDefinitionRegistry介面 //參考:org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader#processBeanDefinition BeanDefinitionReaderUtils.registerBeanDefinition(beanDefinitionHolder, (BeanDefinitionRegistry) beanFactory); } }
BeanPostProcessor
* 1.例項化、依賴注入完畢,在呼叫顯示的初始化之前完成一些定製任務
* 2.例項化、依賴注入、初始化完畢時執行,完成一些定製任務
可以通過此擴充套件完成實現代理 或者動態改變屬性值
如:以下例子友好的封裝實現MQ監聽器
1.定義介面
public interface RabbitMQListener<T> { String getQueueName(); String getRoutingKey(); String getExchangeName(); void process(T t); }
2.自動監聽實現
/**
*通過xml或者註解的方式註冊到spring即可
**/
public class AutoRegisterRabbitMQListener implements BeanPostProcessor { @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { //是否是監聽器 if(bean instanceof RabbitMQListener){ RabbitMQListener rabbitMQListener=(RabbitMQListener)bean; //=================動態監聽=============================== String exchangeName = rabbitMQListener.getExchangeName(); String queueName = rabbitMQListener.getQueueName(); String routingKey =rabbitMQListener.getRoutingKey(); Connection connection = newConnection(); //宣告一個channel一個連線可以監聽多個channel 連線複用 Channel channel = connection.createChannel(); //宣告一個名字為test 非自動刪除的 direct型別的exchange 更多配置書37頁 channel.exchangeDeclare(exchangeName, "direct", true); //宣告一個持久化,非排他,非自動刪除的佇列 channel.queueDeclare(queueName, true, false, false, null); //將佇列與交換器繫結 channel.queueBind(queueName, exchangeName, routingKey); //未名字路由的回撥 channel.addReturnListener(new ReturnListener() { @Override public void handleReturn(int replyCode, String replyText, String exchange, String routingKey, AMQP.BasicProperties properties, byte[] body) throws IOException { //反射獲取當前RabbitMQListener的泛型classs Class resultType=getMessageClass(); rabbitMQListener.process(JSON.parseObject(new String(body),resultType)); } }); } return bean; } }
3.當需要實現一個監聽學生的消費者
public class AddStudentListener implements RabbitMQListener<Student> { @Override public String getQueueName() { return "testQueue"; } @Override public String getRoutingKey() { return "testRotingkey"; } @Override public String getExchangeName() { return "testExchange"; } @Override public void process(Student student) { System.out.println("student開始消費了"); } }