需要解析的xml文件,注意引用ref。
<?xml version="1.0" encoding="UTF-8" ?>
<beans>
<bean id="board1" class="模拟Spring.Board">
<property name="brand" value="华硕"></property>
<property name="price" value="500"></property>
</bean>
<bean id="com1" class="模拟Spring.Computer">
<property name="brand" value="华硕"></property>
<property name="price" value="500"></property>
<property name="board" ref="board1"></property>
</bean>
</beans>
Board类
package 模拟Spring;
/**
* @author duyong_dain@163.com
* @data 2018/10/10 15:36
* @TODO-->
*/
public class Board {
private String brand;
private float price;
public String getBrand() {
return brand;
}
public void setBrand(String brand) {
this.brand = brand;
}
public float getPrice() {
return price;
}
public void setPrice(float price) {
this.price = price;
}
@Override
public String toString() {
return "Board{" +
"brand='" + brand + '\'' +
", price=" + price +
'}';
}
}
Computer类
package 模拟Spring;
/**
* @author duyong_dain@163.com
* @data 2018/10/10 15:36
* @TODO-->
*/
public class Computer {
private String brand;
private float price;
private Board board;
public Board getBoard() {
return board;
}
public void setBoard(Board board) {
this.board = board;
}
public String getBrand() {
return brand;
}
public void setBrand(String brand) {
this.brand = brand;
}
public float getPrice() {
return price;
}
public void setPrice(float price) {
this.price = price;
}
@Override
public String toString() {
return "Computer{" +
"brand='" + brand + '\'' +
", price=" + price +
", board=" + board +
'}';
}
}
package 模拟Spring;
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.util.*;
/**
* @author duyong_dain@163.com
* @data 2018/10/10 15:36
* @TODO-->
*/
public class Spring {
private static Spring instance;
private Spring(){
init();
}
public static Spring getInstance(){
if(instance==null)
instance=new Spring();
return instance;
}
//存储bean
private HashMap<String,Object> beans=new HashMap<>();
//存储被ref引用的对象的信息
private List<String[]> refInfos=new ArrayList<>();
//配置文件路径
String path= "src/main/java/模拟Spring/beans.xml";
private void init(){
/**
*@TODO:初始化XMl文件,创建对象,填充属性
*@return: void
*/
SAXReader reader=new SAXReader();
try{
File file=new File(path);
InputStream in=new FileInputStream(file);
Document doc=reader.read(in);
//获取根元素
Element rootElement=doc.getRootElement();
//bean迭代器
Iterator<Element> beanIterator=rootElement.elementIterator();
while(beanIterator.hasNext()){
//获取bean
Element beanElement=beanIterator.next();
//获取bean的属性对象
Attribute id=beanElement.attribute("id");
Attribute classPath=beanElement.attribute("class");
//创建对象
Class c=Class.forName(classPath.getValue().trim());
Object obj=c.newInstance();
//属性的填充
Iterator<Element> propertyIterator=beanElement.elementIterator();
while(propertyIterator.hasNext()){
//property对象
Element propertyElement=propertyIterator.next();
Attribute propertyname=propertyElement.attribute("name");
//获取name属性的值
String name=propertyname.getValue();
Attribute propertyvalue=propertyElement.attribute("value");
if(propertyvalue==null){
//ref
Attribute propertyRef=propertyElement.attribute("ref");
//ref引用的是容器中的其他对象,暂时记录信息
//记录对象的ID,属性的名称,ref的值
String[] refInfo={id.getValue(),name,propertyRef.getValue()};
refInfos.add(refInfo);
}
else{
//普通属性
String value=propertyvalue.getValue();
setAttr(obj,name,value);
}
}
beans.put(id.getValue(),obj);
}
//有ref的对象没有装配,在这里等所有的对象都创建后开始装配
for(String[] infos:refInfos){
Object obj=beans.get(infos[0]);//获取map中key(id)对应的对象
String attrName=infos[1];//拿到需要装配的name信息
Object targetObj=beans.get(infos[2]);//拿到ref所指向的对象
String methodName="set"+attrName.substring(0,1).toUpperCase()+attrName.substring(1);
Method setMethod=null;
Class c=obj.getClass();
Method[] methods=c.getMethods();
for(Method method:methods){
if(method.getName().equals(methodName)){
setMethod=method;
break;
}
}
if(setMethod==null){
throw new RuntimeException("方法"+methodName+"没有找到");
}
setMethod.invoke(obj,targetObj);
}
}
catch (Exception e){
throw new RuntimeException(e);
}
}
private void setAttr(Object obj,String attrName,String attrValue) throws Exception {
String methodName="set"+attrName.substring(0,1).toUpperCase()+attrName.substring(1);
Method setMethod=null;
Class c=obj.getClass();
Method[] methods=c.getMethods();
for(Method method:methods){
if(method.getName().equals(methodName)){
setMethod=method;
break;
}
}
if(setMethod==null){
throw new RuntimeException("方法"+methodName+"没有找到");
}
Class[] parameterTypes=setMethod.getParameterTypes();
Class parameterType=parameterTypes[0];
if(parameterType==int.class){
setMethod.invoke(obj,Integer.parseInt(attrValue));
}
if(parameterType==byte.class){
setMethod.invoke(obj,Byte.parseByte(attrValue));
}
if(parameterType==short.class){
setMethod.invoke(obj,Short.parseShort(attrValue));
}
if(parameterType== long.class){
setMethod.invoke(obj,Long.parseLong(attrValue));
}
if(parameterType==float.class){
setMethod.invoke(obj,Float.parseFloat(attrValue));
}
if(parameterType==double.class){
setMethod.invoke(obj,Double.parseDouble(attrValue));
}
if(parameterType==boolean.class){
setMethod.invoke(obj,Boolean.parseBoolean(attrValue));
}
if(parameterType==String.class){
setMethod.invoke(obj,attrValue);
}
}
public Object getBean(String id){
return beans.get(id);
}
public <T> T getBean(Class c){
//遍历map
Set<String> keys=beans.keySet();
int count=0;
T t=null;
for(String key:keys){
Object obj=beans.get(key);
if(c==obj.getClass()){
t= (T) c.cast(obj);
count++;
if(count>1){
throw new RuntimeException(c+"出现了俩儿");
}
}
}
return null;
}
public static void main(String[] args) {
Spring s=new Spring();
System.out.println(s.getBean("com1"));
}
}