原理:从配置文件读取类的地址,通过Class.forName()方法实例化对象。方法静态化,使其工厂启动时,所有的bean以被实例化,可以随时取。
思路 :1.定义beanFactory 接口 2. beanFactoryFactory的实现
定义javabean
public class Hello {
public void hello(){
System.out.println("hello spring");
}
}
写配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--
xmlns 即 xml namespace xml 使用的命名空间
xmlns:xsi 即 xml schema instance xml 遵守的具体规范
xsi:schemaLocation 本文档 xml 遵守的规范 官方指定
-->
<bean id="hello" class="com.shsxt.Hello"/>
</beans>
描述对象属性的类
public class Entry {
String name;
String clazz;
public Entry(String name,String clazz){
this.name=name;
this.clazz=clazz;
}
}
beanFactory接口定义
public interface BeanFactory {
Object getBean(String id);
}
beanFactory实现类
public class BeanFactoryImpl implements BeanFactory {
private static final String BEAN_ID = "id";
private static final String BEAN_CLASS = "class";
//对象存放的容器
private static Map<String,Object> container = new ConcurrentHashMap<String,Object>();
//从配置文件读取出来的id和class的键值对才存入list
private static List<Entry> list = new LinkedList<Entry>();
/**
* 构造器,传入配置文件,并初始化bean池
* @param filePath
*/
public BeanFactoryImpl(String filePath){
readXMLHelper(filePath);
beanInit();
}
/**
* 读取配置文件,获取id和class,list
* @param filePath
*/
private static void readXMLHelper(String filePath) {
URL url = BeanFactoryImpl.class.getClassLoader().getResource(filePath);
SAXReader saxReader = new SAXReader();
try{
Document document = saxReader.read(url);
Map<String,Object> map = new HashMap<String,Object>();
map.put("sxt","http://www.springframework.org/schema/beans");
XPath xPath = document.createXPath("//sxt:bean");
xPath.setNamespaceURIs(map);
List<Element> elements = xPath.selectNodes(document);
for (Element element:elements){
list.add(new Entry(element.attributeValue(BEAN_ID),element.attributeValue(BEAN_CLASS)));
}
} catch (DocumentException e) {
e.printStackTrace();
}
}
/**
* 根据list中的class值,实例化对象,并将对应的id-Object存入容器container内
*/
private static void beanInit() {
Iterator<Entry> iterator = list.iterator();
while(iterator.hasNext()){
Entry en = iterator.next();
try{
Class<?> cls = Class.forName(en.clazz);
Object obj = cls.newInstance();
container.put(en.name,obj);
}catch (Exception e){
e.printStackTrace();
}
}
}
/**
* 重写接口的getBean方法,从容器container中取值
* @param name
* @return
*/
public Object getBean(String name) {
return container.get(name);
}
}
测试类
public class HelloTest {
public static void main(String[] args) {
BeanFactoryImpl ac = new BeanFactoryImpl("spring.xml");
Object object = ac.getBean("hello");
Hello hello = (Hello) object;
hello.hello();
}
}