文章目录
前言
- 在了解 spring 源码 的是我们知道 我们的Bean 都会被包装成 BeanDefinition进行操作
- 所以需要对其有一个基本的了解
- 这是一个抽象类
- 其子类有
- RootBeanDefinition
- GenericBeanDefinition
- 该类封装了大部分了操作 BeanDefinition 的操作 你所知道的一些属性 甚至一些操作都在这个类…
属性分析
参考了
…
applyDefaults
- 传递一个
BeanDefinitionDefaults对象进行一些默认值的填充…没啥可说的… 就是为了方便填充的一个方法,比如当你需要批量这么做的时候就可以定义一个 这样的对象…进行属性填充~~~ - 比如去扫描的时候…因为这个方法就是在 扫描的时候去用的…
BeanClass相关方法
- setBeanClassName() 设置Bean的ClassName,这个方法比较有意思,有意思在那下面去看
// 设置Bean的ClassName 赋值给 BeanClass
public void setBeanClassName(@Nullable String beanClassName) {
this.beanClass = beanClassName;
}
- getBeanClassName() 这个方法比较有意思… 从setBeanClassName看的话我们设置的是String 为啥要做一个判断呢… 嘻嘻,那是因为还有一个方法会进行覆盖…
public String getBeanClassName() {
// 获取 beanClass Name
Object beanClassObject = this.beanClass;
// 如果当前类本身就是 Class 类型的话 就获取Name
// 如果不是则直接返回 beanClass ,因为此时 beanClass 可能还是 字符串
if (beanClassObject instanceof Class) {
return ((Class<?>) beanClassObject).getName();
}
else {
// 如果不是Class 类型就代表本身就是String那就强制返回
return (String) beanClassObject;
}
}
- setBeanClass () 这个方法就是设置一个Class 赋值给BeanClass 是跟 setBeanClassName 逻辑是一样一样的,那为啥要这么做呢 ?我们来做一个实验
public void setBeanClass(@Nullable Class<?> beanClass) {
this.beanClass = beanClass;
}
- getClass()
public Class<?> getBeanClass() throws IllegalStateException {
// 这里获取Bean的Class 这里我们知道BeanClass 可能是 Class 类型 也可能是 String 类型
Object beanClassObject = this.beanClass;
if (beanClassObject == null) {
// 抛出异常
}
// 这里如果 不是CLass 就会抛出异常,
// 所以一般在调用这个方法之前会调用 hasBeanClass() 判断一下到底beanClass 是不是
// class 类型,除非你能确定这个就是Class 类型,比如我们手动设置API~~~
if (!(beanClassObject instanceof Class)) {
// 抛出异常
}
return (Class<?>) beanClassObject;
}
-
hasBeanClass() 判断 这个BeanClass 是否存在,上面已经详细讲过这个是为啥了…下面会用例子说明这个问题
-
resolveBeanClass() 简单说用于将ClassName转成Class…
public Class<?> resolveBeanClass(@Nullable ClassLoader classLoader) throws ClassNotFoundException {
// 获取ClassName
String className = getBeanClassName();
if (className == null) {
return null;
}
// 根据Name 获取 Class 类型
Class<?> resolvedClass = ClassUtils.forName(className, classLoader);
// 将 Class 类型 赋值给 beanClass ,此时的beanClass(字符串) 转换成了 Class 类型
this.beanClass = resolvedClass;
return resolvedClass;
}
- 产生的疑问,我们并没有设置Class呀,这个User 对象是怎么被创建的?
public static void main(String[] args) {
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
BeanDefinitionBuilder userBeanBuilder = BeanDefinitionBuilder.genericBeanDefinition();
AbstractBeanDefinition beanDefinition = userBeanBuilder.getBeanDefinition();
// 可以看到这里我们设置的 仅仅是这个User.class的Name 并不是设置的Class
beanDefinition.setBeanClassName(User.class.getName());
beanFactory.registerBeanDefinition("user",beanDefinition);
User bean = beanFactory.getBean(User.class);
System.out.println(bean);
AbstractBeanDefinition user = (AbstractBeanDefinition) beanFactory.getBeanDefinition("user");
System.out.println(beanDefinition==user);
}
- 稍微略一下 创建的源码你就会知道了~~
- AbstractBeanFactory.resolveBeanClass()// 这个方法是去获取Class 去了…可以直接DBUG到这个地方看看
protected Class<?> resolveBeanClass(RootBeanDefinition mbd, String beanName, Class<?>... typesToMatch)
throws CannotLoadBeanClassException {
// 删除了一些没啥影响的代码
// 是否存在 BeanClass 定义, 这里就是去判断去了,可是我传递的是String ,所以是不存在的
if (mbd.hasBeanClass()) {
// 返回BeanClass,如果我们设置的类型是Class 就会直接返回
return mbd.getBeanClass();
}
// 这里就代表没设置.. 那就会去通过 我们设置的Name 去获取这个Class,这里可以自己去跟源码,由于本文就不是讲解这些源码的所以就不过多的渗透进去了
return doResolveBeanClass(mbd, typesToMatch);
}
Singleton相关代码演示
- 用于设置作用域…
- getSingleton --如果没有设置去get的时候默认是
""空串,代表了单例 - setSingleton
- isSingleton --判断是否是单例,如果设置了
singleton或者是空就代表是单例 - isPrototype --判断是否是原型…
- getSingleton --如果没有设置去get的时候默认是
private static final DefaultListableBeanFactory beanFactory;
private static final AbstractBeanDefinition beanDefinition;
static{
beanFactory = new DefaultListableBeanFactory();
beanDefinition = BeanDefinitionBuilder.genericBeanDefinition().getBeanDefinition();
beanDefinition.setBeanClassName(User.class.getName());
beanFactory.registerBeanDefinition("user", beanDefinition);
}
public static void main(String[] args) {
// 判断单例还是 原型,还有一些 request session 等需要WEB的支持了..
// beanDefinition.setScope(BeanDefinition.SCOPE_SINGLETON);
beanDefinition.setScope(BeanDefinition.SCOPE_PROTOTYPE);
if(beanDefinition.isPrototype ()){
for (int i = 0; i <5; i++) {
User bean = beanFactory.getBean(User.class);
System.out.println(bean);
}
}else{
for (int i = 0; i <5; i++) {
User bean = beanFactory.getBean(User.class);
System.out.println(bean);
}
}
}
Bean构造参数演示
- 构造器
- getConstructorArgumentValues – 获取构造器参数
- setConstructorArgumentValues – 设置构造器参数
- hasConstructorArgumentValues --判断存在构造器参数
- 如果 存在构造器函数参数,则就会去创建有参的构造函数,不会去创建无参的构造
private static final DefaultListableBeanFactory beanFactory;
private static final AbstractBeanDefinition beanDefinition;
static {
beanFactory = new DefaultListableBeanFactory();
beanDefinition = BeanDefinitionBuilder.genericBeanDefinition().getBeanDefinition();
beanDefinition.setBeanClassName(User.class.getName());
beanFactory.registerBeanDefinition("user", beanDefinition);
}
private static void constructorArgumentValues() {
ConstructorArgumentValues value = new ConstructorArgumentValues();
value.addIndexedArgumentValue(0, "北京");
value.addIndexedArgumentValue(1, "张三");
value.addIndexedArgumentValue(2, 99);
beanDefinition.setConstructorArgumentValues(value);
System.out.println(getBean());
}
- 源码
AbstractAutowireCapableBeanFactory.createBeanInstance()
- 这里会有一个判断,判断是否存在 构造器参数,如果存在则就会执行有参构造器,无参构造器还没执行到~~

