spring-framework源码第3弹------Spring IOC 容器的简单实现(学习tiny-spring)
声明:本代码来源于tiny-spring ,感谢原作者的源码
修改后的代码tiny-spring-copy
前言
学习Spring源码之前先学习下微缩版的Spring 框架—–tiny-spring 框架。闲话少说,先从IoC 容器开始。
IoC 的实现流程
- 读取配置文件,获取资源输入流
- 解析Bean,生成Bean的实例,
- 根据依赖注入Bean的实例
读取配置文件
Resource 接口,标识一个外部资源,通过getInputStream()获取资源的输入流
public interface Resource { InputStream getInputStream() throws IOException;
}
- 1
- 2
- 3
- 4
UrlResource 实现Resource接口
public class UrlResource implements Resource { private final URL url; public UrlResource(URL url) { this.url = url; } @Override public InputStream getInputStream() throws IOException{ URLConnection urlConnection = url.openConnection(); urlConnection.connect(); return urlConnection.getInputStream(); }
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
ResourceLoader 接口,加载资源,返回UrlResource 对象
public interface ResourceLoader { /** * @param location * @return */ public Resource getResource(String location);
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
UrlResourceLoader类实现ResourceLoader接口
public class UrlResourceLoader implements ResourceLoader { @Override public Resource getResource(String location){ URL resource = this.getClass().getClassLoader().getResource(location); return new UrlResource(resource); }
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
解析配置文件,获取Bean的定义
- BeanDefinition 实体类,用于存放Bean的定义,包括Bean的内容和属性
public class BeanDefinition { /** * */ private Object bean; /** * Bean的类型 */ private Class beanClass; /** * Bean的名称 */ private String beanClassName; /** * 属性类,内部封装了一个List<PropertyValue> */ private PropertyValues propertyValues = new PropertyValues(); get和set方法省略
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
BeanDefinitionReader解析BeanDefinition接口,通过loadBeanDefinitions(String)从一个地址加载类的定义
public interface BeanDefinitionReader { /** * 从配置中读取BeanDefinition * @param location * @throws Exception */ void loadBeanDefinitions(String location) throws Exception;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
AbstractBeanDefinitionReader
实现BeanDefinitionReader接口的抽象类,未具体实现loadBeanDefinitions(String),主要是规范了BeanDefinitionReader的基本结构,
public abstract class AbstractBeanDefinitionReader implements BeanDefinitionReader { //用于保存String - beanDefinition 的键值对 private Map<String,BeanDefinition> registry; //用于保存类加载器 private UrlResourceLoader resourceLoader; protected AbstractBeanDefinitionReader(UrlResourceLoader resourceLoader) { this.registry = new HashMap<String, BeanDefinition>(); this.resourceLoader = resourceLoader; } public Map<String, BeanDefinition> getRegistry() { return registry; } public UrlResourceLoader getResourceLoader() { return resourceLoader; }
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
XmlBeanDefinitionReader类,具体实现BeanDefinitionReader接口,从配置文件中获取Bean的定义
public class XmlBeanDefinitionReader extends AbstractBeanDefinitionReader { public XmlBeanDefinitionReader(UrlResourceLoader resourceLoader) { super(resourceLoader); } @Override public void loadBeanDefinitions(String location) throws Exception { InputStream inputStream = getResourceLoader().getResource(location).getInputStream(); doLoadBeanDefinitions(inputStream); } protected void doLoadBeanDefinitions(InputStream inputStream) throws Exception { DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilder docBuilder = factory.newDocumentBuilder(); Document doc = docBuilder.parse(inputStream); // 解析bean registerBeanDefinitions(doc); inputStream.close(); } /** * 解析Bean * @param doc */ public void registerBeanDefinitions(Document doc) { Element root = doc.getDocumentElement(); parseBeanDefinitions(root); } /** * 解析Bean * @param root */ protected void parseBeanDefinitions(Element root) { NodeList nl = root.getChildNodes(); for (int i = 0; i < nl.getLength(); i++) { Node node = nl.item(i); if (node instanceof Element) { Element ele = (Element) node; processBeanDefinition(ele); } } } /** * 解析Bean中的id和class,以及其他属性 * @param ele */ protected void processBeanDefinition(Element ele) { String name = ele.getAttribute("id"); String className = ele.getAttribute("class"); BeanDefinition beanDefinition = new BeanDefinition(); //保存属性 processProperty(ele, beanDefinition); //保存类全限定名 beanDefinition.setBeanClassName(className); //将获得的Bean的定义保存到map中 getRegistry().put(name, beanDefinition); } /** * 解析Bean中的property属性 * @param ele * @param beanDefinition */ private void processProperty(Element ele, BeanDefinition beanDefinition) { NodeList propertyNode = ele.getElementsByTagName("property"); for (int i = 0; i < propertyNode.getLength(); i++) { Node node = propertyNode.item(i); if (node instanceof Element) { Element propertyEle = (Element) node; String name = propertyEle.getAttribute("name"); String value = propertyEle.getAttribute("value"); if (value != null && value.length() > 0) { beanDefinition.getPropertyValues().addPropertyValue(new PropertyValue(name, value)); } else { String ref = propertyEle.getAttribute("ref"); if (ref == null || ref.length() == 0) { throw new IllegalArgumentException("Configuration problem: <property> element for property '" + name + "' must specify a ref or value"); } BeanReference beanReference = new BeanReference(ref); beanDefinition.getPropertyValues().addPropertyValue(new PropertyValue(name, beanReference)); } } } }
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
注册生成Bean的实例 以及使用该实例
BeanFactory类,标识一个IoC容器,通过getBean(String)来获取Bean的实例。
public interface BeanFactory { Object getBean(String name) throws Exception;
}
- 1
- 2
- 3
- 4
- 5
AbstractBeanFactory类,BeanFactory的一种抽象实现,规范了IoC容器的基本结构,但是把生成Bean的具体方式留给了子类来实现。
public abstract class AbstractBeanFactory implements BeanFactory { private Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<String, BeanDefinition>(); private final List<String> beanDefinitionNames = new ArrayList<String>(); private List<BeanPostProcessor> beanPostProcessors = new ArrayList<BeanPostProcessor>(); @Override public Object getBean(String name) throws Exception { BeanDefinition beanDefinition = beanDefinitionMap.get(name); if (beanDefinition == null) { throw new IllegalArgumentException("No bean named " + name + " is defined"); } Object bean = beanDefinition.getBean(); //如果bean存在,则返回。否则调用doCreateBean方法装配一个Bean if (bean == null) { bean = doCreateBean(beanDefinition); bean = initializeBean(bean, name); beanDefinition.setBean(bean); } return bean; } /** * 对Bean做初始化 * @param bean * @param name * @return * @throws Exception */ protected Object initializeBean(Object bean, String name) throws Exception { for (BeanPostProcessor beanPostProcessor : beanPostProcessors) { bean = beanPostProcessor.postProcessBeforeInitialization(bean, name); } // TODO:call initialize method for (BeanPostProcessor beanPostProcessor : beanPostProcessors) { bean = beanPostProcessor.postProcessAfterInitialization(bean, name); } return bean; } protected Object createBeanInstance(BeanDefinition beanDefinition) throws Exception { return beanDefinition.getBeanClass().newInstance(); } public void registerBeanDefinition(String name, BeanDefinition beanDefinition) throws Exception { beanDefinitionMap.put(name, beanDefinition); beanDefinitionNames.add(name); } public void preInstantiateSingletons() throws Exception { for (Iterator it = this.beanDefinitionNames.iterator(); it.hasNext();) { String beanName = (String) it.next(); getBean(beanName); } } /** * 创建一个Bean的实例 * @param beanDefinition * @return * @throws Exception */ protected Object doCreateBean(BeanDefinition beanDefinition) throws Exception { Object bean = createBeanInstance(beanDefinition); beanDefinition.setBean(bean); applyPropertyValues(bean, beanDefinition); return bean; } protected void applyPropertyValues(Object bean, BeanDefinition beanDefinition) throws Exception { } public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor) throws Exception { this.beanPostProcessors.add(beanPostProcessor); } public List getBeansForType(Class type) throws Exception { List beans = new ArrayList<Object>(); for (String beanDefinitionName : beanDefinitionNames) { if (type.isAssignableFrom(beanDefinitionMap.get(beanDefinitionName).getBeanClass())) { beans.add(getBean(beanDefinitionName)); } } return beans; }
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
AutowireCapableBeanFactory 可以实现自动装配的 BeanFactory。在这个工厂中,实现了doCreateBean方法,该方法分为三步:1. 通过BeanDefinition中保存的类信息实例化一个对象;2.将对象保存在BeanDefinition中,以备下次获取;3. 为其装配属性。在装配属性时,通过BeanDefinition中维护的PropertyValues集合类,把String-Value键值对注入到Bean的属性中去。如果Value的类型是BeanReference,则说明其是一个引用(对应于XML中的ref),通过getBean对其进行获取,然后注入到属性中。
public class AutowireCapableBeanFactory extends AbstractBeanFactory { /** * 将读取到的property值设置到Bean中 * @param bean * @param mbd * @throws Exception */ protected void applyPropertyValues(Object bean, BeanDefinition mbd) throws Exception { if (bean instanceof BeanFactoryAware) { ((BeanFactoryAware) bean).setBeanFactory(this); } for (PropertyValue propertyValue : mbd.getPropertyValues().getPropertyValues()) { Object value = propertyValue.getValue(); if (value instanceof BeanReference) { BeanReference beanReference = (BeanReference) value; value = getBean(beanReference.getName()); } try { Method declaredMethod = bean.getClass().getDeclaredMethod( "set" + propertyValue.getName().substring(0, 1).toUpperCase() + propertyValue.getName().substring(1), value.getClass()); declaredMethod.setAccessible(true); //反射方式设值 declaredMethod.invoke(bean, value); } catch (NoSuchMethodException e) { Field declaredField = bean.getClass().getDeclaredField(propertyValue.getName()); declaredField.setAccessible(true); declaredField.set(bean, value); } } }
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
ApplicationContext 接口以及其实现类,主要是对Resource,BeanFactory,BeanDefinition进行功能封装,解决根据地址获取IoC容器并使用的问题。
AbstractApplicationContext 类,ApplicationContext 的抽象实现,内部包含一个 BeanFactory 类
public abstract class AbstractApplicationContext implements ApplicationContext { protected AbstractBeanFactory beanFactory; public AbstractApplicationContext(AbstractBeanFactory beanFactory) { this.beanFactory = beanFactory; } public void refresh() throws Exception { loadBeanDefinitions(beanFactory); registerBeanPostProcessors(beanFactory); onRefresh(); } protected abstract void loadBeanDefinitions(AbstractBeanFactory beanFactory) throws Exception; protected void registerBeanPostProcessors(AbstractBeanFactory beanFactory) throws Exception { List beanPostProcessors = beanFactory.getBeansForType(BeanPostProcessor.class); for (Object beanPostProcessor : beanPostProcessors) { beanFactory.addBeanPostProcessor((BeanPostProcessor) beanPostProcessor); } } protected void onRefresh() throws Exception{ beanFactory.preInstantiateSingletons(); } @Override public Object getBean(String name) throws Exception { return beanFactory.getBean(name); }
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
ClassPathXmlApplicationContext 类,从类路径加载资源的具体实现类
public class ClassPathXmlApplicationContext extends AbstractApplicationContext { private String configLocation; public ClassPathXmlApplicationContext(String configLocation) throws Exception { this(configLocation, new AutowireCapableBeanFactory()); } public ClassPathXmlApplicationContext(String configLocation, AbstractBeanFactory beanFactory) throws Exception { super(beanFactory); this.configLocation = configLocation; refresh(); } @Override protected void loadBeanDefinitions(AbstractBeanFactory beanFactory) throws Exception { XmlBeanDefinitionReader xmlBeanDefinitionReader = new XmlBeanDefinitionReader(new UrlResourceLoader()); xmlBeanDefinitionReader.loadBeanDefinitions(configLocation); for (Map.Entry<String, BeanDefinition> beanDefinitionEntry : xmlBeanDefinitionReader.getRegistry().entrySet()) { beanFactory.registerBeanDefinition(beanDefinitionEntry.getKey(), beanDefinitionEntry.getValue()); } }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
tiny-spring 的ApplicaitonContext使用流程是这样的:
ApplicaitonContext完成了类定义的读取和加载,并注册到BeanFactory中去。ApplicaitonContext从BeanFactory中寻找BeanPostProcessor,注册到BeanFactory维护的BeanPostProcessor列表中去。ApplicaitonContext以单例的模式,通过主动调用getBean实例化、注入属性、然后初始化BeanFactory中所有的Bean。由于所有的BeanPostProcessor都已经在第2步中完成实例化了,因此接下来实例化的是普通Bean,因此普通Bean的初始化过程可以正常执行。- 调用
getBean时,委托给BeanFactory,此时只是简单的返回每个Bean单例,因为所有的Bean实例在第三步都已经生成了。
参考
https://www.zybuluo.com/dugu9sword/note/382745#%E6%96%87%E4%BB%B6%E7%BB%93%E6%9E%84
文章来源: feige.blog.csdn.net,作者:码农飞哥,版权归原作者所有,如需转载,请联系作者。
原文链接:feige.blog.csdn.net/article/details/80505620
- 点赞
- 收藏
- 关注作者
评论(0)