撸了一遍明白为什么用封装一个ApplicationContext了, 里面很多的方法继承下来, 要去调用都一脸懵逼.
所以哦豁,又顿悟了一下为什么很多抽象类的那些实现好的方法要包保护了, 只给自己的子类去用, 外部是直接调用不到的.
就需要ApplicationContext去封装,把这些实现的方法开放出去.
先看一下整个流程之间类的关系, 这个也叫 类图
补充一下这些符号的说明
-
List item -
-: private -
+: public -
~: default -
#: protected -
下划线: static -
斜体: 抽象类或方法(两个<<尖括号包起来也算)
冒号前有括号是方法名,反之变量名,冒号后是返回值,没有返回值可以直接连冒号一起省略
然后把这些类先创建好,简单归个类
然后上代码
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);
}
|