BeanDefinition
描述了一个bean
实例,它具有属性值、构造函数参数值以及由具体实现提供的更多信息。
BeanDefinition 中需要用到的方法
// BeanDefinition 描述了一个 bean 实例,它具有属性值、构造函数参数值以及由具体实现提供的更多信息。
public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement {
...
//配置 Bean 的 Class 全路径
void setBeanClassName(@Nullable String beanClassName);
// 配置 Bean 是否是自动装配的候选者
void setAutowireCandidate(boolean autowireCandidate);
// 如果找到了多个可注入bean
// 则选择被Primary标记为首选的 Bean
void setPrimary(boolean primary);
// 配置 FactoryBean 的名字
void setFactoryBeanName(@Nullable String factoryBeanName);
// 配置 FactoryMethod 的名字,和 FactoryBean 配合使用
// 可以是某个实例的方法,也可以是静态方法
void setFactoryMethodName(@Nullable String factoryMethodName);
}
// 具体的、成熟的 BeanDefinition 类的基类
// 分解出 GenericBeanDefinition、RootBeanDefinition 和 ChildBeanDefinition 的通用属性。
// 自动装配常量与 AutowireCapableBeanFactory 接口中定义的常量相匹配。
public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccessor
implements BeanDefinition, Cloneable {
...
// 指定此 bean 的构造函数参数值
public void setConstructorArgumentValues(ConstructorArgumentValues constructorArgumentValues);
// 指定此 bean 的属性值(如果有)
public void setPropertyValues(MutablePropertyValues propertyValues);
}
(一)通过构造函数实例化 Bean
1)测试类 User
@Data
public class User {
private Long id;
private String name;
}
2)自定义 RootBeanDefinition,注册到 Spring 容器中
public class TestBeanDefinition {
public static void main(String[] args) {
DefaultListableBeanFactory context = new DefaultListableBeanFactory();
// 1. 实例化一个 RootBeanDefinition
RootBeanDefinition beanDefinition = new RootBeanDefinition();
// 2. 设置 BeanClass
beanDefinition.setBeanClass(User.class);
// 3. 设置 构造方法对应的属性值
ConstructorArgumentValues constructorArgumentValues = new ConstructorArgumentValues();
constructorArgumentValues.addGenericArgumentValue(1L);
constructorArgumentValues.addGenericArgumentValue("huhu");
beanDefinition.setConstructorArgumentValues(constructorArgumentValues);
// 4. 注册到 Spring 容器中
context.registerBeanDefinition("user", beanDefinition);
System.out.println(context.getBean("user"));
}
}
3)控制台输出:
15:45:03.441 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'user'
User(id=1, name=huhu)
4)源码位置
package org.springframework.beans.factory.support;
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory
implements AutowireCapableBeanFactory {
...
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
...
// Candidate constructors for autowiring?
// mbd.hasConstructorArgumentValues() 表示设置了 ConstructorArgumentValues
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
// 选择合适的构造函数,并进行实例化操作
return autowireConstructor(beanName, mbd, ctors, args);
}
...
}
}
(二)实例化 Bean 后通过 Setter 方法进行属性赋值
1)测试代码:
public class TestBeanDefinition {
public static void main(String[] args) {
DefaultListableBeanFactory context = new DefaultListableBeanFactory();
// 1. 实例化一个 RootBeanDefinition
RootBeanDefinition beanDefinition = new RootBeanDefinition();
// 2. 设置 BeanClass
beanDefinition.setBeanClass(User.class);
// 3. 设置 构造方法对应的属性值
ConstructorArgumentValues constructorArgumentValues = new ConstructorArgumentValues();
constructorArgumentValues.addGenericArgumentValue(1L);
constructorArgumentValues.addGenericArgumentValue("huhu");
beanDefinition.setConstructorArgumentValues(constructorArgumentValues);
// 4. 注册到 Spring 容器中
context.registerBeanDefinition("user", beanDefinition);
System.out.println(context.getBean("user"));
}
}
2)源码位置
package org.springframework.beans.factory.support;
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory
implements AutowireCapableBeanFactory {
...
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
...
// Instantiate the bean.
BeanWrapper instanceWrapper = null;
if (instanceWrapper == null) {
// 1. 实例化 bean 对象
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
// Initialize the bean instance.
// 3. 初始化 Bean,通过 Setter 方法
populateBean(beanName, mbd, instanceWrapper);
...
}
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
...
// No special handling: simply use no-arg constructor.
// 2. 通过无参数构造函数实例化对象
return instantiateBean(beanName, mbd);
}
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
...
// 4. 获取 BeanDefinition 中配置的 PropertyValues
PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
if (pvs != null) {
// 5. 调用 setter 方法进行设置
applyPropertyValues(beanName, mbd, bw, pvs);
}
...
}
}
(三)通过工厂方法实例化对象
(3.1)源码解读
package org.springframework.beans.factory.support;
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory
implements AutowireCapableBeanFactory {
...
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
// 如果工厂方法不为空,通过工厂方法实例化 bean 对象
if (mbd.getFactoryMethodName() != null) {
return instantiateUsingFactoryMethod(beanName, mbd, args);
}
}
...
}
package org.springframework.beans.factory.support;
class ConstructorResolver {
public BeanWrapper instantiateUsingFactoryMethod(
String beanName, RootBeanDefinition mbd, @Nullable Object[] explicitArgs) {
BeanWrapperImpl bw = new BeanWrapperImpl();
this.beanFactory.initBeanWrapper(bw);
Object factoryBean;
Class<?> factoryClass;
boolean isStatic;
// 1. 获取 factoryBeanName
String factoryBeanName = mbd.getFactoryBeanName();
if (factoryBeanName != null) {
// 2. 获取 factoryBean
factoryBean = this.beanFactory.getBean(factoryBeanName);
factoryClass = factoryBean.getClass();
isStatic = false;
}
else {
// It's a static factory method on the bean class.
// 3. 没有设置 factoryBeanName 表示为静态的工厂方法
factoryBean = null;
factoryClass = mbd.getBeanClass();
isStatic = true;
}
if (factoryMethodToUse == null || argsToUse == null) {
// Need to determine the factory method...
// Try all methods with this name to see if they match the given arguments.
factoryClass = ClassUtils.getUserClass(factoryClass);
List<Method> candidates = null;
// 4. 选择合适的候选工厂方法
// static 修饰符是否符合条件 && methodName 是否符合条件
if (candidates == null) {
candidates = new ArrayList<>();
Method[] rawCandidates = getCandidateMethods(factoryClass, mbd);
for (Method candidate : rawCandidates) {
if (Modifier.isStatic(candidate.getModifiers()) == isStatic && mbd.isFactoryMethod(candidate)) {
candidates.add(candidate);
}
}
}
// 5. 获取配置的 ConstructorArgumentValues 参数
ConstructorArgumentValues resolvedValues = null;
if (mbd.hasConstructorArgumentValues()) {
ConstructorArgumentValues cargs = mbd.getConstructorArgumentValues();
resolvedValues = new ConstructorArgumentValues();
resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues);
}
Deque<UnsatisfiedDependencyException> causes = null;
// 6. 找到符合条件的工厂方法,并赋值给 factoryMethodToUse
for (Method candidate : candidates) {
factoryMethodToUse = candidate;
}
}
// 7. 通过工厂方法实例化 bean 对象
bw.setBeanInstance(instantiate(beanName, mbd, factoryBean, factoryMethodToUse, argsToUse));
return bw;
}
}
(3.2)静态方法实例化 Bean 对象
1)定义工厂类
public class UserFactory {
// 不带参数的工厂方法
public static User getUser() {
return User.builder()
.id(100L)
.name("who are you")
.build();
}
// 带参数的工厂方法
public static User getUser(long id, String name) {
return User.builder()
.id(id)
.name(name)
.build();
}
}
2)无参的工厂方法实例化 Bean 对象
public class TestBeanDefinition {
public static void main(String[] args) {
DefaultListableBeanFactory context = new DefaultListableBeanFactory();
// 1. 实例化一个 RootBeanDefinition
RootBeanDefinition beanDefinition = new RootBeanDefinition();
// 2. 设置工厂方法和工厂类
// 这里的 BeanClass 是工厂类
beanDefinition.setFactoryMethodName("getUser");
beanDefinition.setBeanClass(UserFactory.class);
// 3. 注册到 Spring 容器中
context.registerBeanDefinition("user", beanDefinition);
System.out.println(context.getBean("user"));
}
}
控制台输出:
13:20:42.071 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'user'
User(id=100, name=who are you)
3)有参数的工厂方法实例化 Bean 对象
public class TestBeanDefinition {
public static void main(String[] args) {
DefaultListableBeanFactory context = new DefaultListableBeanFactory();
// 1. 实例化一个 RootBeanDefinition
RootBeanDefinition beanDefinition = new RootBeanDefinition();
// 2. 设置工厂方法和工厂类
// 这里的 BeanClass 是工厂类
beanDefinition.setFactoryMethodName("getUser");
beanDefinition.setBeanClass(UserFactory.class);
// 3. 设置 FactoryMethodName 的参数
ConstructorArgumentValues constructorArgumentValues = new ConstructorArgumentValues();
constructorArgumentValues.addGenericArgumentValue(1L);
constructorArgumentValues.addGenericArgumentValue("huhu");
beanDefinition.setConstructorArgumentValues(constructorArgumentValues);
// 4. 注册到 Spring 容器中
context.registerBeanDefinition("user", beanDefinition);
System.out.println(context.getBean("user"));
}
}
控制台输出:
13:22:34.074 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'user'
User(id=1, name=huhu)
(3.3)成员方法实例化 Bean 对象
1)定义工厂类,并通过 @Component
注入到 Spring 容器中。
@Component
public class UserFactory {
// 不带参数的工厂方法
public User getUser() {
return User.builder()
.id(2000L)
.name("I am the King")
.build();
}
// 带参数的工厂方法
public User getUser(long id, String name) {
return User.builder()
.id(id)
.name(name)
.build();
}
}
2)无参的工厂方法实例化 Bean 对象
@Component
@Slf4j
public class RegistryCommandLineRunner implements CommandLineRunner{
@Autowired
private DefaultListableBeanFactory context;
@Override
public void run(String... args) throws Exception {
// 1. 实例化一个 RootBeanDefinition
RootBeanDefinition beanDefinition = new RootBeanDefinition();
// 2. 设置 FactoryBeanName 和 FactoryMethodName
// FactoryBeanName 是工厂类在 Spring 容器中的 beanName
// FactoryMethodName 是工厂类用来生成当前 Bean 的方法
beanDefinition.setFactoryBeanName("userFactory");
beanDefinition.setFactoryMethodName("getUser");
// 3. 注册到 Spring 容器中
context.registerBeanDefinition("user", beanDefinition);
System.out.println(context.getBean("user"));
}
}
控制台输出:
User(id=2000, name=I am the King)
3)有参数的工厂方法实例化 Bean 对象
@Component
@Slf4j
public class RegistryCommandLineRunner implements CommandLineRunner{
@Autowired
private DefaultListableBeanFactory context;
@Override
public void run(String... args) throws Exception {
// 1. 实例化一个 RootBeanDefinition
RootBeanDefinition beanDefinition = new RootBeanDefinition();
// 2. 设置 FactoryBeanName 和 FactoryMethodName
// FactoryBeanName 是工厂类在 Spring 容器中的 beanName
// FactoryMethodName 是工厂类用来生成当前 Bean 的方法
beanDefinition.setFactoryBeanName("userFactory");
beanDefinition.setFactoryMethodName("getUser");
// 3. 设置 FactoryMethodName 的参数
ConstructorArgumentValues constructorArgumentValues = new ConstructorArgumentValues();
constructorArgumentValues.addGenericArgumentValue(1L);
constructorArgumentValues.addGenericArgumentValue("huhu");
beanDefinition.setConstructorArgumentValues(constructorArgumentValues);
// 4. 注册到 Spring 容器中
context.registerBeanDefinition("user", beanDefinition);
System.out.println(context.getBean("user"));
}
}
控制台输出:
User(id=1, name=huhu)
网友评论