Spring IoC 主要是以下几个步骤。

  1. 初始化 IoC 容器。
  2. 读取配置文件。
  3. 将配置文件转换为容器识别对的数据结构(这个数据结构在Spring中叫做 BeanDefinition)
  4. 利用数据结构依次实例化相应的对象
  5. 注入对象之间的依赖关系

BeanFactory工厂类接口

public interface BeanFactory {
    //根据类名获得bean
    Object getBean(String beanName,BeanScope beanScope);
    Object getBean(String name);
    //根据类对象获得bean
    Object getBean(Class<?> cls,BeanScope beanScope);
    Object getBean(Class<?> cls);
    //设置bean
    void setBean(String name, Object obj);
    void setBean(Class<?> cls, Object obj);
    //刷新Bean工厂
    void refresh()throws Exception;
    //Bean工厂是否为空
    boolean isEmpty();
}

BeanScope是bean的作用域常量

public enum  BeanScope {
    //单例模式,只有一个实例
    //原型模式,每次通过容器getbean都会产生一个新的bean实例
    SINGLETON,
    PROTOTYPE
}

BeanDefinition(bean的定义类)

bean的各项属性

public interface BeanDefinition {
    //获得类对象
    Class<?> getBeanClass();
    //设置类对象
    void setBeanClass(Class<?> cls);
    //获得作用域
    BeanScope getScope();
    //是否单例
    boolean isSingleton();
    //是否原型
    boolean isPrototype();
    //是否需要代理
    boolean getIsProxy();
    //设置是否需要代理
    void setIsProxy(boolean isProxy);
    //获得代理类
    MyProxy getProxy();
    //设置代理类
    void setProxy(MyProxy myProxy);
    //获得初始化方法名
    String getInitMethodName();
}

BeanDefinitionRegistry

将bean的定义信息BeanDefinition注册到BeanDefinition容器中

这里的注册 Bean 是指将 Bean 定义成 BeanDefinition,之后放入 Spring 容器中,就是拆分的意思

我们常说的容器其实就是 Beanfactory 中的一个 Map,key 是 Bean 的名称,value 是 Bean 对应的 BeanDefinition

public class BeanDefinitionRegistry {
    //BeanDefinition容器
    private static Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>();

    //将bean注册进容器(map)
    public static void registryBeanDefinition(String beanName,BeanDefinition beanDefinition{
        //判空
        Objects.requireNonNull(beanName, "beanName 不能为空");
        Objects.requireNonNull(beanDefinition, "beanDefinition 不能为空");
        beanDefinitionMap.put(beanName, beanDefinition);
    }

    //根据类名className获取BeanDefinition
    public static BeanDefinition getBeanDefinition(String className){
        return beanDefinitionMap.get(className);
    }

    //判断BeanDefinition是否存在
    public static boolean containsBeanDefinition(String className) {
        return beanDefinitionMap.containsKey(className);
    }

    //获得BeanDefinition容器
    public static Map<String,BeanDefinition> getBeanDefinitionMap() {
        return beanDefinitionMap;
    }
}

GenericBeanDefinition(用于标准bean定义)

public class GenericBeanDefinition implements BeanDefinition{

    private Class<?> beanClass;

    private BeanScope scope =BeanScope.SINGLETON;

    private String initMethodName;

    private boolean isProxy = false;

    private MyProxy myProxy = null;


    public void setBeanClass(Class<?> beanClass){
        this.beanClass = beanClass;
    }

    public void setScope(BeanScope scope) {
        this.scope = scope;
    }

    public void setInitMethodName(String initMethodName) {
        this.initMethodName = initMethodName;
    }

    @Override
    public Class<?> getBeanClass() {
        return beanClass;
    }

    @Override
    public BeanScope getScope() {
        return scope;
    }

    @Override
    public boolean isSingleton() {
        return Objects.equals(scope,BeanScope.SINGLETON);
    }

    @Override
    public boolean isPrototype() {
        return Objects.equals(scope, BeanScope.PROTOTYPE);
    }

    @Override
    public String getInitMethodName() {
        return initMethodName;
    }

    @Override
    public MyProxy getProxy() {
        // TODO Auto-generated method stub
        return myProxy;
    }

    @Override
    public void setProxy(MyProxy myProxy) {
        // TODO Auto-generated method stub
        this.myProxy = myProxy;
    }

    @Override
    public boolean getIsProxy() {
        // TODO Auto-generated method stub
        return isProxy;
    }

