Spring Boot使用BeanPostProcessor-後置處理器對Bean進行攔截,改造Bean或做一些邏輯業務

前面我們介紹了一些方式定製Bean的生命週期,這篇博客將介紹如何在把Bean注入容器之前攔截,再根據需求做一些操作。

  • 創建類實現BeanPostProcessor接口,並重寫方法。使用@Component註解,把其注入容器(這樣Processor才能起作用)。:
import com.michael.annotation.demo.POJO.Module;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.stereotype.Component;

@Component
public class MyBeanPostProcessor implements BeanPostProcessor {

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        if(beanName.equals("Module1")){
            ((Module)bean).setName("Java Programming");
        }
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("The postProcessAfterInitialization method is calling.");
        return bean;
    }
}
  • 測試代碼:
import com.michael.annotation.demo.POJO.Module;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;

import static java.lang.System.out;

@SpringBootApplication
public class DemoApplication {

    public static void main(String[] args) {
        ApplicationContext applicationContext = SpringApplication.run(DemoApplication.class, args);
        out.println("The container has been initialized.");
        for(String name : applicationContext.getBeanDefinitionNames()){
            if(!name.contains("."))
                out.println(name);
        }

        //print the module'name which is set when postProcessBeforeInitialization method is calling.
        out.println(((Module)applicationContext.getBean("Module1")).getName());

        out.println("The container has been destroyed.");
    }
}
  • 輸出:
The postProcessAfterInitialization method is calling.
The postProcessAfterInitialization method is calling.
The postProcessAfterInitialization method is calling.
The postProcessAfterInitialization method is calling.
The Module Bean is being created.
The postConstruct method is calling.
The postProcessAfterInitialization method is calling.
The postProcessAfterInitialization method is calling.
The postProcessAfterInitialization method is calling.
The postProcessAfterInitialization method is calling.
The postProcessAfterInitialization method is calling.
The postProcessAfterInitialization method is calling.
The postProcessAfterInitialization method is calling.
The postProcessAfterInitialization method is calling.
The postProcessAfterInitialization method is calling.
The postProcessAfterInitialization method is calling.
The postProcessAfterInitialization method is calling.
The postProcessAfterInitialization method is calling.
The postProcessAfterInitialization method is calling.
The postProcessAfterInitialization method is calling.
The postProcessAfterInitialization method is calling.
2020-03-25 16:23:35.478  INFO 28179 --- [           main] c.m.annotation.demo.DemoApplication      : Started DemoApplication in 0.636 seconds (JVM running for 0.93)
The container has been initialized.
demoApplication
test
myBeanPostProcessor
myConfig
personService
Module1
propertySourcesPlaceholderConfigurer
taskExecutorBuilder
applicationTaskExecutor
taskSchedulerBuilder
Java Programming
The container has been destroyed.
The preDestroy method is calling.

Process finished with exit code 0
  • 從輸出可以看出BeanPostProcessor-後置處理器裏面的方法在所有Bean被注入前後都被調用了一遍, 我們可以理解爲filter所有Bean。
  • ID爲"Module1"的Bean被攔截後,設置了其name屬性,在main方法中被打印出來。
  • 在學習Spring Boot的過程中,越發感覺AOP和IOC是Spring的核心。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章