BeanDefinition简单梳理
spring 容器启动的时候会先执行bean扫描操作,扫描之后的每个bean信息都封装到BeanDefinition中去,这个BeanDefinition 到底存放了什么信息?bean的class 类型,FactoryBean的名称和FactoryBean的工厂方法。 bean的作用域,是否是primary,是否是延迟加载,描述信息,是否是单例。 bean的依赖信息。 bean的初始化方法和销毁方法。 bean 属性值信息以及构造函数信息。 bean的其他信息等等。
总之一句话:beanDefinition中包含了要实例化和初始化一个bean的所有信息,另外引入BeanDefinition的另一个总用是:再只解析一次bean的情况下,尽可能的拿到bean的所有信息,防止重复解析,以空间获取时间。
spring是如何解析得到一个Bean的BeanDefiniton信息?这个底层是借助于asm技术(字节码解析技术)。
BeanDefinition 存在的意义 提升效率 :Spring创建一个Bean是通过反射创建的,通过将Class、注解信息等等这些信息缓存起来,在创建bean的时候能够直接从缓存中获取从而达到提升创建效率的目的。 方便修改 :spring创建对象的时候,创建的信息全部是通过 BeanDefinition 内存储的信息来创建对象的,所以,我们可以通过修改BeanDefinition内部特定的值来改变Spring创建对象的结果。 便于扩展 :我们通过一些特定的接口,可以获取到一个类的所有的BeanDefinition信息,从而完成一些特定功能的实现。
BeanDefinition一些实现及子接口 AnnotatedBeanDefinition: 子接口,新增了获取注解元数据信息和工厂方法元数据信息的方法。AbstractBeanDefinition:BeanDefinition 的抽象实现类,实现了BeanDefinition的大多数方法,同时定义了很多静态常量/定义了一些变量设置了默认值,一般的其他的BeanDefinition都是继承这个抽象类。ChildBeanDefinition:相当于一个子类,必须得有一个父级BeanDefinition(spring 2.5之后已经不建议使用了,可以用GenericBeanDefinition替代 )。RootBeanDefinition:可以作为其他BeanDefinition的父级BeanDefinition,也可以单独作为beanDefinition,但是不能设置其父级beanDefinition,setParentName方法会直接抛出异常。 ScannedGenericBeanDefinition:通过注解扫描出来的Bean的BeanDefinition都是这种类型。 AnnotatedGenericBeanDefinition:存在@Bean配置的配置类,扫描出来的BeanDefinition 都是这种类型。
BeanDefinition 在BeanFactory中是如何存储的
DefaultListableBeanFactory 类中定义了存储BeanDefinition的map
private final Map, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256 );
BeanDefinition生成的地方 ClassPathBeanDefinitionScanner:scan方法。AnnotatedBeanDefinitionReader: register 方法。编程的方式定义BeanDefinition:AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition(BizService.class) .addDependsOn("com.zgh.xxxxService") //设置一些依赖 .addPropertyValue("id",1243) //设置一些属性 .setInitMethodName("init") //设置初始化方法 .getBeanDefinition(); //BeanDefinitionRegistry registry,可以在BeanDefinitionRegistryPostProcessor 的postProcessBeanDefinitionRegistry //方法中进行注册 registry.registerBeanDefinition("bizService",beanDefinition);