    @Override
    public void setIsProxy(boolean isProxy) {
        // TODO Auto-generated method stub
        this.isProxy=isProxy;
    }
}

实现bean工厂接口

public class DefaultBeanFactory implements BeanFactory {
    //bean工厂单例
    private static volatile DefaultBeanFactory instance = null;
    //一级缓存Bean容器,IOC容器,直接从此处获取Bean
    private static Map<String, Object> singletonObjects = new ConcurrentHashMap<>();
    //二级缓存,为了将完全地Bean和半成品的Bean分离,避免读取到不完整的Bean
    private static Map<String,Object> earlySingletonObjects=new ConcurrentHashMap<>();
    //三级缓存,值为一个对象工厂,可以返回实例对象
    private static Map<String,ObjectFactory> singletonFactories=new ConcurrentHashMap<>();
    //是否在创建中
    private static Set<String> singletonsCurrennlyInCreation = new HashSet<>();

    //Bean的注册信息BeanDefinition容器
    private static Map<String, BeanDefinition> beanDefinitionMap = BeanDefinitionRegistry.getBeanDefinitionMap();

}

初始化bean

//初始化bean
static {
    ///获得被Component,Service,Controller注解的类对象集合
    Set<Class<?>> beanClassSet = ClassSetHelper.getBeanClassSet();
    if(beanClassSet!=null && !beanClassSet.isEmpty()) {
        try {
            for(Class<?> beanClass : beanClassSet) {
                GenericBeanDefinition genericBeanDefinition = new GenericBeanDefinition();
                genericBeanDefinition.setBeanClass(beanClass);
                BeanDefinitionRegistry.registryBeanDefinition(beanClass.getName(), genericBeanDefinition);
            }
            //注册配置的bean
            getInstance().initConfigBean();
            //注册其他所有的bean
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

ClassSetHelper.getBeanClassSet()

//获得被Component,Service,Controller注解的类对象集合
public static Set<Class<?>> getBeanClassSet() {
    Set<Class<?>> beanClassSet = new HashSet<Class<?>>();
    beanClassSet.addAll(getServiceClassSet());
    beanClassSet.addAll(getControllerClassSet());
    beanClassSet.addAll(getComponentClassSet());
    return beanClassSet;
}

获取单例bean工厂

public static DefaultBeanFactory getInstance(){
    if (null == instance){
        synchronized (DefaultBeanFactory.class){
            if (null == instance){
                instance=new DefaultBeanFactory();
                return instance;
            }
        }
    }
    return instance;
}

根据类名获取bean

public Object getBean(String beanName) {
    Object bean = null;
    try {
        bean=doGetBean(beanName,BeanScope.SINGLETON);
    } catch (Exception e) {
        e.printStackTrace();
    }
    return bean;
}

根据类的class对象获取bean

public Object getBean(Class<?> cls) {
    Object bean = null;
    try {
        bean=doGetBean(cls.getName(),BeanScope.SINGLETON);
    } catch (Exception e) {
        e.printStackTrace();
    }
    return bean;
}

其中doGetBean指从beanMap获取bean,不存在就实例一个

同时加入三级缓存

private Object doGetBean(String beanName,BeanScope beanScope) throws Exception {
    Objects.requireNonNull(beanName, "beanName 不能为空");
    //获取单例
    Object bean = getSingleton(beanName);
    if(bean != null) {
        return bean;
    }
    //如果未获取到bean,且bean不在创建中,则置bean的状态为在创建中
    if(!singletonsCurrennlyInCreation.contains(beanName)) {
        singletonsCurrennlyInCreation.add(beanName);
    }
    BeanDefinition beanDefinition = beanDefinitionMap.get(beanName);
    if(beanDefinition==null) {
        throw new Exception("不存在 "+beanName+" 的定义");
    }

    //获得类对象
    Class<?> beanClass = beanDefinition.getBeanClass();
    //找到实现类
    beanClass = findImplementClass(beanClass,null);
    //判断是否需要代理,若需要则生成代理类
    if(beanDefinition.getIsProxy() && beanDefinition.getProxy()!=null) {
        MyProxy myProxy = beanDefinition.getProxy();
        bean=myProxy.getProxy(beanClass);
    }
    else {
        bean = beanClass.getDeclaredConstructor().newInstance();
    }
    //将实例化后,但未注入属性的bean,放入三级缓存中
    final Object temp = bean;
    singletonFactories.put(beanName, new ObjectFactory() {
        @Override
        public Object getObject(){
            return temp;
        }
    });
    //反射调用init方法(获得初始化方法名)
    String initMethodName = beanDefinition.getInitMethodName();
    if (initMethodName != null){
        Method method = beanClass.getMethod(initMethodName, null);
        //方法调用
        method.invoke(bean,null);

    }

    //注入bean的属性
    fieldInject(beanClass, bean, false);
    //如果三级缓存存在bean,则拿出放入二级缓存中
    if(singletonFactories.containsKey(beanName)) {
        ObjectFactory factory  = singletonFactories.get(beanName);
        earlySingletonObjects.put(beanName, factory.getObject());
        singletonFactories.remove(beanName);
    }
    //如果二级缓存存在bean,则拿出放入一级缓存中
    if(earlySingletonObjects.containsKey(beanName)) {
        bean = earlySingletonObjects.get(beanName);
        singletonObjects.put(beanName, bean);
        earlySingletonObjects.remove(beanName);
    }
    return bean;

}

设置bean

@Override
public void setBean(String beanName, Object obj) {
    try {
        Objects.requireNonNull(beanName, "beanName 不能为空");
        singletonObjects.put(beanName, obj);
    } catch (Exception e) {
        // TODO: handle exception
        e.printStackTrace();
    }
}

@Override
public void setBean(Class<?> cls, Object obj) {
    this.setBean(cls.getName(), obj);
}

可以建立一个ClassSetHelper来扫描有某注解的类,并放进集合

//获取基础包名下直接或间接带有某注解的所有类
public static Set<Class<?>> getClassSetByInheritedAnnotation(Class<? extends Annotation> present){
    Set<Class<?>> classSet = new HashSet<Class<?>>();
    for (Class<?> cls : CLASS_SET) {
        if(isAnnoPresent(cls,present)){
            classSet.add(cls);
        }
    }
    return classSet;
}

例如注入@Configuration中配置bean

private void initConfigBean() throws Exception {
    Set<Class<?>> configClassSet = ClassSetHelper.getClassSetByInheritedAnnotation(Configuration.class);
    if(configClassSet==null || configClassSet.isEmpty()) {
        return;
    }
    for(Class<?> configClass : configClassSet) {
        //注册Configuration
        GenericBeanDefinition genericBeanDefinition = new GenericBeanDefinition();
        genericBeanDefinition.setBeanClass(configClass);
        BeanDefinitionRegistry.registryBeanDefinition(configClass.getName(), genericBeanDefinition);
        Object configBean = getBean(configClass);
        Method[] methods = configClass.getDeclaredMethods();
        for(Method method:methods) {
            if(method.isAnnotationPresent(Bean.class)) {
                Class<?> returnClass = method.getReturnType();
                Object bean = method.invoke(configBean);
                String keyName = returnClass.getName();
                singletonObjects.put(keyName, bean);
                System.out.println("成功注入"+configClass.getName()+" 中的  "+returnClass.getName());
            }

        }
        singletonObjects.remove(configClass.getName());
    }
}

自定义注解

例如@Value

@Retention(RUNTIME)
@Target(FIELD)
public @interface Value {
    //默认值
    String value() default "";
}

如果注解中只有一个元素且元素名字为 value,那么在使用这个注解的时候,元素的名字和等号都可以省略

@Documented

指明修饰的注解,可以被例如javadoc此类的工具文档化,只负责标记,没有成员取值

@Retention()

  • 指明修饰的注解的生存周期,即会保留到哪个阶段
  • SOURCE:源码级别保留,编译后即丢弃。
  • CLASS:编译级别保留,编译后的class文件中存在,在jvm运行时丢弃,这是默认值。
  • RUNTIME: 运行级别保留,编译后的class文件中存在,在jvm运行时保留,可以被反射调用

@Target({ FIELD, LOCAL_VARIABLE })

指明了修饰的这个注解的使用范围

  • TYPE:类,接口或者枚举
  • FIELD:域,包含枚举常量
  • METHOD:方法
  • PARAMETER:参数
  • CONSTRUCTOR:构造方法
  • LOCAL_VARIABLE:局部变量
  • ANNOTATION_TYPE:注解类型
  • PACKAGE:包

从缓存中获取单例bean

private Object getSingleton(String beanName){
    //若一级缓存有bean,直接返回
    Object bean = singletonObjects.get(beanName);
    if (bean!=null){
        return bean;
    }
    //如果一级缓存不存在bean,且bean在创建中,则从二级缓存中拿出半成品bean返回,否则从三级缓存拿出放入二级缓存中
    if (singletonsCurrennlyInCreation.contains(beanName)){
        bean = earlySingletonObjects.get(beanName);
        if (bean == null){
            ObjectFactory factory = singletonFactories.get(beanName);
            if (factory != null){
                bean = factory.getObject();
                earlySingletonObjects.put(beanName, bean);
                singletonFactories.remove(beanName);
            }
        }
    }
    return bean;

}