其实这篇博文写的很粗糙,主要是记录一下分析源码的过程,我觉得最重要的还是用debug去跟一次
对象从创建到注入到容器的过程,Spring做了什么事。
其实做了蛮多事的,有的基本上看不懂。
其实也可以借鉴组件化思想,Spring是个IOC容器,我们注入的对象就是组件
而组件就存在生命周期,初始化和销毁,以及相互继承和引用等关系。
两大图,图片来自于
https://javadoop.com/post/spring-ioc#BeanFactory%20%E7%AE%80%E4%BB%8B
BeanFactory 管理容器中所有bean的工厂
Object getBean(String name) throws BeansException;
获得注册好的bean对象
boolean isSingleton(String name) throws NoSuchBeanDefinitionException;
是否是单例对象
NoSuchBeanDefinitionException这个异常恐怕是耳闻熟详,
一般情况就是容器中不存在这个bean,而你使用配置文件或者注解将它注入,导致找不到这个bean 。或者是单例模式下存在不唯一的bean
ListableBeanFactory 列出所有在容器中注册的bean
获取到所有在容器中注册的bean的名称
String[] getBeanDefinitionNames();
获取指定注解所有的 Bean 的名称
String[] getBeanNamesForAnnotation(Class<? extends Annotation> annotationType);
获取到指定注解的所有bean的集合
Map<String, Object> getBeansWithAnnotation(Class<? extends Annotation> annotationType) throws BeansException;
总而言之这个接口实现按照不同条件获取bean名称或者bean集合功能的
HierarchicalBeanFactory 分层 bean工厂接口
获得父级bean工厂
BeanFactory getParentBeanFactory();
通过bean名称判断本地bean工厂是否包含该bean对象
boolean containsLocalBean(String name);
总而言之,这个接口就是对多个bean工厂设置父子关系,实现分层的功能
AutowireCapableBeanFactory自动装配bean工厂
根据类对象创建对应的bean对象(创建bean对象的实例)
<T> T createBean(Class<T> beanClass) throws BeansException;
将已存在的bean对象自动装配到容器中
void autowireBean(Object existingBean) throws BeansException;
这里我补充一下,我们传统程序设计,A对象需要用到B对象,都是直接在A类中直接new B对象,这就造成耦合,而IOC容器就是帮我们解决这个问题,所有对象的创建都由IOC完成,我们只需要配置一下就可以使用了,无非就是xml配置文件和注解方式进行注入。
这两个方法应该就是实现该过程的一部分。
自动装配bean
Object configureBean(Object existingBean, String beanName) throws BeansException;
这个方法估计就是@Configuration和@Bean注解的实现了。
初始化bean对象
Object initializeBean(Object existingBean, String beanName) throws BeansException;
在bean对象之前做一些事情
Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
throws BeansException;
在bean对象初始化之后做一些事
Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException;
ApplicationContext上下文对象,重点中的重点
为什么它这么牛逼?
继承了这么接口,你说功能丰不丰富
EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory,
MessageSource, ApplicationEventPublisher, ResourcePatternResolver
对于想要拥有自动装配能力,并且想把这种能力暴露给外部应用的BeanFactory类需要实现此接口。
正常情况下,不要使用此接口,应该更倾向于使用BeanFactory或者ListableBeanFactory接口。此接口主要是针对框架之外,没有向Spring托管Bean的应用。通过暴露此功能,Spring框架之外的程序,具有自动装配等Spring的功能
AutowireCapableBeanFactory getAutowireCapableBeanFactory() throws IllegalStateException;
ConfigurableBeanFactory 可配置的bean工厂
配置bean对象的作用域
String SCOPE_SINGLETON = "singleton";
String SCOPE_PROTOTYPE = "prototype";
设置类的加载类,用来加载类。
void setBeanClassLoader(ClassLoader beanClassLoader);
返回该bean对象的加载类
ClassLoader getBeanClassLoader();
添加一个用于处理bean组件初始化之前或者之后操作的后置处理器
void addBeanPostProcessor(BeanPostProcessor beanPostProcessor);
AbstractBeanFactory 抽象bean工厂
一看这么多就知道这个抽象类功能是有多么丰富了。。
说几个重要的方法
首先这个方法熟悉的不能再熟悉了吧,通过名称获取bean对象(单例)
@Override
public Object getBean(String name) throws BeansException {
return doGetBean(name, null, null, false);
}
通过id名称和类型来获取bean对象
@Override
public <T> T getBean(String name, Class<T> requiredType) throws BeansException {
return doGetBean(name, requiredType, null, false);
}
这个方法就比较重要了,自己跟着源码走一波吧。。
其实就是获取bean对象的过程,要经过一系列的校验和判断
protected <T> T doGetBean(
final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)
throws BeansException
创建bean对象才是核心方法,实现原理是java反射。
protected abstract Object createBean(String beanName, RootBeanDefinition mbd, Object[] args)
throws BeanCreationException;
我反正跟着跟着就跟崩了。。
AbstractAutowireCapableBeanFactory
抽象自动装配bean工厂
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory
implements AutowireCapableBeanFactory
也就是AbstractBeanFactory和AutowireCapableBeanFactory的综合实现
这些方法都是用来创建和填充类的实例
@Override
@SuppressWarnings("unchecked")
public <T> T createBean(Class<T> beanClass) throws BeansException {
// Use prototype bean definition, to avoid registering bean as dependent bean.
使用原型bean定义,避免将bean注册为依赖bean
就是我们可能存在这么一种情况,当需要两个bean相互协作时,例如beanA是beanB的属性,那么当bean的生命周期不同时,就容易出现问题
不过这段代码是实现多例模式下创建bean的过程,返回的应该是bean的类而不是bean的一个实例。
RootBeanDefinition bd = new RootBeanDefinition(beanClass);
bd.setScope(SCOPE_PROTOTYPE);
bd.allowCaching = ClassUtils.isCacheSafe(beanClass, getBeanClassLoader());
return (T) createBean(beanClass.getName(), bd, null);
}
@Override
public void autowireBean(Object existingBean) {
// Use non-singleton bean definition, to avoid registering bean as dependent bean.
使用非单例bean定义,避免注册为依赖bean
RootBeanDefinition bd = new RootBeanDefinition(ClassUtils.getUserClass(existingBean));
bd.setScope(BeanDefinition.SCOPE_PROTOTYPE);
bd.allowCaching = ClassUtils.isCacheSafe(bd.getBeanClass(), getBeanClassLoader());
BeanWrapper bw = new BeanWrapperImpl(existingBean);
initBeanWrapper(bw);
populateBean(bd.getBeanClass().getName(), bd, bw);
}
@Override
public Object configureBean(Object existingBean, String beanName) throws BeansException {
markBeanAsCreated(beanName);
BeanDefinition mbd = getMergedBeanDefinition(beanName);
RootBeanDefinition bd = null;
if (mbd instanceof RootBeanDefinition) {
RootBeanDefinition rbd = (RootBeanDefinition) mbd;
bd = (rbd.isPrototype() ? rbd : rbd.cloneBeanDefinition());
}
if (!mbd.isPrototype()) {
if (bd == null) {
bd = new RootBeanDefinition(mbd);
}
bd.setScope(BeanDefinition.SCOPE_PROTOTYPE);
bd.allowCaching = ClassUtils.isCacheSafe(ClassUtils.getUserClass(existingBean), getBeanClassLoader());
}
BeanWrapper bw = new BeanWrapperImpl(existingBean);
initBeanWrapper(bw);
populateBean(beanName, bd, bw);
return initializeBean(beanName, existingBean, bd);
}
跟一波源码吧
ConfigurableListableBeanFactory
配置列出所有bean的工厂接口
说白了就是注解实现方式,加上自身的8个方法,一共有83个方法实现,
public interface ConfigurableListableBeanFactory
extends ListableBeanFactory, AutowireCapableBeanFactory, ConfigurableBeanFactory {
根据bean的名称返回bean的定义
BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;
@Override
public BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException {
BeanDefinition bd = this.beanDefinitionMap.get(beanName);
if (bd == null) {
if (logger.isTraceEnabled()) {
logger.trace("No bean named '" + beanName + "' found in " + this);
}
throw new NoSuchBeanDefinitionException(beanName);
}
return bd;
}
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<String, BeanDefinition>(256);
ConcurrentHashMap这个map关注一下,线程安全
DefaultListableBeanFactory默认可列出所有bean的工厂类
这个类可以说是最最最常见的类
https://blog.csdn.net/pengjx2014/article/details/83045333#DefaultListableBeanFactory_1
具体内容见这篇文档,不过你看了基本上也不会想看第二遍了。