加载解析配置bean文件
利用反射实例化bean
通过工厂模式获取实例
用map表示容器
一、加载xml配置文件
public class XmlConfig {
/**
* 功能描述:加载配置文件,获取所有的bean
* @param path 配置路径
* @return 所有bean的map
*/
public static Map<String, Bean> getConfig(String path){
Map<String, Bean> config = new HashMap<String, Bean>();
// 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<Element> 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<Element> properties = element.elements("property");
List<Property> pros = new ArrayList<Property>();
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<String, Object> ioc;
private Map<String, Bean> config;
/**
* 功能描述:初始化
*/
public ClassPathXmlApplicationContext(String path){
this.ioc = new HashMap<String, Object>();
this.config = XmlConfig.getConfig(path);
for (Map.Entry<String, Bean> entry : this.config.entrySet()) {
String key = entry.getKey();
Bean bean = entry.getValue();
Object value = createBean(bean);
this.ioc.put(key, value);
}
}
/**
* 功能描述:创建bean实例
* @param bean
* @return
*/
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<Property> 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);
}
四、测试类
/**
* IOC容器
* 工厂模式
*
*/
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<Property> properties = new ArrayList<Property>();
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<Property> 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;
}
}