简单的spring IOC 实现
程序员文章站
2022-07-12 12:57:40
...
springbean的加载 步骤为,1.配置xml文件,2.加载xml文件,并解析,3.将得到的class类保存.下面就是代码
package myc_demo.ioctest;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.FileInputStream;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;
/**
* @program: Demo
*
* @description: 人间有味是清欢
* 简单的spring ioc实现
* @author: liuSha.pufengjun
* @create: 2018-07-26 10:05
**/
public class SimpleIOC {
private Map<String ,Object> beanMap = new HashMap<>();
public SimpleIOC(String location) throws Exception{
loadBeans(location);
}
public Object getBean(String name){
Object bean = beanMap.get(name);
if(null == bean){
throw new IllegalArgumentException("there is no bean with name " +name);
}
return bean;
}
/**
* 加载bean
* @param location
* @throws Exception
*/
private void loadBeans(String location) throws Exception {
//加载并解析xml配置文件
InputStream inputStream = new FileInputStream(location);
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder documentBuilder = factory.newDocumentBuilder();
Document document = documentBuilder.parse(inputStream);
Element root = document.getDocumentElement();
NodeList nodes = root.getChildNodes();
for (int i = 0 ;i < nodes.getLength(); i++){
Node node = nodes.item(i);
if(node instanceof Element){
Element ele = (Element) node;
String id = ele.getAttribute("id");
String className = ele.getAttribute("class");
//加载class
Class beanClass = null;
try {
beanClass = Class.forName(className);
} catch (ClassNotFoundException e) {
e.printStackTrace();
return;
}
// 创建 类
Object bean = beanClass.newInstance();
//遍历property标签
NodeList propertyNodes = ele.getElementsByTagName("property");
for (int j = 0; j < propertyNodes.getLength() ; j++) {
Node propertyNode = propertyNodes.item(j);
if (propertyNode instanceof Element) {
Element propertyElement = (Element) propertyNode;
String name = propertyElement.getAttribute("name");
String value = propertyElement.getAttribute("value");
// 利用反射将 bean 相关字段访问权限设为可访问
Field declaredField = bean.getClass().getDeclaredField(name);
declaredField.setAccessible(true);
if (value != null && value.length() > 0) {
// 设置属性值
declaredField.set(bean, value);
} else {
String ref = propertyElement.getAttribute("ref");
if (null == ref && ref.length() == 0){
throw new IllegalArgumentException("ref config error!!");
}
// 将引用填充到相关字段中
declaredField.set(bean, getBean(ref));
}
//将bean注册到map中
registerBean(id,bean);
}
}
}
}
}
//将bean添加到map中
private void registerBean(String id ,Object bean){
beanMap.put(id,bean);
}
}
实体类:
package myc_demo.ioctest;
/**
* @program: Demo
* @description: 人间有味是清欢
* @author: liuSha.pufengjun
* @create: 2018-07-26 14:04
**/
public class Rain {
//数量
private String amount;
//雨势
private String trend ;
public String getAmount() {
return amount;
}
public void setAmount(String amount) {
this.amount = amount;
}
public String getTrend() {
return trend;
}
public void setTrend(String trend) {
this.trend = trend;
}
@Override
public String toString() {
return "Wheel : {amount ["+amount+"] trend [" + trend + "] }";
}
}
package myc_demo.ioctest;
/**
* @program: Demo
* @description: 人间有味是清欢
* @author: liuSha.pufengjun
* @create: 2018-07-26 14:03
**/
public class Warter {
//类型
private String type;
//地址
private String address;
//成分
private String constituent;
//构成
private String take;
private Rain rain;
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getConstituent() {
return constituent;
}
public void setConstituent(String constituent) {
this.constituent = constituent;
}
public String getTake() {
return take;
}
public void setTake(String take) {
this.take = take;
}
public Rain getRain() {
return rain;
}
public void setRain(Rain rain) {
this.rain = rain;
}
@Override
public String toString() {
return "car { type ["+ type+"] address [ " + address+ " ] constituent [" + constituent+ "] take [ " +take
+"] wheel [" + rain.toString() + "] }";
}
}
测试类: 这里/ioc.xml表示更目录下 不加 / 表示当前目录下
@Test
public void getBean() throws Exception {
String location = SimpleIOC.class.getClassLoader().getResource("ioc.xml").getFile();
SimpleIOC simpleIOC = new SimpleIOC(location);
Warter warter = (Warter) simpleIOC.getBean("warter");
System.out.println(warter);
Rain rain = (Rain) simpleIOC.getBean("rain");
System.out.println(rain);
}
xml文件: ioc.xml
<beans>
<bean id="rain" class="myc_demo.ioctest.Rain">
<property name="amount" value="小雨" />
<property name="trend" value="越下越大" />
</bean>
<bean id="warter" class="myc_demo.ioctest.Warter">
<property name="type" value="淡水"/>
<property name="address" value="杭州"/>
<property name="constituent" value="H2O2"/>
<property name="take" value="H O N "/>
<property name="rain" ref="rain"/>
</bean>
</beans>
运行测试类结果: