撸了一遍明白为什么用封装一个ApplicationContext了, 里面很多的方法继承下来, 要去调用都一脸懵逼.

所以哦豁,又顿悟了一下为什么很多抽象类的那些实现好的方法要包保护了, 只给自己的子类去用, 外部是直接调用不到的.

就需要ApplicationContext去封装,把这些实现的方法开放出去.

先看一下整个流程之间类的关系, 这个也叫 类图

spring获取profile_实例化

补充一下这些符号的说明

  • List item
  • -: private
  • +: public
  • ~: default
  • #: protected
  • 下划线: static
  • 斜体: 抽象类或方法(两个<<尖括号包起来也算)

冒号前有括号是方法名,反之变量名,冒号后是返回值,没有返回值可以直接连冒号一起省略

然后把这些类先创建好,简单归个类

spring获取profile_spring_02


然后上代码

BeanFactory

第一步还是BeanFactory,还是先这么简单

public interface BeanFactory {
    Object getBean(String name);
}

BeansException

专门抛Bean工厂中一些异常信息

public class BeansException extends NestedRuntimeException {

    public BeansException(String msg) {
        super(msg);
    }
}

BeanDefinition

然后上一篇我们讲过的, 是通过BeanDefinition只用来存储Bean的信息

@Data
public class BeanDefinition {

    private Class beanClass;

    //这里升级为只传类型,而不是实例 在需要的时候自己去实例
    public BeanDefinition(Class beanClass){
        this.beanClass=beanClass;
    }
}

单例注册接口定义SingletonBeanRegistry

因为上面只是传入了一个class, 所以需要一个能获取实例化对象的方法,开一个接口,让其他人去做实现

public interface SingletonBeanRegistry {

    Object getSingleton(String beanName);
}

单例注册实现DefaultSingletonBeanRegistry

这里就有了一个单例Bean的管理员

这是注册类,补充了一个注册Bean的方法.

public class DefaultSingletonBeanRegistry implements SingletonBeanRegistry {

    private final Map<String,Object> singletonObjects =new HashMap<>();

    /**
     * 实现获取单例的方法
     * @param beanName
     * @return
     */
    @Override
    public Object getSingleton(String beanName) {
        return singletonObjects.get(beanName);
    }

    /**
     * 提供一个包保护的方法 可以被继承此类的其他类调用
     * @param beanName
     * @param singletonObject
     */
    protected void addSingletonBean(String beanName,Object singletonObject){
        singletonObjects.put(beanName, singletonObject);
    }
}

抽象类定义(模板方法)AbstractBeanFactory

有了个获取类的方法,就可以getBean了?

public abstract class AbstractBeanFactory extends DefaultSingletonBeanRegistry implements BeanFactory {

    @Override
    public Object getBean(String beanName){
        //继承自DefaultSingletonBeanRegistry 的方法
        Object bean = getSingleton(beanName);
        if (bean != null){
            return bean;
        }
        //获取不到就两个抽象方法 让实现此类的去做实现
        BeanDefinition beanDefinition = getBeanDefinition(beanName);
        return createBean(beanName,beanDefinition);

    }

    protected abstract BeanDefinition getBeanDefinition(String name) throws BeansException;

    protected abstract Object createBean(String beanName,BeanDefinition bean) throws BeansException;
}

显然还不够,因为前面说了实例化的操作还没整好呢! 所以获取不到类的时候我们就要去实例化类.

但是我不管实现,我只负责获取Bean, 我们分工明确, 我需求提在这里,其他人去帮我实现吧!

这就是模板模式, 我不止定需求,我甚至把这些需求怎么串联起来都定成了一个模板

将核心的调用逻辑在这里定义好, 后续的人不用关心怎么我的方法要怎么去串联, 尽管实现自己的功能就好.

实例化Bean类 AbstractAutowireCapableBeanFactory

这个方法负责创建Bean,另外一个BeanDefinition的事情我就不管了,所以这是一个抽象类,只实现一个抽象方法,上面遗留的另外一个需求,让子类再去实现增强.

public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory{

    @Override
    protected Object createBean(String name, BeanDefinition beanDefinition) throws BeansException {
        Object bean;
        try {
            bean = beanDefinition.getBeanClass().newInstance();
        }catch (InstantiationException | IllegalAccessException e) {
            throw new BeansException("In");
        }
        addSingletonBean(name,bean);
        return bean;
    }
}

前面有Bean的管理类了,但是还没有BeanDefinition的管理类

核心实现类 DefaultListableBeanFactory

然后居然是让这个叫BeanFactory的去管理,我不能理解并且大为震惊.

public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory implements BeanDefinitionRegistry{

    private final Map<String,BeanDefinition> beanDefinitionMap =new HashMap<>();

    @Override
    public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition){
        beanDefinitionMap.put(beanName,beanDefinition);
    }

    @Override
    protected BeanDefinition getBeanDefinition(String name) throws BeansException {
        BeanDefinition beanDefinition = beanDefinitionMap.get(name);
        if (beanDefinition ==null) throw new BeansException("No bean named '"+name+"' is defined") ;
        return beanDefinition;
    }
}

不过现在都已经好了,包括Bean的定义 注册 获取,上测试代码

@Test
public void testBeanFactory(){
    //初始化 beanFactory
    DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
    //创建 bean信息
    BeanDefinition beanDefinition = new BeanDefinition(UserService.class);
    String beanName = "userService";
    //注册到工厂中
    beanFactory.registerBeanDefinition(beanName,beanDefinition);
    //获取实例
    UserService userService = (UserService) beanFactory.getBean(beanName);
    userService.queryUserInfo();
    //第二次再获取应该走单例
    UserService singletonUserService = (UserService)beanFactory.getBean(beanName);

    singletonUserService.queryUserInfo();
    //是否为单例
    System.out.println(userService);
    System.out.println(singletonUserService);
}