spring模拟 xml文件装载bean
简单的demo 用于更清楚的了解 spring的注入原理。spring IOC都知道通过JAVA的反射 但是具体的反射 ,怎么实现的?。。。相信就是已经工作的小伙伴好多也不知道他的具体实现方式
结构图 model 当做service 简单的demo 没有太规范
xml配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans>
<bean id="user" class="com.spring.model.Student">
</bean>
<bean id="person" class="com.spring.model.Person">
<property name="age" value="1111"/>
<property name="addres" value="BJ"/>
<property name="name" value="tom"/>
<property name="student" ref="user"/>
</bean>
<bean id="A" class="com.spring.model.A">
<property name="person" ref="person"/>
</bean>
</beans>
Model代码
package com.spring.model;
public class A {
String username;
String pas;
Person person;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPas() {
return pas;
}
public void setPas(String pas) {
this.pas = pas;
}
public Person getPerson() {
return person;
}
public void setPerson(Person person) {
this.person = person;
}
public void sysGet() {
System.out.println(person.toString());
}
}
package com.spring.model;
import java.lang.reflect.Method;
public class Person implements java.io.Serializable{
/**
*
*/
private static final long serialVersionUID = 1L;
private String name;
private int age;
private String addres;
private Student student;
public Person() {}
public Student getStudent() {
return student;
}
public void setStudent(Student student) {
this.student = student;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getAddres() {
return addres;
}
public void setAddres(String addres) {
this.addres = addres;
}
public static void main(String[] args) throws NoSuchMethodException, SecurityException {
Person person = new Person();
Student student = new Student();
Class<?> tClass = student.getClass();
Method method = person.getClass().getMethod("setStudent",tClass);
System.err.println(method);
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + ", addres=" + addres + ", student=" + student + "]";
}
}
package com.spring.model;
import java.io.Serializable;
public class Student implements Serializable {
int SttNum;
int clazz;
public int getSttNum() {
return SttNum;
}
public void setSttNum(int sttNum) {
SttNum = sttNum;
}
public int getClazz() {
return clazz;
}
public void setClazz(int clazz) {
this.clazz = clazz;
}
}
package com.spring;
import java.util.List;
import java.util.Properties;
public class Bean {
private String name;
private String className;
private List<Property> properties;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getClassName() {
return className;
}
public void setClassName(String className) {
this.className = className;
}
public List<Property> getProperties() {
return properties;
}
public void setProperties(List<Property> properties) {
this.properties = properties;
}
}
package com.spring;
public class Property {
private String name;
private Object value;
private String ref;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Object getValue(){
return value;
}
public void setValue(Object value) {
this.value = value;
}
public String getRef() {
return ref;
}
public void setRef(String ref) {
this.ref = ref;
}
}
package com.spring;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import java.io.InputStream;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class ConfigManager {
static Document document =null;
static Map<String, Object> map = new HashMap<String, Object>();
public static Map<String, Object> getConfig(String path){
String xpath = "//bean";
try {
InputStream inputStream = ConfigManager.class.getResourceAsStream(path);
SAXReader reader = new SAXReader();
document = reader.read(inputStream);
List<Element> list = document.selectNodes(xpath);
for(Element element : list){
Bean bean = new Bean();
String name = element.attributeValue("id");
bean.setName(name);
bean.setClassName(element.attributeValue("class"));
List<Property> lProperties =new ArrayList<Property>();
List<Element> children = element.elements("property");
for(Element element2 : children){
Property property = new Property();
property.setName(element2.attributeValue("name"));
property.setValue(element2.attributeValue("value"));
property.setRef(element2.attributeValue("ref"));
lProperties.add(property);
}
bean.setProperties(lProperties);
map.put(name, bean);
}
return map;
} catch (Exception e1) {
e1.printStackTrace();
return null;
}
}
}
测试类 和用于注入属性的静态方法BeanSet 参数 ConfigManager 返回的map对象
package com.spring;
import java.lang.reflect.Method;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.lang.StringUtils;
import com.spring.model.A;
import com.spring.model.Person;
public class test {
static ConcurrentHashMap<String,Object> applicActionContext = new ConcurrentHashMap<String,Object>(); //类似于 spring 的上下文存储bean对象
public static void main(String[] args) throws Exception {
Map<String, Object> map = ConfigManager.getConfig("/spring-test.xml");
BeanSet(map);
Person person = (Person) applicActionContext.get("person");
A a =(A) applicActionContext.get("A");
a.sysGet();
}
public static void BeanSet(Map<String, Object> map) throws Exception{
for (Map.Entry<String, Object> entry : map.entrySet()) {
System.out.println("Key = " + entry.getKey() + ", Value = " + entry.getValue());
Bean bean = (Bean) entry.getValue();
Object beanObj = Class.forName(bean.getClassName()).newInstance();
applicActionContext.put(bean.getName(), beanObj);
for(Property property : bean.getProperties()){
String methodName = "set" + property.getName().substring(0, 1).toUpperCase() + property.getName().substring(1);
if(property.getValue()!=null){//属性注入
BeanUtils.setProperty(beanObj, property.getName(), property.getValue());
}
if(StringUtils.isNotBlank(property.getRef())){//依赖注入
Bean vbBean = (Bean) map.get(property.getRef());
Object o = null;
if(null==applicActionContext.get(vbBean.getName())){
o = Class.forName(vbBean.getClassName()).newInstance();
applicActionContext.put(vbBean.getName(),o);
}else {
o = applicActionContext.get(vbBean.getName());
}
Method method = beanObj.getClass().getMethod(methodName, o.getClass());
method.invoke(beanObj, o);
}
}
}
}
}
简单的demo 用于更清楚的了解 spring的注入原理。spring IOC都知道
demo 下载地址