编码实现Spring 利用@Resource注解实现bean的注入,xml实现基本数据类型的注入
首先分析。
1: 肯定要利用dom4j读取xml配置文件,将所有的bean的配置信息读取出来
2: 利用反射技术,实例化所有的bean
3: 写注解处理器, 利用注解和内省实现依赖对象的注入。
4: 利用XML中<property>信息,通过内省beanUtils实现基本数据类型的注入
实现:
package cn.gbx.example; import java.beans.IntrospectionException; import java.beans.Introspector; import java.beans.PropertyDescriptor; import java.io.File; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.net.URL; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.commons.beanutils.ConvertUtils; import org.dom4j.Document; import org.dom4j.Element; import org.dom4j.XPath; import org.dom4j.io.SAXReader; public class MyClassPathXmlApplicationContext { private List<DefBean> defBeans = new ArrayList<DefBean>(); private Map<String, Object> singletons = new HashMap<String, Object>(); public MyClassPathXmlApplicationContext(String filename) { this.readXML(filename); this.instanceBean(); this.injectAnotation(); this.injectXML(); } //注入基本类型的属性 private void injectXML() { //枚举bean for (DefBean defBean : defBeans) { Object bean = singletons.get(defBean.getId()); if (bean != null) { //枚举该bean的Property看有没有基本数据类型的注入 for (DefProperty defProperty : defBean.getDefPropertys()) { if (defProperty.getValue() != null){ try { PropertyDescriptor[] ps = Introspector.getBeanInfo(bean.getClass()).getPropertyDescriptors(); for (PropertyDescriptor p : ps) { if (p.getName().equals(defProperty.getName())) { Method setter = p.getWriteMethod(); //保证有set方法 if (setter != null) { Object value = ConvertUtils.convert(defProperty.getValue(), p.getPropertyType()); setter.setAccessible(true); setter.invoke(bean, value); } break; } } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } } } //注解处理器 private void injectAnotation() { //枚举实例化的bean for (String key : singletons.keySet()) { Object bean = singletons.get(key); if (bean != null) { /* * 检查setter方法 */ try { PropertyDescriptor[] ps = Introspector.getBeanInfo(bean.getClass()).getPropertyDescriptors(); //枚举每个bean的属性 for (PropertyDescriptor p : ps) { Method setter = p.getWriteMethod(); Object value = null; //存在set方法, 并且有setter上边有Resource注解 if (setter != null && setter.isAnnotationPresent(GbxResource.class)){ GbxResource gbxResource = setter.getAnnotation(GbxResource.class); //若有name 则按name查找 if (gbxResource.name() != null && !"".equals(gbxResource.name())) { value = singletons.get(gbxResource.name()); } else { //若没有,先安名字查找, 再按数据类型查找 value = singletons.get(p.getName()); if (value == null) { for (String key2 : this.singletons.keySet()) { if (p.getPropertyType().isAssignableFrom(this.singletons.get(key2).getClass())) { value = this.singletons.get(key2); break; } } } } setter.setAccessible(true); setter.invoke(bean, value); } } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } /* * 检查字段 */ Field[] fileds = bean.getClass().getDeclaredFields(); for (Field field : fileds) { if (field.isAnnotationPresent(GbxResource.class)) { GbxResource gbxResource = field.getAnnotation(GbxResource.class); Object value = null; if (gbxResource.name() != null && !"".equals(gbxResource.name())) { value = this.singletons.get(gbxResource.name()); } else { value = this.singletons.get(field.getName()); if (value == null) { for (String key2 : this.singletons.keySet()) { if (field.getType().isAssignableFrom(this.singletons.get(key2).getClass())) { value = this.singletons.get(key2); break; } } } } field.setAccessible(true); try { field.set(bean, value); } catch (IllegalAccessException e) { e.printStackTrace(); } } } } } } //实例化bean对象 private void instanceBean() { for (DefBean bean : defBeans) { System.out.println(bean.getId() + " : " + bean.getClassName()); if (bean.getClassName() != null && !"".equals(bean.getClassName())) { try { singletons.put(bean.getId(), Class.forName(bean.getClassName()).newInstance()); } catch (Exception e) { e.printStackTrace(); } } } } //读取xml文件 private void readXML(String filename) { SAXReader reader = new SAXReader(); Document document = null; URL xmlPath = this.getClass().getClassLoader().getResource(filename); try { //的到document document = reader.read(xmlPath); //设置命名空间 Map<String, String> nsMap = new HashMap<String, String>(); nsMap.put("ns", "http://www.springframework.org/schema/beans"); //创建查询路径 XPath xPath = document.createXPath("//ns:beans/ns:bean"); xPath.setNamespaceURIs(nsMap); List<Element> beans = xPath.selectNodes(document); DefBean defBean = null; for (Element e : beans) { String id = e.attributeValue("id"); String className = e.attributeValue("class"); defBean = new DefBean(id, className); XPath xPath2 = e.createXPath("ns:property"); xPath2.setNamespaceURIs(nsMap); List<Element> propertys = xPath2.selectNodes(e); DefProperty defProperty = null; for (Element e2 : propertys) { String name = e2.attributeValue("name"); String ref = e2.attributeValue("ref"); String value = e2.attributeValue("value"); defProperty = new DefProperty(name, ref, value); defBean.getDefPropertys().add(defProperty); } defBeans.add(defBean); } } catch (Exception e) { e.printStackTrace(); } } public Object getBean(String key) { return singletons.get(key); } }
package cn.gbx.serviceimpl; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Properties; import java.util.Set; import javax.annotation.Resource; import org.springframework.beans.factory.annotation.Autowired; import cn.gbx.daoimpl.PersonDao; import cn.gbx.example.GbxResource; import cn.gbx.service.PersonService; public class PersonServiceImpl implements PersonService { @GbxResource private PersonDao personDao; private String name; public void save() { personDao.save(); System.out.println("Name = " + name); System.out.println("service层的 save方法"); } public void setPersonDao(PersonDao personDao) { this.personDao = personDao; } public String getName() { return name; } public void setName(String name) { this.name = name; } public PersonDao getPersonDao() { return personDao; } }
注解:
package cn.gbx.example; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.METHOD, ElementType.FIELD}) public @interface GbxResource { public String name() default ""; }