Bean参数设置
- 属性
- setPropertyValues 属性
- getPropertyValues
- hasPropertyValues
初始化、销毁方法
- setInitMethodName – 初始化方法
- setEnforceInitMethod – 设置是否启动 初始化方法 (这里不用过多关注…)
- isEnforceInitMethod – 判断是否启动了初始化方法 (这里不用过多关注…)
- setDestroyMethodName 销毁方法
其他功能方法
* setAbstract --设置为抽象的..如果设置为true也就是说不会进行实例化
* isAbstract --判断是否是抽象的
* setLazyInit 设置懒加载
* isLazyInit 判断是否是懒加载
* getLazyInit 获取..懒加载
* setAutowireMode 设置自动装配
* getAutowireMode 获取自动装配 --默认是 AUTOWIRE_NO 不进行自动装配
* setPrimary 设置是否是主要的
* isPrimary 判断是否为主要''
factory相关
- setFactoryBeanName --设置
- getFactoryBeanName --获取
- setFactoryMethodName --设置方法
- getFactoryMethodName --获取方法
这一个个的API 我就想一一演示的
可以自行去演示玩玩看
public static void main(String[] args) {
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition().getBeanDefinition();
beanDefinition.setBeanClassName(User.class.getName());
// 设置直接去设置 BeanDefinition 就好了,比如我设置一个原型,就可以看到每次创建的对象都不一样...
beanDefinition.setScope(BeanDefinition.SCOPE_SINGLETON);
beanFactory.registerBeanDefinition("user", beanDefinition);
}
但是可以明确的是 spring 就是这么玩的… 不管是XML 还是注解还是 外部配置等…
相关文章
GenericBeanDefinition-分析
AbstractBeanDefinition分析
BeanMetadataAttributeAccessor 分析

本文深入探讨Spring框架中BeanDefinition的使用与实现细节,包括属性分析、作用域设置、构造参数处理、初始化与销毁方法等关键功能。通过具体代码演示,帮助读者理解如何在Spring中管理和操作Bean。

606

被折叠的 条评论
为什么被折叠?



