springboot原理实战(3)-- spring扩展接口BeanPostProcessor,BeanFactoryPostProcessor

简介: springboot原理实战(3)-- spring扩展接口BeanPostProcessor,BeanFactoryPostProcessor

目录:


入门springboot前,先了解spring的下面这三个接口扩展,很有必要。

先看下脑图:

1dc618a0ed9580ce8bfa6facb208c08f.png


1.BeanPostProcessor


这个接口上篇文章讲过,spring利用这个接口,只要实现ApplicationContextWare接口,就可以在此接口,获取springcontext.

他的主要作用也就是:在bean初始化时 搞点小动作:


举例演示:


注入一个bean:


@Component
public class User {
    @PostConstruct
    public void init(){
        System.out.println("===user init==");
    }
}


实现BeanPostProcessor接口,这个接口会影响所有的bean初始化。


@Component
public class MyBeanPostProcessor implements BeanPostProcessor {
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("=========postProcessBeforeInitialization========"+bean.getClass());
        return bean;
    }
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("=========postProcessAfterInitialization========"+bean.getClass());
        return bean;
    }
}


测试:


public class App2 {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext("com.springboot.demo3");
        System.out.println(User.class);
        context.close();
    }
}


运行结果:可以看出什么?在bean初始化前后都打印了。

5d4c6812c8535adbb050f4ddf2e1bce8.png


2.MyBeanFactoryPostProcessor


有了bean初始化时,进行一些小动作,那么容器初始化时是不是可以做一些小动作呢?可以。


这个就是BeanFactoryPostProcessor接口。


BeanFactoryPostProcessor在spring容器初始化之后触发,而且只会触发一次.

我们实现下这个接口:


@Component
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        System.out.println("=================="+ beanFactory.getBeanDefinitionCount());
    }
}


运行结果:

1dc618a0ed9580ce8bfa6facb208c08f.png


显示容器预先注入了8个对象,也就是,这个spring在背后注入了其他的bean。我们就可以在postProcessBeanFactory()方法中,在容器初始化时做一些业务操作。

特别注意: 仅仅会触发一次这个方法。


3.BeanDefinitionRegistryPostProcessor


刚才的那个方法,我们可以在容器初始化时,做一些事情,比如我们通过

beanFactory.getBeanDefinitionCount()获取初始化bean的个数,但是能不能再这里注入一些bean呢?


可以的。


不过得用到BeanFactoryPostProcessor的一个子接口:

5d4c6812c8535adbb050f4ddf2e1bce8.png

这个类扩展了一个方法:

46a9d80a6e05e4e3b19d57a0ee70bcdf.png

里面有个参数BeanDefinitionRegistry.这个类可以帮我们注入一些bean的操作。

66ba272a0bfc97be54a5fa679e3d5482.png

通过上面的registerBeanDefinition的方法。可以注入bean。


下面的removeBeanDefinition可以移除bean。


代码演示:


我们实现这个BeanDefinitionRegistryPostProcessor接口注入10个Person对象:


public class Person {
    private String name;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                '}';
    }
}


注意Person没有加@Component。


我们用容器注入:


@Component
public class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
    }
    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
        for (int i=1;i<=10;i++){
            BeanDefinitionBuilder bdb = BeanDefinitionBuilder.rootBeanDefinition(Person.class);
            bdb.addPropertyValue("name","admin"+i);
            registry.registerBeanDefinition("person"+i, bdb.getBeanDefinition());
        }
    }
}


测试类:


public class App2 {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext("com.springboot.demo3");
        context.getBeansOfType(Person.class).values().forEach(System.out::println);
        context.close();
    }
}


打印结果:

1dc618a0ed9580ce8bfa6facb208c08f.png

显示注入了。


扩展:也可以用AnnotationConfigApplicationContext注入


public class App2 {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext("com.springboot.demo3");
        for (int i=1;i<=10;i++){
            BeanDefinitionBuilder bdb = BeanDefinitionBuilder.rootBeanDefinition(Person.class);
            bdb.addPropertyValue("name","admin"+i);
            context.registerBeanDefinition("person"+i, bdb.getBeanDefinition());
        }
        context.getBeansOfType(Person.class).values().forEach(System.out::println);
        context.close();
    }
}


运行结果:

5d4c6812c8535adbb050f4ddf2e1bce8.png

为什么AnnotationConfigApplicationContext也可以注入bean呢?

46a9d80a6e05e4e3b19d57a0ee70bcdf.png66ba272a0bfc97be54a5fa679e3d5482.png


通过观察我们发现。AnnotationConfigApplicationContext是BeanDefinitionRegistry子接口的子接口。所以可以调用BeanDefinitionRegistry的所有方法!!


相关文章
|
2天前
|
Java Spring 容器
【Spring底层原理】BeanFactory的实现
【Spring底层原理】BeanFactory的实现
7 0
|
5天前
|
Java Spring 容器
Spring底层原理之 BeanFactory 与 ApplicationContext
Spring底层原理之 BeanFactory 与 ApplicationContext
16 3
|
6天前
|
Java Python Spring
小唐开始学 Spring Boot——(2)Spring Boot核心配置与注解
小唐开始学 Spring Boot——(2)Spring Boot核心配置与注解
|
14天前
|
移动开发 前端开发 NoSQL
ruoyi-nbcio从spring2.7.18升级springboot到3.1.7,java从java8升级到17(二)
ruoyi-nbcio从spring2.7.18升级springboot到3.1.7,java从java8升级到17(二)
150 0
|
14天前
|
监控 安全 Java
Spring cloud原理详解
Spring cloud原理详解
27 0
|
14天前
|
XML Java 数据库连接
Spring框架与Spring Boot的区别和联系
Spring框架与Spring Boot的区别和联系
40 0
|
14天前
|
Java Spring
spring boot访问接口报500
spring boot访问接口报500
16 2
|
14天前
|
Java 开发者 微服务
Spring Cloud原理详解
【5月更文挑战第4天】Spring Cloud是Spring生态系统中的微服务框架,包含配置管理、服务发现、断路器、API网关等工具,简化分布式系统开发。核心组件如Eureka(服务发现)、Config Server(配置中心)、Ribbon(负载均衡)、Hystrix(断路器)、Zuul(API网关)等。本文讨论了Spring Cloud的基本概念、核心组件、常见问题及解决策略,并提供代码示例,帮助开发者更好地理解和实践微服务架构。此外,还涵盖了服务通信方式、安全性、性能优化、自动化部署、服务网格和无服务器架构的融合等话题,揭示了微服务架构的未来趋势。
42 6
|
JSON 前端开发 Java
SpringBoot 实战:一招实现结果的优雅响应
今天说一下 Spring Boot 如何实现优雅的数据响应:统一的结果响应格式、简单的数据封装。
329 0
SpringBoot 实战:一招实现结果的优雅响应
|
21小时前
|
JavaScript Java 测试技术
基于vue和微信小程序的校园自助打印系统+springboot+vue.js附带文章和源代码设计说明文档ppt
基于vue和微信小程序的校园自助打印系统+springboot+vue.js附带文章和源代码设计说明文档ppt
18 7