1. 实例化(Spring 实例化 Bean 时需读取该 Bean 对应的 BeanDefinition)
2. 属性赋值 Populate(翻译为 填充的意思)
3. 初始化
4. 销毁
BeanDefinition 的定义与作用
BeanDefinition 是 Spring 内部的一个接口,定义了 Bean 描述的基本规范,值得关注的主要方法包括:
- getBeanClassName:获取 Bean 的类名称;
- isLazyInit:是否懒加载;
- getFactoryBeanName:获取对应的 FactoryBean 的名称;
- getConstructorArgumentValues:获取构造器参数,可以通过 xml、注解注入;
- getPropertyValues:获取属性参数,可以通过 xml、注解注入。
可以看到 BeanDefinition 接口的方法覆盖了 Spring 构造 Bean 需要的所有信息,是一个什么样的类型,构造器有哪些实参,属性的值注入哪些值,使用哪个 FactoryBean 来获取 Bean等。限于篇幅,BeanDefinition 的其他数据,比如是否单例、是否原型等就不一一介绍了。
Spring(四)核心容器 - BeanDefinition 解析
目录
BeanDefinition 主要是用来描述 Bean,其存储了 Bean 的相关信息,Spring 实例化 Bean 时需读取该 Bean 对应的 BeanDefinition。
BeanDefinition 整体可以分为两类,
一类是描述通用的 Bean,还有一类是描述注解形式的 Bean。
一般前者在 XML 时期定义 <bean‘> 标签以及在 Spring 内部使用较多,
而现今我们大都使用后者,通过注解形式加载 Bean。
jar包里的是不能将内部类抽取出来的, 需要下载spring源码才可以
Diagrams类图中,显而易见:
- 蓝色/绿色 实线箭头 是指 extends 关系
- 绿色虚线箭头 是指 implements 关系
AnnotatedBeanDefinition
AnnotatedBeanDefinition 是 BeanDefinition 子接口之一,该接口扩展了 BeanDefinition 的功能,其用来操作注解元数据。一般情况下,通过注解方式得到的 Bean(@Component、@Bean),其 BeanDefinition 类型都是该接口的实现类。
public interface AnnotatedBeanDefinition extends BeanDefinition {
// 获得当前 Bean 的注解元数据
AnnotationMetadata getMetadata();
// 获得当前 Bean 的工厂方法上的元数据
MethodMetadata getFactoryMethodMetadata();
}
该接口可以返回两个元数据的类:
-
AnnotationMetadata:主要对 Bean 的注解信息进行操作,如:获取当前 Bean 标注的所有注解、判断是否包含指定注解。
-
MethodMetadata:方法的元数据类。提供获取方法名称、此方法所属类的全类名、是否是抽象方法、判断是否是静态方法、判断是否是final方法等。
bean的生命周期 1. 实例化,2.属性赋值, 3.初始化
BeanDefinition它是实例化 Bean 的原材料,Spring 就是根据 BeanDefinition 中的信息实例化 Bean
BeanDefinition 用于保存 Bean 的相关信息,包括属性、构造方法参数、依赖的 Bean 名称及是否单例、延迟加载等,它是实例化 Bean 的原材料,Spring 就是根据 BeanDefinition 中的信息实例化 Bean。
工厂要提前准备好
AbstractApplicationContext #refresh()
AbstractAutowireCapableBeanFactory #createBean()
属性填充-->初始化
import com.winner.service.UserService;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import java.util.Arrays;
public class Main {
public static void main(String[] args) {
// AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
// context.register(AppConfig.class);
// context.refresh();
// 上面3行代码, 可以换位一下一行代码
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
String[] beanDefinitionNames = context.getBeanDefinitionNames();
System.out.println("----------------------------");
System.out.println("打印容器中所有的beanDefinitionNames");
Arrays.stream(beanDefinitionNames).forEach(a -> System.out.println(a));
BeanDefinition beanDefinition = context.getBeanDefinition("userServiceImpl");
// Generic bean: class [com.winner.service.UserServiceImpl];
// scope=singleton; abstract=false;
// lazyInit=null;
// autowireMode=0;
// dependencyCheck=0;
// autowireCandidate=true;
// primary=false;
// factoryBeanName=null;
// factoryMethodName=null;
// initMethodName=null;
// destroyMethodName=null;
// defined in file [D:\code\spring-framework\sino\build\classes\java\main\com\winner\service\UserServiceImpl.class]
UserService userService = context.getBean("userServiceImpl", UserService.class);
userService.test();
}
}