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的核心。
发布了70 篇原创文章 · 获赞 4 · 访问量 3024

猜你喜欢

转载自blog.csdn.net/qq_34515959/article/details/105108732