文章预览
在开始源码分析之前,share一下Spring IOC的流程图:【
Spring IOC(1)流程图
】
Spring通过BeanDefinition将配置文件中的<bean>配置信息转换为容器的内部表示,并将这些BeanDefiniton注册到BeanDefinitonRegistry中。Spring容器的BeanDefinitionRegistry就像是Spring配置信息的内存数据库,主要是以map的形式保存,后续操作直接从BeanDefinitionRegistry中读取配置信息(
DefaultListableBeanFactory是实现类,内部通过beanDefinitionMap保存BeanDefinition
)。
比如上一篇文章的代码,通过ClassPathResource读取配置文件,然后通过BeanDefinitionReader将BeanDefinition加载并注册到DefaultListableBeanFactory中。
ClassPathResource classPathResource = new ClassPathResource("applicationContext.xml");
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
BeanDefinitionReader reader = new XmlBeanDefinitionReader(beanFactory);
reader.loadBeanDefinitions(classPathResource);
Student student = (Student) beanFactory.getBean("student");
System.out.println(student.getName());
同样在ApplicationContext中也是这样的逻辑:
loadBeanDefinitions则是通过模板方法模式,由子类实现是从xml还是通过Annotation获取BeanDefinition,不过大体逻辑还是一样,通过BeanDefinitionReader关联BeanFactory和读取的BeanDefinition。
在refresh()方法中,通过obtainFreshBeanFactory获得BeanFactory
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
refreshBeanFactory();
return getBeanFactory();
}
//这里真正的创建BeanFactory,并且加载BeanDefinition
protected final void refreshBeanFactory() throws BeansException {
if (hasBeanFactory()) {
destroyBeans();
closeBeanFactory();
}
try {
//创建BeanFactory
DefaultListableBeanFactory beanFactory = createBeanFactory();
beanFactory.setSerializationId(getId());
customizeBeanFactory(beanFactory);
//加载BeanDefinition
loadBeanDefinitions(beanFactory);
synchronized (this.beanFactoryMonitor) {
this.beanFactory = beanFactory;
}
}
catch (IOException ex) {
throw new ApplicationContextException("I/O error parsing
bean definition source for " + getDisplayName(), ex);
}
}
//AbstractXmlApplicationContext实现的loadBeanDefinitions,从xml中读取BeanDefinition
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException,
IOException {
// Create a new XmlBeanDefinitionReader for the given BeanFactory.
XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
beanDefinitionReader.setEnvironment(this.getEnvironment());
beanDefinitionReader.setResourceLoader(this);
beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));
initBeanDefinitionReader(beanDefinitionReader);
loadBeanDefinitions(beanDefinitionReader);
}
BeanDefinition
BeanDefinition是一个接口类型,提供以下功能:
-
bean的描述信息(Scope单例还是原型bean,Lazy懒加载,是不是抽象abstract)
-
依赖类类名(String[] dependOn)
-
自动装配的相关信息(AutowireCandidate,Primary)
-
init函数,destroy函数的名字(String类型)
-
factoryBean的名字以及FactoryMethod
-
构造函数形参的值(ConstructorArgumentValues)
-
Bean的属性以及对应的值(MutablePropertyValues)
public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement {
//单例模式
String SCOPE_SINGLETON = ConfigurableBeanFactory.SCOPE_SINGLETON;
//原型模式
String SCOPE_PROTOTYPE = ConfigurableBeanFactory.SCOPE_PROTOTYPE;
//返回当前BeanDefinition的Parent Definition
String getParentName();
//设置当前BeanDefinition所属class name
void setBeanClassName(@Nullable String beanClassName);
//获得bean所属class name
String getBeanClassName();
//设置Scope是单例还是原型
void setScope(@Nullable String scope);
//获取Scope
String getScope();
//设置bean是否被懒加载
void setLazyInit(boolean lazyInit);
//判断bean是否是懒加载
boolean isLazyInit();
//设置bean初始化时depend on的bean的name
void setDependsOn(@Nullable String... dependsOn);
//获取这个bean所depend on的bean数组
String[] getDependsOn();
//设置当前bean是不是一个被Autowired到别的bean的候选bean
void setAutowireCandidate(boolean autowireCandidate);
//查看这个bean是不是Autowired到别的bean的候选bean
boolean isAutowireCandidate();
// 设置这个bean是primary autowire candidate
void setPrimary(boolean primary);
//这个bean是不是primary autowire candidate
boolean isPrimary();
//如果需要FactoryBean的话,指定FactoryBean的名字
void setFactoryBeanName(@Nullable String factoryBeanName);
//获取Factorybean的名字
String getFactoryBeanName();
//设置FactoryMethod,可以被factoryBean使用
void setFactoryMethodName(@Nullable String factoryMethodName);
//获取FactoryMethod
String getFactoryMethodName();
//返回构造函数参数
ConstructorArgumentValues getConstructorArgumentValues();
//是否有构造函数参数
default boolean hasConstructorArgumentValues() {
return !getConstructorArgumentValues().isEmpty();
}
//返回property相关值
MutablePropertyValues getPropertyValues();
//是否有property值定义
default boolean hasPropertyValues() {
return !getPropertyValues().isEmpty();
}
//设置initializer method
void setInitMethodName(@Nullable String initMethodName);
//返回initializer method
String getInitMethodName();
//设置destroy method
void setDestroyMethodName(@Nullable String destroyMethodName);
//获取destroy method
String getDestroyMethodName();
//设置role
void setRole(int role);
//获取role
int getRole();
//设置description
void setDescription(@Nullable String description);
//获取description
String getDescription();
// Read-only attributes
//判断是不是单例bean
boolean isSingleton();
//判断是不是原型bean
boolean isPrototype();
//判断bean是不是abstract的
boolean isAbstract();
//获取资源的description
String getResourceDescription();
//获取originating BeanDefinition
BeanDefinition getOriginatingBeanDefinition();
}
针对于该接口,提供了AbstractBeanDefinition这样一个抽象类,在该类中提供了上述set方法所对应的变量,以及实现。
private volatile Object beanClass;
private String scope = SCOPE_DEFAULT;
private boolean abstractFlag = false;
private boolean lazyInit = false;
private int autowireMode = AUTOWIRE_NO;
private int dependencyCheck = DEPENDENCY_CHECK_NONE;
private String[] dependsOn;
private boolean autowireCandidate = true;
private boolean primary = false;
private final Map<String, AutowireCandidateQualifier> qualifiers = new LinkedHashMap<>();
private Supplier<?> instanceSupplier;
private boolean nonPublicAccessAllowed = true;
private boolean lenientConstructorResolution = true;
private String factoryBeanName;
private String factoryMethodName;
private ConstructorArgumentValues constructorArgumentValues;
private MutablePropertyValues propertyValues;
private MethodOverrides methodOverrides;
private String initMethodName;
private String destroyMethodName;
private boolean enforceInitMethod = true;
private boolean enforceDestroyMethod = true;
private boolean synthetic = false;
private int role = BeanDefinition.ROLE_APPLICATION;
@Nullable
private String description;
@Nullable
private Resource resource;
那么最终实现类RootBeanDefinition是比较常用的一种,内部提供了BeanDefinitionHolder来保存BeanDefinition和beanName。
BeanDefinition实例
因为XML比较直观,所以这里主要通过XML的形式配置bean,后面再整理基于Annotation方式的。
从上图可以看出<bean>标签内可以定义这些内容,最终都会解析到BeanDefinition的属性中。
运行时修改BeanDefinition定义
一般情况下,BeanDefinition只在容器启动时加载并解析,除非容器刷新或重启,这些信息不会发生变化,当然如果用户有特殊的需求,也可以通过编程的方式在运行期调整BeanDefinition的定义。
public class BeanDefinitionPostProcessor implements BeanDefinitionRegistryPostProcessor {
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
BeanDefinition student = registry.getBeanDefinition("student");
student.getPropertyValues().getPropertyValue("name").setConvertedValue("Test");
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
BeanDefinition student = beanFactory.getBeanDefinition("student");
student.getPropertyValues().getPropertyValue("name").setConvertedValue("Test1");
//通过转换成DefaultListableBeanFactory来registerBeanDefinition
((DefaultListableBeanFactory) beanFactory).registerBeanDefinition("test" ,student);
}
}
如上述代码,BeanDefinitionRegistryPostProcessor继承了BeanFactoryPostProcessor,所以它会有两个方法,如果只是获取BeanDefinition并更新,那么BeanFactoryPostProcessor也能够操作,
且BeanFactoryPostProcessor还提供注册新的BeanDefinition,但是需要将ConfigurableListableBeanFactory强制转换成DefaultListableBeanFactory。
在AbstractApplicationContext中,提供了addBeanFactoryPostProcessor(new BeanDefinitionPostProcessor());且在refresh()方法里会通过invokeBeanFactoryPostProcessors(beanFactory)来调用BeanFactoryPostProcessor。
………………………………