packagecom.mengya.context;importjava.beans.Introspector;importjava.beans.PropertyDescriptor;importjava.lang.reflect.Field;importjava.lang.reflect.Method;importjava.util.HashMap;importjava.util.List;importjava.util.Map;importorg.apache.commons.beanutils.BeanUtils;importcom.mengya.spring.annotation.MyResource;importcom.mengya.spring.bean.BeanDefinition;importcom.mengya.spring.bean.PropertyDefinition;importcom.mengya.spring.util.ReadXMLUtil;public classMengyaClassPathXMLApplicationContext {private List beanDefintionList = null;private Map sigletons = new HashMap();/*** 容器初始化时 传入配置文件名称 读取配置文件..实例化bean
*
*@paramconfigFileName*/
publicMengyaClassPathXMLApplicationContext(String configFileName) {
beanDefintionList=ReadXMLUtil.readXMLBeanDefintion(configFileName);this.instanceBeans();this.injectObject();this.annotationInject();
}/*** 注解实现依赖注入
**/
private voidannotationInject() {/*** 遍历bean,获取bean里的所有属性描述对象,遍历属性描述对象数组.
* ---获取属性的setter方法.如果该属性setter方法存在,判断方法上是否有MyResource注解,
* 如果有,获取注解对象,通过注解对象获取name值
* 如果name值存在:根据name值查找Map中是否有该名称的bean,如果有,调用该属性的setter方法执行注入.
* 如果name值不存在:获取该属性的名称,从map中查找是否有此名称的bean. 如果有:调用setter方法注入
* 没有:获取该属性的类型,遍历map查找map中是否有和此属性类型一致的bean,如果有,则执行注入
*
* ---获取该属性,判断该属性上是否有MyResource注解 如果有:获取该注解的对象,通过该对象获取name值
* 如果name值存在:根据name值查找map中是否有该bean如果有则执行注入
* 如果name值不存在:获取该属性的名称,查找map中是否有该名称的bean 如果有:执行注入 没有:获取该属性的类型
* 遍历map中判断是否有和该类型一致的bean
**/
for(String beanName : sigletons.keySet()) {
System.out.println("beanName: " +beanName);
Object bean=getBean(beanName);
System.out.println("bean:" +bean.toString());if (null !=bean) {try{//获取所有的属性
PropertyDescriptor pd[] =Introspector.getBeanInfo(bean.getClass()).getPropertyDescriptors();for(PropertyDescriptor descriptor : pd) {//获取set方法
Method setter =descriptor.getWriteMethod();//若在set方法设置了MyResource注解
if (null != setter && setter.isAnnotationPresent(MyResource.class)) {
MyResource myResource= setter.getAnnotation(MyResource.class);
String diName= null;
Object diObject= null;//设置了name属性值
if (null != myResource.name() && !"".equals(myResource.name())) {
diName=myResource.name();
}else {//按默认的属性值装配置
diName =descriptor.getName();
}
diObject=getBean(diName);
setter.setAccessible(true);
setter.invoke(bean, diObject);
}
}//获取所有字段
Field[] fields =bean.getClass().getDeclaredFields();for(Field field : fields) {if (field.isAnnotationPresent(MyResource.class)) {
MyResource myResource= field.getAnnotation(MyResource.class);
String diName= null;
Object diObject= null;//设置了name属性值
if (null != myResource.name() && !"".equals(myResource.name())) {
diName=myResource.name();
}else {//按默认的属性值装配置
diName =field.getName();
}
diObject=getBean(diName);
field.setAccessible(true);
field.set(bean, diObject);
}
}
}catch(Exception e) {
e.printStackTrace();
}
}
}
}/*** 注入Bean
**/
private voidinjectObject() {for(BeanDefinition beanDefinition : beanDefintionList) {
Object obj=getBean(beanDefinition.getId());if (null !=obj) {
List propertys =beanDefinition.getPropertys();if (null != propertys && propertys.size() > 0) {try{//通过Java的内省机制获取到对象中所有属性的描述信息
PropertyDescriptor[] ps =Introspector.getBeanInfo(obj.getClass()).getPropertyDescriptors();for(PropertyDescriptor descriptor : ps) {for(PropertyDefinition property : propertys) {//判断XML文件中解析出来的属性和对象中的属性名称是否一样
if(descriptor.getName().equals(property.getName())) {if (null != property.getRef() && !"".equals(property.getRef())) {
Object diObject=getBean(property.getRef());
descriptor.getWriteMethod().invoke(obj, diObject);
}else{
BeanUtils.setProperty(obj, property.getName(), property.getValue());
}
}
}
}
}catch(Exception e) {
e.printStackTrace();
}
}
}
}
}/*** 实例化Bean
**/
private voidinstanceBeans() {for(BeanDefinition beanDefinition : beanDefintionList) {try{
Object obj=Class.forName(beanDefinition.getClassName()).newInstance();this.sigletons.put(beanDefinition.getId(), obj);
}catch(Exception e) {
e.printStackTrace();
}
}
System.out.println("this.sigletons: " + this.sigletons.toString());
}/*** 获取Bean实例
*
*@parambeanName
*@return
*/
publicObject getBean(String beanName) {return this.sigletons.get(beanName);
}
}