1. 程式人生 > >spring ioc中例項化bean以及依賴注入bean和基本型別屬性簡單實現方案

spring ioc中例項化bean以及依賴注入bean和基本型別屬性簡單實現方案

Spring兩個重要特性IOC和AOP,本文中簡單實現bean的建立以及屬性依賴注入。

實現步驟如下:

1、通過dom4j解析bean.xml檔案,將bean物件以及依賴屬性裝入List。

2、遍歷list,通過反射機制例項化物件。

3、遍歷list,通過反射呼叫bean裡的set方法注入依賴物件以及基本型別屬性。

引入dom4j maven依賴

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>myproject</groupId>
	<artifactId>myproject</artifactId>
	<packaging>war</packaging>
	<version>0.0.1-SNAPSHOT</version>
	<name>myproject Maven Webapp</name>
	<url>http://maven.apache.org</url>
	<dependencies>
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>3.8.1</version>
			<scope>test</scope>
		</dependency>

		<dependency>
			<groupId>dom4j</groupId>
			<artifactId>dom4j</artifactId>
			<version>1.6.1</version>
		</dependency>
		<dependency>
			<groupId>jaxen</groupId>
			<artifactId>jaxen</artifactId>
			<version>1.1.6</version>
		</dependency>

		<!-- https://mvnrepository.com/artifact/commons-beanutils/commons-beanutils -->
		<dependency>
			<groupId>commons-beanutils</groupId>
			<artifactId>commons-beanutils</artifactId>
			<version>1.8.3</version>
		</dependency>

	</dependencies>
	<build>
		<finalName>myproject</finalName>
	</build>
</project>

spring bean配置檔案

<beans xmlns="http://www.springframework.org/schema/beans"    
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc"    
    xmlns:context="http://www.springframework.org/schema/context"    
    xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"    
    xsi:schemaLocation="http://www.springframework.org/schema/beans     
        http://www.springframework.org/schema/beans/spring-beans-3.2.xsd     
        http://www.springframework.org/schema/mvc     
        http://www.springframework.org/schema/mvc/spring-mvc-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/aop     
        http://www.springframework.org/schema/aop/spring-aop-3.2.xsd     
        http://www.springframework.org/schema/tx     
        http://www.springframework.org/schema/tx/spring-tx-3.2.xsd ">    
      
    <bean id="orderDao" class="com.ocean.spring.bean.OrderDao">  
    </bean>  
      
    <bean id="orderService" class="com.ocean.spring.bean.OrderService">  
        <!-- 需要注入bean -->  
        <property name="orderDao" ref="orderDao"/>
         <!-- 需要注入基本型別資料 -->  
        <property name="name" value="ocean"/>
        <property name="id" value="56"/>
    </bean>    
</beans>
OrderService類
package com.ocean.spring.bean;

public class OrderService {

	private OrderDao orderDao;

	private String name;

	private int id;
	
	public void updateOrder() {
		System.out.println(this.name+","+this.id);
		orderDao.updateOrder();
	}

	public void setName(String name) {
		this.name = name;
	}

	public void setId(int id) {
		this.id = id;
	}
	// set 方法提供依賴注入
	public void setOrderDao(OrderDao orderDao) {
		this.orderDao = orderDao;
	}
}
OrderDao類
package com.ocean.spring.bean;  
  
public class OrderDao {  
    public void updateOrder(){  
        System.out.println("更新訂單資訊");  
    }  
} 

bean描述類
package com.ocean.spring.bean;  
  
import java.util.ArrayList;  
import java.util.List;  
/** 
 * bean描述物件 
 * @author 
 * 
 */  
public class BeanDefine {  
      
    private String id;  
    private String className;  
      
    private List<PropertiesDto> propertiesDtos = new ArrayList<PropertiesDto>();  
      
    public BeanDefine(String id, String className) {  
        this.id = id;  
        this.className = className;  
    }  
    public String getId() {  
        return id;  
    }  
    public void setId(String id) {  
        this.id = id;  
    }  
    public String getClassName() {  
        return className;  
    }  
    public void setClassName(String className) {  
        this.className = className;  
    }  
    public List<PropertiesDto> getPropertiesDtos() {  
        return propertiesDtos;  
    }  
    public void setPropertiesDtos(List<PropertiesDto> propertiesDtos) {  
        this.propertiesDtos = propertiesDtos;  
    }  
      
}  


bean屬性描述類
package com.ocean.spring.bean;

/**
 * 屬性描述物件
 * 
 * @author
 * 
 */
public class PropertiesDto {
	private String name;
	
	private String ref;
	
	private String value;
	
