Spring5源码 - 02 Bean和Java对象的区别与猜想验证BeanDefinition

简介: Spring5源码 - 02 Bean和Java对象的区别与猜想验证BeanDefinition

20200914143739548.png


问题

Spring创建的Bean 和 我们提供的Class对象 有什么关系吗? 一定是我们提供的这个对象实例吗?


加载流程



20200916090019877.png



BeanFactoryPostProcessor的执行时机


结合上图的流程,我们可以得出如下结论

  1. 在bean被转换成BeanDefinition之后
  2. 在实例化bean之前


中间这个部分,如果用户实现了BeanFactoryPostProcessor接口,则可以对BeanDefinition进行修改


Code

演示下这个功能


2020091601290443.png


两个类 一个可以被Spring扫描到的bean Artisan1 , 另外一个是普通的对象 Artisan2

package com.artisan.bd;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
@Component
public class Artisan1 {
  @PostConstruct
  public void  init(){
    System.out.println("Artisan1 Created");
  }
}


标注了 @Component

package com.artisan.bd;
import javax.annotation.PostConstruct;
public class Artisan2 {
}


普通对象


配置类

package com.artisan.bd;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@ComponentScan("com.artisan.bd")
public class AppConfig {
}


测试类

package com.artisan.bd;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class Test {
  public static void main(String[] args) {
    AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);
    System.out.println(ac.getBean(Artisan1.class));
    System.out.println(ac.getBean(Artisan2.class));
  }
}


20200916013416918.png

同时我们也看到了 Artisan1这个对象,对应的 BeanDefinition中的beanClass也是 Artisan1 .


那能改么? 能改成Artisan2吗?


看了刚才的流程图,我们知道如果实现了BeanFactoryPostProcessor接口,就可以修改BeanDefinition。


试试吧

package com.artisan.bd;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.GenericBeanDefinition;
import org.springframework.stereotype.Component;
@Component
public class ArtisanBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
  /**
   * beanFactory 就是流程图中的 bdmap    BeanDefinition的map集合
   * @param beanFactory the bean factory used by the application context
   * @throws BeansException
   */
  @Override
  public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
    // 取出A对应的 beanDefinition -----> 这时候bd中存放的类是A.class
    GenericBeanDefinition beanDefinition = (GenericBeanDefinition) beanFactory.getBeanDefinition("artisan1");
    //ScannedGenericBeanDefinition beanDefinition1 = (ScannedGenericBeanDefinition) beanFactory.getBeanDefinition("artisan1");
    // 将bd中的beanclass修改为B
    beanDefinition.setBeanClass(Artisan2.class);
  }
}


20200916085458412.png

使用实现类来接收 beanFactory.getBeanDefinition(“artisan1”) 的返回值,可用方法更多,接口中的方法太少,并且也木有我们要用的setBeanClassName 方法。


别忘了加@Component,不然spring无法扫描到,这个就不会生效 。


再此执行刚才的代码

20200916014024300.png


20200916014253611.png


同时,通过name artisan1 获取到的bean 其实是被修改后了的, 因为Sping根据用户提供的Artisan2, 实例化了Artisan2


20200916090230642.png


再比如说修改scope

20200916014816748.png20200916014855683.png


都明白了哈, 后面从源码的角度分析 ~


相关文章
|
5天前
|
设计模式 缓存 Java
重学Java基础篇—Java对象创建的7种核心方式详解
本文全面解析了Java中对象的创建方式,涵盖基础到高级技术。包括`new关键字`直接实例化、反射机制动态创建、克隆与反序列化复用对象,以及工厂方法和建造者模式等设计模式的应用。同时探讨了Spring IOC容器等框架级创建方式,并对比各类方法的适用场景与优缺点。此外,还深入分析了动态代理、Unsafe类等扩展知识及注意事项。最后总结最佳实践,建议根据业务需求选择合适方式,在灵活性与性能间取得平衡。
42 3
|
12天前
|
存储 算法 安全
Java对象创建和访问
Java对象创建过程包括类加载检查、内存分配(指针碰撞或空闲列表)、内存初始化、对象头设置及初始化方法执行。访问方式有句柄和直接指针两种,前者稳定但需额外定位,后者速度快。对象创建涉及并发安全、垃圾回收等机制。
Java对象创建和访问
|
17天前
|
存储 监控 数据可视化
SaaS云计算技术的智慧工地源码,基于Java+Spring Cloud框架开发
智慧工地源码基于微服务+Java+Spring Cloud +UniApp +MySql架构,利用传感器、监控摄像头、AI、大数据等技术,实现施工现场的实时监测、数据分析与智能决策。平台涵盖人员、车辆、视频监控、施工质量、设备、环境和能耗管理七大维度,提供可视化管理、智能化报警、移动智能办公及分布计算存储等功能,全面提升工地的安全性、效率和质量。
|
1月前
|
存储 Java
Java中判断一个对象是否是空内容
在 Java 中,不同类型的对象其“空内容”的定义和判断方式各异。对于基本数据类型的包装类,空指对象引用为 null;字符串的空包括 null、长度为 0 或仅含空白字符,可通过 length() 和 trim() 判断;集合类通过 isEmpty() 方法检查是否无元素;数组的空则指引用为 null 或长度为 0。
|
2月前
|
Java
Java快速入门之类、对象、方法
本文简要介绍了Java快速入门中的类、对象和方法。首先,解释了类和对象的概念,类是对象的抽象,对象是类的具体实例。接着,阐述了类的定义和组成,包括属性和行为,并展示了如何创建和使用对象。然后,讨论了成员变量与局部变量的区别,强调了封装的重要性,通过`private`关键字隐藏数据并提供`get/set`方法访问。最后,介绍了构造方法的定义和重载,以及标准类的制作规范,帮助初学者理解如何构建完整的Java类。
|
2月前
|
安全 Java
Object取值转java对象
通过本文的介绍,我们了解了几种将 `Object`类型转换为Java对象的方法,包括强制类型转换、使用 `instanceof`检查类型和泛型方法等。此外,还探讨了在集合、反射和序列化等常见场景中的应用。掌握这些方法和技巧,有助于编写更健壮和类型安全的Java代码。
72 17
|
2月前
|
Java
java代码优化:判断内聚到实体对象中和构造上下文对象传递参数
通过两个常见的java后端实例场景探讨代码优化,代码不是优化出来的,而是设计出来的,我们永远不可能有专门的时间去做代码优化,优化和设计在平时
|
2月前
|
监控 JavaScript 数据可视化
建筑施工一体化信息管理平台源码,支持微服务架构,采用Java、Spring Cloud、Vue等技术开发。
智慧工地云平台是专为建筑施工领域打造的一体化信息管理平台,利用大数据、云计算、物联网等技术,实现施工区域各系统数据汇总与可视化管理。平台涵盖人员、设备、物料、环境等关键因素的实时监控与数据分析,提供远程指挥、决策支持等功能,提升工作效率,促进产业信息化发展。系统由PC端、APP移动端及项目、监管、数据屏三大平台组成,支持微服务架构,采用Java、Spring Cloud、Vue等技术开发。
122 7
|
3月前
|
存储 Java Spring
【Spring】获取Bean对象需要哪些注解
@Conntroller,@Service,@Repository,@Component,@Configuration,关于Bean对象的五个常用注解
101 12
|
3月前
|
存储 Java 应用服务中间件
【Spring】IoC和DI,控制反转,Bean对象的获取方式
IoC,DI,控制反转容器,Bean的基本常识,类注解@Controller,获取Bean对象的常用三种方式