1. 程式人生 > 實用技巧 >spring原始碼閱讀-使用例子

spring原始碼閱讀-使用例子

說明

這裡定義在原始碼中看到的各個介面使用例子

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 {
    @Override
    
public 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開始消費了");
    }
}