加载解析配置bean文件
利用反射实例化bean
通过工厂模式获取实例
用map表示容器
一、加载xml配置文件
public class XmlConfig {
public static Map getConfig(String path){
Map config = new HashMap();
// 1、读取applicationContext
InputStream inputStream = XmlConfig.class.getResourceAsStream(path);
SAXReader reader = new SAXReader();
document read = null;
try {
read = reader.read(inputStream);
} catch (documentException e) {
e.printStackTrace();
throw new RuntimeException("配置文件错误,请检查");
}
Element rootElement = read.getRootElement();
List elements = rootElement.elements("bean");
if (elements == null){
return config;
}
for (Element element : elements) {
Bean bean = new Bean();
// 获取bean的id和class
String id = element.attributevalue("id");
String className = element.attributevalue("class");
bean.setId(id);
bean.setClassName(className);
List properties = element.elements("property");
List pros = new ArrayList();
if (properties != null){
for (Element property : properties) {
Property pro = new Property();
// 加载参数
String name = property.attributevalue("name");
String value = property.attributevalue("value");
String ref = property.attributevalue("ref");
pro.setName(name);
pro.setValue(value);
pro.setRef(ref);
bean.getProperties().add(pro);
}
}
// 校验id不重复
if (config.containsKey(id)){
throw new RuntimeException("bean节点ID重复:" + id);
}
config.put(id, bean);
}
return config;
}
}
二、实例化bean
public class ClassPathXmlApplicationContext implements BeanFactory {
private Map ioc;
private Map config;
public ClassPathXmlApplicationContext(String path){
this.ioc = new HashMap();
this.config = XmlConfig.getConfig(path);
for (Map.Entry entry : this.config.entrySet()) {
String key = entry.getKey();
Bean bean = entry.getValue();
Object value = createBean(bean);
this.ioc.put(key, value);
}
}
public Object createBean(Bean bean){
// 利用反射,获取bean实例
Class> clazz = null;
try {
clazz = Class.forName(bean.getClassName());
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("配置的class不合理");
}
Object instance = null;
try {
instance = clazz.newInstance();
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("创建bean实例失败");
}
List properties = bean.getProperties();
if (properties == null){
return instance;
}
for (Property property : properties) {
String name = property.getName();
String value = property.getValue();
String ref = property.getRef();
if(value != null){
Field field = null;
try {
field = clazz.getDeclaredField(name);
field.setAccessible(true);
field.set(instance, value);
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("属性名称不合法");
}
}
if(ref != null){
try{
Field field = clazz.getDeclaredField(name);
field.setAccessible(true);
Object obj = ioc.get(ref);
field.set(instance, obj);
}catch (Exception e){
e.printStackTrace();
throw new RuntimeException("没有找到依赖的对象");
}
}
}
return instance;
}
public Object getBean(String id){
return this.ioc.get(id);
}
}
三、工厂模式获取实例
public interface BeanFactory {
Object getBean(String beanName);
}
四、测试类
public class AppTest {
public static void main(String[] args) {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("/AppContext.xml");
User fundUser = (User)context.getBean("user");
System.out.println(fundUser.toString());
}
}
五、其它类
// Bean
public class Bean {
private String id;
private String className;
private List properties = new ArrayList();
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 getProperties() {
return properties;
}
}
// Property
public class Property {
private String name;
private String value;
private String ref;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public String getRef() {
return ref;
}
public void setRef(String ref) {
this.ref = ref;
}
}



