首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 软件管理 > 软件架构设计 >

Spring2.5 IOC的容易实现

2012-10-07 
Spring2.5 IOC的简单实现1、定义一个接口package com.css.framework.contextpublic interface MyApplicati

Spring2.5 IOC的简单实现

1、定义一个接口

package com.css.framework.context;public interface MyApplicationContext {/** * 获取bean的实例 * @param beanName * @return */public Object getBean(String beanName);}

??2、Bean节点的描述文件

package com.css.framework.beans.factory.config;import java.util.ArrayList;import java.util.List;/** * Spring Bean 的描述文件 *  * @author Administrator *  */public class BeanDefinition {    //Bean节点中的id属性private String id;//Bean节点中的className属性private String className;/** * Bean节点中的属性描述property节点 */private List<PropertyDefinition> properties  = new ArrayList<PropertyDefinition>();public String getId() {return id;}public BeanDefinition(String id, String className) {super();this.id = id;this.className = className;}public void setId(String id) {this.id = id;}public String getClassName() {return className;}public void setClassName(String className) {this.className = className;}    public List<PropertyDefinition> getProperties() {        return properties;    }    public void setProperties(List<PropertyDefinition> properties) {        this.properties = properties;    }}

?

package com.css.framework.beans.factory.config;/**** <p>Title: property节点的描述文件 </p>* <p>Description: property节点的描述文件</p>* <p>Copyright: Copyright (c) 2010,CSS</p>* <p>Company: CSS</p>* @author 章殷* @date 2010-6-19* @version 1.0*/public class PropertyDefinition {    private String name;    private String ref;    private String value;    public String getValue() {        return value;    }    public void setValue(String value) {        this.value = value;    }    public PropertyDefinition(String name, String ref,String value) {        super();        this.name = name;        this.ref = ref;        this.value = value;    }    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    public String getRef() {        return ref;    }    public void setRef(String ref) {        this.ref = ref;    }}

?

4、关键的实现类

package com.css.framework.context;import java.beans.IntrospectionException;import java.beans.Introspector;import java.beans.PropertyDescriptor;import java.lang.reflect.Field;import java.lang.reflect.InvocationTargetException;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.DocumentException;import org.dom4j.Element;import org.dom4j.XPath;import org.dom4j.io.SAXReader;import com.css.framework.annotation.MyResource;import com.css.framework.beans.factory.config.BeanDefinition;import com.css.framework.beans.factory.config.PropertyDefinition;import com.css.inter.IConstructorServiceBean;/**** <p>Title: 加载beans.xml文件 </p>* <p>Description: 加载xml文件,实例化文件中的Bean,并实现IOC</p>* <p>Copyright: Copyright (c) 2010,CSS</p>* <p>Company: CSS</p>* @author 章殷* @date 2010-6-19* @version 1.0*/public class MyClassPathXmlApplicationContext implements MyApplicationContext {    //所有的bean的描述文件列表    private List<BeanDefinition> beanDefines = new ArrayList<BeanDefinition>();    //定义所有的实例化的Bean    private Map<String, Object> sigletons = new HashMap<String, Object>();    public MyClassPathXmlApplicationContext(String filename) {        //加载配置文件        readXml(filename);        //实例化配置文件中的Bean        instanceBeans();        //使用注解方法进行注入        annotationInject();        //给Bean注入对象        injectObject();    }    /**     * <p> 使用注解的方式,将对象注入到实例Bean中。</p>     * @author 章 殷     * @date 2010-6-19     */    private void annotationInject() {        //循环所有实例化的Bean        for (String beanName : sigletons.keySet()) {            //获取Bean            Object bean = sigletons.get(beanName);            if (bean != null) {                try {                    //通过属性注入                    propertyInject(bean);                    //通过字段注入,包括字段的名称                    fieldInject(bean);                } catch (Exception e) {                    // TODO Auto-generated catch block                    e.printStackTrace();                }            }        }    }    /**     * <p> 通过属性名属性类型进行注入。</p>     * @param bean     * @throws IntrospectionException     * @throws IllegalAccessException     * @throws InvocationTargetException     * @author 章 殷     * @date 2010-6-19     */    private void propertyInject(Object bean) throws IntrospectionException, IllegalAccessException,                    InvocationTargetException {        //获取Bean的属性描述信息,通过setter方法进行注入        PropertyDescriptor[] ps = Introspector.getBeanInfo(bean.getClass()).getPropertyDescriptors();        for (PropertyDescriptor propertyDesc : ps) {            //获取属性的setter方法            Method setter = propertyDesc.getWriteMethod();            //判断setter方法是否存储,时候存在MyResource注解            if (setter != null && setter.isAnnotationPresent(MyResource.class)) {                //获取属性的注解                MyResource resource = setter.getAnnotation(MyResource.class);                Object value = null;                //判断注解的name值是否为空,是否为空字符                if (resource.name() != null && !"".equals(resource.name())) {                    //从容器中取出name对应的对象                    value = sigletons.get(resource.name());                }                //下面的方法是通过属性名和属性的类型来查找实例Bean                else {                    //通过属性名来查找对应的实体Bean                    value = sigletons.get(propertyDesc.getName());                    if (value == null) {                        //通过属性的类型来查找对应的实体Bean                        for (String key : sigletons.keySet()) {                            // 循环所有的容器Bean,判断属性的类型和容器中的类型是否匹配                            if (propertyDesc.getPropertyType().isAssignableFrom(sigletons.get(key).getClass())) {                                value = sigletons.get(key);                                break;                            }                        }                    }                }                setter.setAccessible(true);//如果是私有的方法,设置该值为true,就可以调用该setter方法                setter.invoke(bean, value); //把引用注入到Bean中            }        }    }    /**     * <p> 通过字段名进行实例注入。</p>     * @param bean     * @throws IllegalAccessException     * @author 章 殷     * @date 2010-6-19     */    private void fieldInject(Object bean) throws IllegalAccessException {        //获取Bean的所有字段信息        Field[] fields = bean.getClass().getDeclaredFields();        for (Field field : fields) {            //判断字段上是否存在MyResource注解            if (field.isAnnotationPresent(MyResource.class)) {                MyResource resource = field.getAnnotation(MyResource.class);                Object value = null;                //通过注解的Name属性来查询实体Bean                if (resource.name() != null && !"".equals(resource.name())) {                    value = sigletons.get(resource.name());                }                //通过字段的名称和字段类型来查询实例Bean                else {                    value = sigletons.get(field.getName());//通过属性名来查找                    if (value == null) {                        for (String key : sigletons.keySet()) {                            if (field.getType().isAssignableFrom(sigletons.get(key).getClass())) {                                value = sigletons.get(key);                                break;                            }                        }                    }                }                field.setAccessible(true);//设置私有的属性可以进行访问                field.set(bean, value); //将应用注入到属性中            }        }    }    /**     * <p> IOC的Spring的实现,该方法是用的是属性注入,可以注入依赖对象和基本数据类型。</p>     * @author 章 殷     * @date 2010-6-18     */    private void injectObject() {        System.out.println("============开始进行IOC注入==============");        //循环所有的beanDefines        for (BeanDefinition beanDefinition : beanDefines) {            //获取实例化后的bean            Object bean = sigletons.get(beanDefinition.getId());            if (bean != null) {                //获取实例化后的Bean的属性描述西西里                try {                    PropertyDescriptor[] ps = Introspector.getBeanInfo(bean.getClass()).getPropertyDescriptors();                    for (PropertyDefinition propertyDefinition : beanDefinition.getProperties()) {                        for (PropertyDescriptor propertyDescriptor : ps) {                            Method setter = null;                            //判断Bean的属性名 与 property节点中的Name值是否相同                            if (propertyDefinition.getName().equals(propertyDescriptor.getName())) {                                setter = propertyDescriptor.getWriteMethod();//获取实例化Bean的set方法                                if (setter != null) {                                    Object value = null;                                    //如果引用存在,注入依赖对象                                    if (propertyDefinition.getRef() != null                                                    && !"".equals(propertyDefinition.getRef().trim())) {                                        value = sigletons.get(propertyDefinition.getRef());//从容器中获取ref的Bean                                    }                                    //注入基本数据类型                                    else {                                        value = ConvertUtils.convert(propertyDefinition.getValue(), propertyDescriptor                                                        .getPropertyType());                                    }                                    setter.setAccessible(true);//如果是私有的方法,设置该值为true,就可以调用该setter方法                                    setter.invoke(bean, value); //把引用注入到Bean中                                    System.out.println("注入[" + beanDefinition.getClassName() + "]的"                                                    + propertyDefinition.getName() + "属性成功");                                }                            }                        }                    }                } catch (Exception e) {                    System.err.println("注入【" + beanDefinition.getClassName() + "】时出错!");                }            }        }        System.out.println("============IOC注入完成==============");        System.out.println("");    }    /**     * <p> 实例化beanDefines中的所有Bean。</p>     * @author 章 殷     * @date 2010-6-18     */    private void instanceBeans() {        System.out.println("============开始实例化Bean==============");        for (BeanDefinition beanDefinition : beanDefines) {            try {                if (beanDefinition.getClassName() != null && !"".equals(beanDefinition.getClassName().trim())) {                    sigletons.put(beanDefinition.getId(), Class.forName(beanDefinition.getClassName()).newInstance());                    System.out.println("实例化[" + beanDefinition.getClassName() + "]成功!");                }            } catch (Exception e) {                System.err.println("实例化[" + beanDefinition.getClassName() + "]时出错!");                e.printStackTrace();            }        }        System.out.println("============实例化Bean完成==============");        System.out.println("");    }    /**     * <p> 读取bean.xml文件,将xml的描述文件转换为java描述文件。</p>     * @param filename     * @author 章 殷     * @date 2010-6-18     */    @SuppressWarnings("unchecked")    private void readXml(String filename) {        System.out.println("============开始加载配置文件" + filename + "==============");        SAXReader saxReader = new SAXReader();        Document document = null;        URL xmlpath = this.getClass().getClassLoader().getResource(filename);        try {            document = saxReader.read(xmlpath);            Map<String, String> nsMap = new HashMap<String, String>();            nsMap.put("ns", "http://www.springframework.org/schema/beans");            //定位到beans/bean节点下            XPath xsub = document.createXPath("//ns:beans//ns:bean");            xsub.setNamespaceURIs(nsMap); //设置命名空间            List<Element> beans = xsub.selectNodes(document); //获取xml中所有的bean节点            for (Element element : beans) {                String id = element.attributeValue("id"); //获取属性id的值                String clazz = element.attributeValue("class");//获取属性class的值                BeanDefinition beanDefinition = new BeanDefinition(id, clazz);                //将Bean.xml文件中的property节点映射到beanDefinition                XPath propertySub = element.createXPath("ns:property"); //创建property的相对路径                propertySub.setNamespaceURIs(nsMap);                List<Element> propertis = propertySub.selectNodes(element);                for (Element property : propertis) {                    String propertyName = property.attributeValue("name");                    String propertyRef = property.attributeValue("ref");                    String propertyValue = property.attributeValue("value");                    beanDefinition.getProperties().add(                                    (new PropertyDefinition(propertyName, propertyRef, propertyValue)));                    System.out.println(">>>>:加载属性[" + clazz + ".(" + propertyRef + ")]成功!");                }                beanDefines.add(beanDefinition);                System.out.println(">>>>:加载类[" + clazz + "]成功!");            }        } catch (DocumentException e) {            System.err.println("加载配置文件<" + xmlpath + ">时出错!");            e.printStackTrace();        }        System.out.println("============配置文件" + filename + "加载完成==============");        System.out.println("");    }    /**     * 获取bean的实例     * @param beanName     * @return     */    public Object getBean(String beanName) {        return sigletons.get(beanName);    }    public static void main(String[] args) {        MyApplicationContext context = new MyClassPathXmlApplicationContext("beans.xml");        //        IPersonServiceBean personService = (IPersonServiceBean) context.getBean("personService");        //        personService.save();        IConstructorServiceBean constructor = (IConstructorServiceBean) context.getBean("constructorServiceBean");        constructor.save();    }}

?

热点排行