	public PropertiesDto() {
	}
	public PropertiesDto(String name, String ref, String value) {
		this.name = name;
		this.ref = ref;
		this.value = value;
	}

	public String getValue() {
		return value;
	}

	public void setValue(String value) {
		this.value = value;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getRef() {
		return ref;
	}

	public void setRef(String ref) {
		this.ref = ref;
	}

}


模擬實現bean的例項化以及依賴注入類
package com.ocean.spring.bean;

import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.beanutils.ConvertUtils;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.XPath;
import org.dom4j.io.SAXReader;

public class SpringIoc {
	private List<BeanDefine> beanDefines = new ArrayList<BeanDefine>();

	private Map<String, Object> beans = new HashMap<String, Object>();

	public static void main(String[] args) {
		SpringIoc SpringIoc = new SpringIoc();
		SpringIoc.myIoc();
		OrderService orderService = (OrderService) SpringIoc.getBeans().get("orderService");
		orderService.updateOrder();// 如果報空指標則注入失敗,如果打印出資訊表示注入成功
	}

	public void myIoc() {
		// dom4j解析xml
		readXML("config/spring/spring-bean.xml");
		// 利用反射例項化bean
		instanceBean();
		// bean的屬性注入
		inject();
	}

	/**
	 * dom4j解析xml
	 * 
	 * @param fileName
	 */
	private void readXML(String fileName) {
		SAXReader saxReader = new SAXReader();
		URL url = this.getClass().getClassLoader().getResource(fileName);
		try {
			Map<String, String> nsMap = new HashMap<String, String>();
			nsMap.put("ns", "http://www.springframework.org/schema/beans");
			Document document = saxReader.read(url);
			XPath xPath = document.createXPath("//ns:beans/ns:bean");// 建立查詢路徑
			xPath.setNamespaceURIs(nsMap);
			List<Element> beans = xPath.selectNodes(document);
			for (Element element : beans) {
				String id = element.attributeValue("id");
				String className = element.attributeValue("class");
				BeanDefine beanDefine = new BeanDefine(id, className);// bean描述物件

				XPath propertysub = element.createXPath("ns:property");
				propertysub.setNamespaceURIs(nsMap);
				List<Element> properties = propertysub.selectNodes(element);
				if (properties != null && properties.size() > 0) {
					for (Element property : properties) {
						String name = property.attributeValue("name");
						String ref = property.attributeValue("ref");
						String value = property.attributeValue("value");
						if (name != null) {
							PropertiesDto propertiesDto = new PropertiesDto();// 屬性描述物件
							propertiesDto.setName(name);
							if (ref != null) {
								propertiesDto.setRef(ref);
							}
							if (value != null) {
								propertiesDto.setValue(value);
							}
							beanDefine.getPropertiesDtos().add(propertiesDto);
						}
					}
				}
				beanDefines.add(beanDefine);
			}
		} catch (DocumentException e) {
		}
	}

	/**
	 * 例項化
	 */
	private void instanceBean() {
		if (beanDefines == null || beanDefines.size() == 0) {
			System.out.println("容器中沒有需要例項化的bean");
			return;
		}
		try {
			for (BeanDefine beanDefine : beanDefines) {
				beans.put(beanDefine.getId(), Class.forName(beanDefine.getClassName()).newInstance());
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 依賴注入
	 */
	private void inject() {
		try {
			for (BeanDefine beanDefine : beanDefines) {
				List<PropertiesDto> propertiesDtos = beanDefine.getPropertiesDtos();
				if (propertiesDtos != null && propertiesDtos.size() > 0) {
					Object bean = beans.get(beanDefine.getId());
					PropertyDescriptor[] propertyDescriptors = Introspector.getBeanInfo(bean.getClass())
							.getPropertyDescriptors();
					for (PropertiesDto propertiesDto : propertiesDtos) {
						for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {
							if (propertyDescriptor.getName().equals(propertiesDto.getName())) {
								Method setter = propertyDescriptor.getWriteMethod();// 獲取屬性的set方法
								if (propertiesDto.getRef() != null && !"".equals(propertiesDto.getRef())) {
									setter.invoke(bean, beans.get(propertiesDto.getRef()));// 將依賴的bean注入進來
								}
								String value = propertiesDto.getValue();
								if (value != null && !"".equals(value)) {
									// 用apache的ConvertUtils將基本型別屬性注入進來
									setter.invoke(bean,
											ConvertUtils.convert(value, propertyDescriptor.getPropertyType()));
								}
								break;
							}
						}
					}
				}
			}
		} catch (Exception e) {
		}
	}

	public Map<String, Object> getBeans() {
		return beans;
	}
}

工程目錄結構圖