Small Spring系列一:BeanFactory(一)
人生如逆旅,我亦是行人。
前言
Spring是一个开放源代码的设计层面框架,它解决的是业务逻辑层和其他各层的松耦合问题,因此它将面向接口的编程思想贯穿整个系统应用。
准备
bean-v1.xml
配置bean
的信息BeanDefinition
用于存放bean
的定义BeanFactory
获取bean的信息,实例化
bean`BeanFactoryTest
测试BeanFactory
是否可用
bean-v1.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans>
<bean id = "nioCoder"
class = "com.niocoder.service.v1.NioCoderService">
</bean>
<bean id ="invalidBean"
class="xxx.xxx">
</bean>
</beans>
BeanDefinition
bean-v1.xml
中定义了每个bean
,但这些信息我们该如何存储呢?
spring
是通过BeanDefinition
接口来描述bean
的定义
BeanDefinition
package com.niocoder.beans;
/**
* bean.xml bean的定义
* @author zhenglongfei
*/
public interface BeanDefinition {
/**
* 获取bean.xml中 bean的全名 如 "com.niocoder.service.v1.NioCoderService"
* @return
*/
String getBeanClassName();
}
GenericBeanDefinition
GenericBeanDefinition
实现了BeanDefinition
接口
package com.niocoder.beans.factory.support;
import com.niocoder.beans.BeanDefinition;
/**
* BeanDefinition 实现类
*
* @author zhenglongfei
*/
public class GenericBeanDefinition implements BeanDefinition {
private String id;
private String beanClassName;
public GenericBeanDefinition(String id, String beanClassName) {
this.id = id;
this.beanClassName = beanClassName;
}
public String getBeanClassName() {
return this.beanClassName;
}
}
BeanFactory
我们已经使用BeanDefinition
来描述bean-v1.xml
的bean
的定义,下面我们使用BeanFactory
来获取bean
的实例
BeanFactory
package com.niocoder.beans.factory;
import com.niocoder.beans.BeanDefinition;
/**
* 创建bean的实例
* @author zhenglongfei
*/
public interface BeanFactory {
/**
* 获取bean的定义
* @param beanId
* @return
*/
BeanDefinition getBeanDefinition(String beanId);
/**
* 获取bean的实例
* @param beanId
* @return
*/
Object getBean(String beanId);
}
DefaultBeanFactory
DefaultBeanFactory
实现了BeanFactory
接口
package com.niocoder.beans.factory.support;
import com.niocoder.beans.BeanDefinition;
import com.niocoder.beans.factory.BeanCreationException;
import com.niocoder.beans.factory.BeanDefinitionStoreException;
import com.niocoder.beans.factory.BeanFactory;
import com.niocoder.util.ClassUtils;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import java.io.InputStream;
import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* BeanFactory的默认实现类
*
* @author zhenglongfei
*/
public class DefaultBeanFactory implements BeanFactory {
private static final String ID_ATTRIBUTE = "id";
private static final String CLASS_ATTRIBUTE = "class";
/**
* 存放BeanDefinition
*/
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>();
/**
* 根据文件名称加载,解析bean.xml
*
* @param configFile
*/
public DefaultBeanFactory(String configFile) {
loadBeanDefinition(configFile);
}
/**
* 具体解析bean.xml的方法 使用dom4j
*
* @param configFile
*/
private void loadBeanDefinition(String configFile) {
ClassLoader cl = ClassUtils.getDefaultClassLoader();
try (InputStream is = cl.getResourceAsStream(configFile)) {
SAXReader reader = new SAXReader();
Document doc = reader.read(is);
Element root = doc.getRootElement();
Iterator<Element> elementIterator = root.elementIterator();
while (elementIterator.hasNext()) {
Element ele = elementIterator.next();
String id = ele.attributeValue(ID_ATTRIBUTE);
String beanClassName = ele.attributeValue(CLASS_ATTRIBUTE);
BeanDefinition bd = new GenericBeanDefinition(id, beanClassName);
this.beanDefinitionMap.put(id, bd);
}
} catch (Exception e) {
throw new BeanDefinitionStoreException("IOException parsing XML document", e);
}
}
@Override
public BeanDefinition getBeanDefinition(String beanId) {
return this.beanDefinitionMap.get(beanId);
}
@Override
public Object getBean(String beanId) {
BeanDefinition bd = this.getBeanDefinition(beanId);
if (bd == null) {
throw new BeanCreationException("BeanDefinition does not exist");
}
ClassLoader cl = ClassUtils.getDefaultClassLoader();
String beanClassName = bd.getBeanClassName();
try {
// 使用反射创建bean的实例,需要对象存在默认的无参构造方法
Class<?> clz = cl.loadClass(beanClassName);
return clz.newInstance();
} catch (Exception e) {
throw new BeanCreationException("Bean Definition does not exist");
}
}
}
BeanFactoryTest
以上,我们已经创建了bean.xml
,BeanDefinition
来描述bean
的定义,并且使用BeanFactory
来获取bean
的实例。下面我们来测试一下BeanFactory
是否可用。
package com.niocoder.test.v1;
import com.niocoder.beans.BeanDefinition;
import com.niocoder.beans.factory.BeanCreationException;
import com.niocoder.beans.factory.BeanDefinitionStoreException;
import com.niocoder.beans.factory.BeanFactory;
import com.niocoder.beans.factory.support.DefaultBeanFactory;
import com.niocoder.service.v1.NioCoderService;
import org.junit.Assert;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
/**
* BeanFactory 测试类
*/
public class BeanFactoryTest {
/**
* 测试获取bean
*/
@Test
public void testGetBean() {
BeanFactory factory = new DefaultBeanFactory("bean-v1.xml");
BeanDefinition bd = factory.getBeanDefinition("nioCoder");
assertEquals("com.niocoder.service.v1.NioCoderService", bd.getBeanClassName());
NioCoderService nioCoderService = (NioCoderService) factory.getBean("nioCoder");
assertNotNull(nioCoderService);
}
/**
* 测试无效的bean
*/
@Test
public void testInvalidBean() {
BeanFactory factory = new DefaultBeanFactory("bean-v1.xml");
try {
factory.getBean("invalidBean");
} catch (BeanCreationException e) {
return;
}
Assert.fail("expect BeanCreationException ");
}
/**
* 测试无效的xml
*/
@Test
public void testInvalidXML() {
try {
new DefaultBeanFactory("xxx.xml");
} catch (BeanDefinitionStoreException e) {
return;
}
Assert.fail("expect BeanDefinitionStoreException ");
}
}
代码下载
类图
Small Spring系列一:BeanFactory(一)的更多相关文章
- 转:Spring系列之beanFactory与ApplicationContext
原文地址:Spring系列之beanFactory与ApplicationContext 一.BeanFactoryBeanFactory 是 Spring 的“心脏”.它就是 Spring IoC ...
- Spring系列之beanFactory与ApplicationContext
一.BeanFactoryBeanFactory 是 Spring 的“心脏”.它就是 Spring IoC 容器的真面目.Spring 使用 BeanFactory 来实例化.配置和管理 Bean. ...
- 深入理解Spring系列之三:BeanFactory解析
转载 https://mp.weixin.qq.com/s?__biz=MzI0NjUxNTY5Nw==&mid=2247483824&idx=1&sn=9b7c2603093 ...
- Spring 系列: Spring 框架简介 -7个部分
Spring 系列: Spring 框架简介 Spring AOP 和 IOC 容器入门 在这由三部分组成的介绍 Spring 框架的系列文章的第一期中,将开始学习如何用 Spring 技术构建轻量级 ...
- Spring 系列: Spring 框架简介(转载)
Spring 系列: Spring 框架简介 http://www.ibm.com/developerworks/cn/java/wa-spring1/ Spring AOP 和 IOC 容器入门 在 ...
- 通俗化理解Spring3 IoC的原理和主要组件(spring系列知识二总结)
♣什么是IoC? ♣通俗化理解IoC原理 ♣IoC好处 ♣工厂模式 ♣IoC的主要组件 ♣IoC的应用实例 ♣附:实例代码 1.什么是IoC(控制反转)? Spring3框架的核心是实现控制反转(Io ...
- 狗鱼IT教程:推介最强最全的Spring系列教程
Spring是一个开源框架,Spring是于2003 年兴起的一个轻量级的Java 开发框架,由Rod Johnson创建. 简单来说,Spring是一个分层的JavaSE/EEfull-stack( ...
- Spring系列之IOC的原理及手动实现
目录 Spring系列之IOC的原理及手动实现 Spring系列之DI的原理及手动实现 导语 Spring是一个分层的JavaSE/EE full-stack(一站式) 轻量级开源框架.也是几乎所有J ...
- Spring系列之DI的原理及手动实现
目录 Spring系列之IOC的原理及手动实现 Spring系列之DI的原理及手动实现 前言 在上一章中,我们介绍和简单实现了容器的部分功能,但是这里还留下了很多的问题.比如我们在构造bean实例的时 ...
- Spring系列之AOP的原理及手动实现
目录 Spring系列之IOC的原理及手动实现 Spring系列之DI的原理及手动实现 引入 到目前为止,我们已经完成了简易的IOC和DI的功能,虽然相比如Spring来说肯定是非常简陋的,但是毕竟我 ...
随机推荐
- pdf.js跨域加载文件
pdf.js一个基于Html的工具类,熟悉pdf.js的朋友们很清楚,pdf.js帮助我们做了很多事.尤其金融类网站会产生很多的报表.需要在线预览.pdf.js绝对是我们的首选 本地预览 在pdf.j ...
- python基础知识 01
一.计算机基础知识 计算机有硬件+操作系统+软件应用组成 cpu:人的大脑 内存:人的临时记忆 硬盘:人的永久记忆 操作系统 控制计算机硬件工作的流程 应用程序 安装在操作系统上的软件 二.Pytho ...
- C/C++ 数据类型
C/C++ 数据类型 C语言包含5个基本数据类型: void, integer, float, double, 和 char. 类型 描述 字节数 取值范围 void 空类型 1 int 整型 4 - ...
- 重读《学习JavaScript数据结构与算法-第三版》- 第4章 栈
定场诗 金山竹影几千秋,云索高飞水自流: 万里长江飘玉带,一轮银月滚金球. 远自湖北三千里,近到江南十六州: 美景一时观不透,天缘有分画中游. 前言 本章是重读<学习JavaScript数据结构 ...
- QMS 的趨勢概述
自泰勒Taylor提出的科学管理被奉行后,制造业的分工已然成形,而产品不再是由工匠单独负责完成.为确保产品的质量,产品在完工后的检验为确保瑕疵品不外流出给客户的必要关卡.然而当产品依靠检验结果并无法减 ...
- git 技术栈
之前用的都是svn ,git还是要了解的,万一哪天要用了呢
- pak文件的打包和解包
pak格式的文件 一般游戏有资源 游戏素材会打包放进去 比如游戏语音 游戏多加点语音 多加一些贴图资源 外部文件实现的 素材--->pak文件--->用的时候从文件中取出来 文件的打包 ...
- MUI-页面传参数
点击第一个页面的标签,跳转到第二个页面,把第一个页面的值也传往目标页面 现在提供两种实现方式 注意:需要在手机运行才可以,用电脑浏览器可能不支持. 第一种方式 页面已创建,通过自定义事件传值 fir ...
- Linux任务调度(8)
crond任务调度: 是指系统在某个时间执行特定的命令或程序. 分类:1.系统工作,有些重要的工作必须周而复始地执行,如病毒扫描等:2.个别用户工作,个别用户可能希望执行某些程序,如mysql数据库备 ...
- sea.js的同步魔法
前些时间也是想写点关于CMD模块规范的文字,以便帮助自己理解.今天看到一篇知乎回答,算是给了我一点启发. 同步写法却不阻塞? 先上一个sea.js很经典的模块写法: // 定义一个模块 define( ...