原理:從配置文件讀取類的地址,通過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();
}
}