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的所有方法!!


相关文章
|
1月前
|
XML Java 数据格式
探索Spring之利剑:ApplicationContext接口
本文深入介绍了Spring框架中的核心接口ApplicationContext,解释了其作为应用容器的功能,包括事件发布、国际化支持等,并通过基于XML和注解的配置示例展示了如何使用ApplicationContext管理Bean实例。
86 6
|
12天前
|
缓存 安全 Java
Spring Boot 3 集成 Spring Security + JWT
本文详细介绍了如何使用Spring Boot 3和Spring Security集成JWT,实现前后端分离的安全认证概述了从入门到引入数据库,再到使用JWT的完整流程。列举了项目中用到的关键依赖,如MyBatis-Plus、Hutool等。简要提及了系统配置表、部门表、字典表等表结构。使用Hutool-jwt工具类进行JWT校验。配置忽略路径、禁用CSRF、添加JWT校验过滤器等。实现登录接口,返回token等信息。
179 12
|
18天前
|
存储 安全 Java
Spring Boot 3 集成Spring AOP实现系统日志记录
本文介绍了如何在Spring Boot 3中集成Spring AOP实现系统日志记录功能。通过定义`SysLog`注解和配置相应的AOP切面,可以在方法执行前后自动记录日志信息,包括操作的开始时间、结束时间、请求参数、返回结果、异常信息等,并将这些信息保存到数据库中。此外,还使用了`ThreadLocal`变量来存储每个线程独立的日志数据,确保线程安全。文中还展示了项目实战中的部分代码片段,以及基于Spring Boot 3 + Vue 3构建的快速开发框架的简介与内置功能列表。此框架结合了当前主流技术栈,提供了用户管理、权限控制、接口文档自动生成等多项实用特性。
69 8
|
1月前
|
负载均衡 Java 开发者
深入探索Spring Cloud与Spring Boot:构建微服务架构的实践经验
深入探索Spring Cloud与Spring Boot:构建微服务架构的实践经验
179 5
|
3月前
|
存储 安全 Java
|
3月前
|
Java 测试技术 开发者
springboot学习四:Spring Boot profile多环境配置、devtools热部署
这篇文章主要介绍了如何在Spring Boot中进行多环境配置以及如何整合DevTools实现热部署,以提高开发效率。
137 2
|
3月前
|
前端开发 Java 程序员
springboot 学习十五:Spring Boot 优雅的集成Swagger2、Knife4j
这篇文章是关于如何在Spring Boot项目中集成Swagger2和Knife4j来生成和美化API接口文档的详细教程。
436 1
|
3月前
|
Java Spring
springboot 学习十一:Spring Boot 优雅的集成 Lombok
这篇文章是关于如何在Spring Boot项目中集成Lombok,以简化JavaBean的编写,避免冗余代码,并提供了相关的配置步骤和常用注解的介绍。
164 0
|
1天前
|
JavaScript Java 测试技术
基于SpringBoot+Vue实现的留守儿童爱心网站设计与实现(计算机毕设项目实战+源码+文档)
博主是一位全网粉丝超过100万的CSDN特邀作者、博客专家,专注于Java、Python、PHP等技术领域。提供SpringBoot、Vue、HTML、Uniapp、PHP、Python、NodeJS、爬虫、数据可视化等技术服务,涵盖免费选题、功能设计、开题报告、论文辅导、答辩PPT等。系统采用SpringBoot后端框架和Vue前端框架,确保高效开发与良好用户体验。所有代码由博主亲自开发,并提供全程录音录屏讲解服务,保障学习效果。欢迎点赞、收藏、关注、评论,获取更多精品案例源码。
27 10
|
1天前
|
JavaScript Java 测试技术
基于SpringBoot+Vue实现的家政服务管理平台设计与实现(计算机毕设项目实战+源码+文档)
面向大学生毕业选题、开题、任务书、程序设计开发、论文辅导提供一站式服务。主要服务:程序设计开发、代码修改、成品部署、支持定制、论文辅导,助力毕设!
20 8