实现Spring中的BeanFactory

  • 概览
  • 具体代码如下:
  • 1. 接口:
  • 2. 三个实现类 分别实现接口的save() 方法 如下
  • 3. beans.xml
  • 4. beanFactory类:
  • 5. 测试:
  • 总结:


在spring中通过管理ioc的思想,将实例的创建于管理交由spring容器来管理。这里来简单的实现一下这个Spring的Bean工厂。
主要是 工厂+反射+配置文件 配合实现

概览

创建项目,结构如下图:

Bean实现Java代码配置数据库连接 java beanfactory_Bean实现Java代码配置数据库连接

  • 一个接口和三个实现类。
  • 一个bean工厂类
  • 包就导入了一个 dom4j的包。
  • beans.xml 的配置文件
  • 一个测试类。
具体代码如下:
1. 接口:

Bean实现Java代码配置数据库连接 java beanfactory_BeanFactory_02

2. 三个实现类 分别实现接口的save() 方法 如下

Bean实现Java代码配置数据库连接 java beanfactory_Bean实现Java代码配置数据库连接_03


Bean实现Java代码配置数据库连接 java beanfactory_BeanFactory_04


Bean实现Java代码配置数据库连接 java beanfactory_BeanFactory_05

3. beans.xml

Bean实现Java代码配置数据库连接 java beanfactory_BeanFactory_06

4. beanFactory类:
package cn.beanFactoryDemo.beanFactory;

import java.util.Iterator;
import java.util.List;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.junit.Test;

import cn.beanFactoryDemo.service.UserService;
import cn.beanFactoryDemo.service.impl.UserService1;

/**
 * 仿造spring源码  bean的生产过程
 * @author fbd
 *
 */
public class BeanFactory {

		//工厂+反射    
		@Test
		public static Object getBean(String ids) throws Exception {
			String classValue = null;
			// 1. 加载xml 配置文件, 并获得document 对象
			SAXReader reader = new SAXReader ();
			Document dc = reader.read
					(BeanFactory.class.getClassLoader()
							.getResourceAsStream("beans.xml"));
			// 2. 解析xml 获取参数ids 对应的 类路径的字符串
			// 获取跟标签
			Element root = dc.getRootElement();
			// 获取跟标签下的所有字标签
			List<Element> list = root.elements();
			// 遍历
			for(Element element : list) {
				//获取每个子标签的属性
				//判断
				if(element.attributeValue("id").equals(ids)) 
				{
					// 获取class 属性值
					classValue = element.attributeValue("class");
					System.out.println(classValue);
				}
			}
			// 3. 用上步获取到的类路径的字符串 通过反射获取对象
			Class classs = Class.forName(classValue);
			// 通过无参构造创建对象
			Object obj = classs.newInstance();
			return obj;
		}		
}
5. 测试:
package cn.beanFactoryDemo.web;

import org.junit.Test;

import cn.beanFactoryDemo.beanFactory.BeanFactory;
import cn.beanFactoryDemo.service.UserService;
import cn.beanFactoryDemo.service.impl.UserService3;

public class Demo {

	@Test
	public void test1() {
		// 调用service层 save
				/*UserService1 us1 = new UserService1();
				us1.save();*/
				
				/*UserService2 us2 = new UserService2();
				us2.save();*/
				
				UserService3 us3 = new UserService3();
				us3.save();
				// 可以完成 功能  但是扩展性不是太好
				// 有没有方式让扩展性好点    接口
	}
	@Test
	public void test2()
	{
		UserService us=new UserService3();
		us.save();
		// 接口的开发对扩展性好了 但是耦合度不低 还需要修改源码
		// 能不能有一种方式 不要修改我web层的源码了   有   工厂模式(作用:生产对象)
		
	}
	
	@Test
	public void test3() throws Exception
	{
		UserService us=(UserService) BeanFactory.getBean("UserService");
		us.save();
		//  web层的耦合度确实没有 不需要修改任何的源码
		// 但是工厂的耦合度又高了 还得修改工厂的源码
		// 问题: 能不能所有的源码都不修改了 还能完成以上功能
		// 能     工厂+反射+配置文件   
	}
}
总结:
  1. 这里简单演示了Spring中BeanFactory的Bean的创建原理。通过配置文件+反射+工厂的设计模式。
  2. 也可以看出来 , 面向接口编程的有点:
  • 降低代码得耦合度。
  • 使程序易于扩展
  • 逻辑更加清晰
    接口其实就是暴露出来的一种规则。面向接口编程,其实也是按规则编程。这样代码也会很清晰,易于维护。