目录
- 1. 类含义
- 2. Bean创建过程 - 流程图
- 3. 例子
- 3.1. 可变属性注入到实体中
- 3.2. 模拟Bean创建的例子
1. 类含义
BeanDefinition
- 类定义,为Bean创建提供一些定义类的信息。实现类如下:RootBeanDefinition
- 类定义信息,包含有父子关系的BeanDefinition。是常用的实例化BeanDefinition。
BeanWrapper
- 封装Bean,包含有实例化的Bean、Bean类、属性描述集合。一般用来做属性注入。实现类如下:BeanWrapperImpl
AbstractApplicationContext
- 应用上下文,实现类如下:AnnotationConfigWebApplicationContext
- 使用注解的方式配置Web应用上下文(常用)AnnotationConfigReactiveWebApplicationContext
- 使用注解的方式配置ReactiveWeb应用上下文FileSystemXmlApplicationContext
- 通过本地系统查找XML配置文件来启动的 应用上下文。(略)ClassPathXmlApplicationContext
- 通过编译路径查找XML配置文件来启动的 应用上下文。(略)XmlWebApplicationContext
- 通过XML配置文件来启动的 Web应用上下文。(略)GenericXmlApplicationContext
- 通过XML配置文件配置 应用上下文。(略)StaticWebApplicationContext
- 静态web服务的应用上下文。(略)
BeanFactory
- Bean工厂,负责提供BeanBeanDefinitionRegistry
- BeanDefinition的注册表,用来放置BeanDefinition。BeanUtils
- 里面有很多Bean操作,例如:使用无参构造函数创建Bean:BeanUtils.instantiateClass(beanClass)ConstructorResolver
- 构造函数解析器,用来注入有参的构造函数。有参是一个Bean类,就会从BeanFactory获取该Bean。MutablePropertyValues
- 可变的属性值,用来装载属性名称还有属性值。有点类似Map,但它比Map包含有更多的属性定义信息。一般使用beanWrapper.setPropertyValues(mutablePropertyValues),直接把可变的属性值,注入到Bean中。*PostProcessor
- 后置处理程序,用于操作的前后事件等。
2. Bean创建过程 - 流程图
忽略了很多中间的判定操作。
这里只记录扩展点,方便以后做扩展。
3. 例子
3.1. 可变属性注入到实体中
package org.springframework.beans.factory.support;
import org.springframework.beans.BeanWrapper;
import org.springframework.beans.BeanWrapperImpl;
import org.springframework.beans.MutablePropertyValues;
public class MutablePropertyValuesTest {
// 可变属性注入到实体中。
public static void main(String[] args) {
MutablePropertyValues mutablePropertyValues = new MutablePropertyValues();
mutablePropertyValues.addPropertyValue("name", "tavion");
mutablePropertyValues.addPropertyValue("age", 1);
BeanWrapper beanWrapper = new BeanWrapperImpl(PropertyBean.class);
beanWrapper.setPropertyValues(mutablePropertyValues);
System.out.println(beanWrapper.getPropertyValue("name"));//输出:tavion
System.out.println(((PropertyBean)beanWrapper.getWrappedInstance()).getName());//输出:tavion
System.out.println(beanWrapper.getPropertyValue("age"));//输出:1
System.out.println(((PropertyBean)beanWrapper.getWrappedInstance()).getAge());//输出:1
}
}
class PropertyBean{
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
3.2. 模拟Bean创建的例子
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeanWrapper;
import org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.config.SmartInstantiationAwareBeanPostProcessor;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.GenericApplicationContext;
import org.springframework.util.ClassUtils;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
@Slf4j
public class BeanCreateTest {
public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
// 0. 参数初始化
Object bean = null;//实例化后的Bean
Class<?> beanClass = BeanTest1.class;//要实例化的Bean类
String beanName = ClassUtils.getShortName(beanClass);//要实例化的Bean名称
// 1. 创建Context 上下文和BeanFactory
AbstractApplicationContext context = new GenericApplicationContext();
DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) context.getBeanFactory();
// 2. 配置TestUser和TestOrg的BeanDefinition
RootBeanDefinition mbd = new RootBeanDefinition(beanClass);
beanFactory.registerBeanDefinition(BeanTest2.class.getName(),new RootBeanDefinition(BeanTest2.class));
beanFactory.registerBeanDefinition(beanName,mbd);
// 3. 注册 BeanPostProcessor
registerAutowiredAnnotationBeanPostProcessor(context);
// 4. 检索构造方法,通过有参构造方法创建Bean
// tip:这里我只是把beanFactory.getBean()里面的操作,简写重复写一遍。
for (SmartInstantiationAwareBeanPostProcessor beanPostProcessor : beanFactory.getBeanPostProcessorCache().smartInstantiationAware) {
// AutowiredAnnotationBeanPostProcessor beanPostProcessor = new AutowiredAnnotationBeanPostProcessor();
Constructor<?>[] ctors = beanPostProcessor.determineCandidateConstructors(beanClass, beanName);
if (ctors != null) {
log.info("1. 通过构造方法的方式创建Bean:"+beanName);
// 得到构造参数,注入属性,若是Bean类,则会通过beanFactory.getBean() 方式得到传参值。getBean如果没有,则创建新的Bean
BeanWrapper beanWrapper = new ConstructorResolver(beanFactory)
.autowireConstructor(beanName, mbd, ctors, null);
bean = beanWrapper.getWrappedInstance();
if(bean!=null){
break;
}
}
}
// 5. 通过无参构造方法创建Bean
if(bean==null){
log.info("2. 通过无构造方法的方式创建Bean");
bean = BeanUtils.instantiateClass(beanClass);
}
// 6. 打印实例化后的Bean
System.out.println(bean);
}
private static void registerAutowiredAnnotationBeanPostProcessor(AbstractApplicationContext context) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory)context.getBeanFactory();
// 1. 加入 AutowiredAnnotationBeanPostProcessor 后置处理器
beanFactory.registerBeanDefinition(AutowiredAnnotationBeanPostProcessor.class.getName(),
new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class));
// 2. AutowiredAnnotationBeanPostProcessor 加入到缓存中,待后续执行
// 2.1. context.invokeBeanFactoryPostProcessors(beanFactory);// 因为是protected修饰的方法,所以我们在这里需要用反射方式调用
Method method = AbstractApplicationContext.class.getDeclaredMethod("invokeBeanFactoryPostProcessors", ConfigurableListableBeanFactory.class);
method.setAccessible(true);
method.invoke(context, beanFactory);
// 2.2。 context.registerBeanPostProcessors(beanFactory);// 因为是protected修饰的方法,所以我们在这里需要用反射方式调用
Method method2 = AbstractApplicationContext.class.getDeclaredMethod("registerBeanPostProcessors", ConfigurableListableBeanFactory.class);
method2.setAccessible(true);
method2.invoke(context, beanFactory);
}
}
class BeanTest1 {
private BeanTest2 beanTest2;
public BeanTest1(BeanTest2 beanTest2) {
this.beanTest2 = beanTest2;
}
}
class BeanTest2 {
}