1. 程式人生 > >spring 底層實現IOC DI簡單依賴反射

spring 底層實現IOC DI簡單依賴反射

1.準備實體,dao介面和實現類,service介面和實現類,spring.xml配置檔案

實體:public class User implements Serializable{
private Integer id;
private String name;
private Integer age;
public User(Integer id, String name, Integer age) {
super();
this.id = id;
this.name = name;
this.age = age;
}
public User() {
super();
// TODO Auto-generated constructor stub
}
@Override
public String toString() {
return "User [id=" + id + ", name=" + name + ", age=" + age + "]";
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}

}

dao介面和實現類

public interface UserDao {
List<User> queryAll();
}



public class UserDaoImpl implements UserDao {
@Override
public List<User> queryAll() {
// TODO Auto-generated method stub
System.out.println("++++++query all users++++");
return null;
}
}

service介面和實現類

public interface UserService {
List<User> selectAll();
}

public class UserServiceImpl implements UserService {
     
private UserDao userDao;

public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}


@Override
public List<User> selectAll() {
// TODO Auto-generated method stub
return userDao.queryAll();
}
}

spring.xml檔案

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
   xmlns:context="http://www.springframework.org/schema/context"
   xmlns:mvc="http://www.springframework.org/schema/mvc"
   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-3.2.xsd
      http://www.springframework.org/schema/context
      http://www.springframework.org/schema/context/spring-context-3.2.xsd
      http://www.springframework.org/schema/mvc
      http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd ">
<bean id="userDao" class="org.hi.software.test.dao.UserDaoImpl"/>
<bean id="userService" class="org.hi.software.test.service.UserServiceImpl">
<property name="userDao" ref="userDao"/>
</bean>
</beans>

2.

a、讀取xml檔案

//存放所有的bean節點
HashMap<String, String> beanMap = new HashMap<String, String>();
//存放所有bean節點對應的property集合{'beanid1':'{'name':'ref','name','value'}','beanid2':'{'',''}'}
HashMap<String, Map<String, String>> propertyMap = new HashMap<String, Map<String, String>>();
//工廠存放beanid ,和對應的物件
HashMap<String, Object> context = new HashMap<String, Object>();

//讀取xml檔案拿到id和class,放入工廠beanMap DocumentBuilderFactory newInstance = DocumentBuilderFactory.newInstance(); //讀取配置檔案             Document document = newInstance.newDocumentBuilder().parse("src/org/hi/software/spring.xml"); //通過節點名稱獲取所有的節點集合 NodeList elementsByTagName = document.getElementsByTagName("bean");

b、

拿到bean節點,遍歷所有的property屬性拿到property屬性的集合propertyAttributeMap(<name,ref>或者<name,value>) propertyAttributeMap作為value,beanId作為key,放入集合propertyMap //遍歷拿到節點的key value for (int i = 0; i < elementsByTagName.getLength(); i++) {                 Element beanitem = (Element) elementsByTagName.item(i);                 String beanid = beanitem.getAttribute("id");                 String beanclass = beanitem.getAttribute("class"); //System.out.println(beanclass+"---->"+beanid); beanMap.put(beanid, beanclass); //獲取每個bean下的property屬性                     NodeList elementsByTagName2 = beanitem.getElementsByTagName("property");                     Map<String, String> propertyAttributeMap=new HashMap<String, String>(); for (int j = 0; j < elementsByTagName2.getLength(); j++) {                             Element propertyitem = (Element)elementsByTagName2.item(j);                             String name = propertyitem.getAttribute("name");                             String ref = propertyitem.getAttribute("ref"); //System.out.println(name+"---"+ref); propertyAttributeMap.put(name, ref);                         } propertyMap.put(beanid,propertyAttributeMap);             } d、IOC:beanMap轉化為context工廠(beanID-->物件) for (Map.Entry<String, String> bean : beanMap.entrySet()) {                 String beanid = bean.getKey();                 String beanclass = bean.getValue();                 Object object = Class.forName(beanclass).newInstance(); context.put(beanid, object);             } e、DI:遍歷propertyMap,通過key找到bean物件,value就是property集合包含name和value(ref)         組裝setName方法進行賦值,如果不是基本型別,應通過context獲得複雜物件進行賦值 for (Map.Entry<String, Map<String, String>> beanProperty:propertyMap.entrySet()) {                 String bid = beanProperty.getKey();                 Object target = context.get(bid);                 System.out.println("target:"+target);                 Map<String, String> value = beanProperty.getValue(); for (Map.Entry<String, String> proString :value.entrySet()) {                     String name = proString.getKey();                     String ref = proString.getValue();                     Object object = context.get(ref);                     System.out.println("object:"+object);                     String methodName="set"+name.substring(0, 1).toUpperCase()+name.substring(1);                     Method declaredMethod = target.getClass().getDeclaredMethod(methodName,context.get(ref).getClass().getInterfaces()[0]); declaredMethod.invoke(target, object);                 } 3.測試 UserService us = (UserService) context.get("userService");
us.selectAll();