美文网首页
Spring中如何实现bean的自动装载之简化

Spring中如何实现bean的自动装载之简化

作者: 刘荣杰 | 来源:发表于2021-05-18 09:38 被阅读0次

bean的自动装载是通过BeanFactory实现的,那么beanfactory是如何完成自动加载的呢?我们学过Spring都知道装载的逻辑实在xml中,如何根据xml实现bean装配
xml配置文件:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    <bean id="HelloChina" class="cn.lovepi.chapter01.HelloChina">
 
    </bean>
    <bean id="HelloWorld" class="cn.lovepi.chapter01.HelloWorld">
 
    </bean>
    <bean id="Person" class="cn.lovepi.chapter01.Person">
        <!--bean中属性配置,属性即为类中所声明的接口变量。给其添加了一个引用-->
        <property name="iHelloMessage" ref="HelloWorld">
        </property>
    </bean>
</beans>

学习了Java反射机制的我们知道得到了Class就可以得到该类全部信息,可以得到构造函数进行实例化,而如何得到Class对象呢,发现没class都给定了全限定名,我们通过Class.forname得到Class对象,进行实例化得到实例即bean,那么提供property得即通过反射得到method运行相应set函数。

BeanFactory:

public class BeanFactory {
 
    private Map<String, Object> beanMap = new HashMap<String, Object>();
 
    /**
     * bean工厂的初始化.
     * 
     * @param xml xml配置文件
     */
    public void init(String xml) {
        try {
            //1.创建读取配置文件的reader对象
            SAXReader reader = new SAXReader();
            //2.获取当前线程中的类装载器对象
            ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
            //3.从class目录下获取指定的xml文件
            InputStream ins = classLoader.getResourceAsStream(xml);
            Document doc = reader.read(ins);
            Element root = doc.getRootElement();
            Element foo;
            
            //4.遍历xml文件当中的Bean实例
            for (Iterator i = root.elementIterator("bean"); i.hasNext();) {
                foo = (Element) i.next();
                
                //5.针对每个一个Bean实例,获取bean的属性id和class
                Attribute id = foo.attribute("id");
                Attribute cls = foo.attribute("class");
                
                //6.利用Java反射机制,通过class的名称获取Class对象
                Class bean = Class.forName(cls.getText());
                //7.获取对应class的信息
                java.beans.BeanInfo info = java.beans.Introspector.getBeanInfo(bean);
                //8.获取其属性描述
                java.beans.PropertyDescriptor pd[] = info.getPropertyDescriptors();
 
                //9.创建一个对象,并在接下来的代码中为对象的属性赋值
                Object obj = bean.newInstance();
                
                //10.遍历该bean的property属性
                for (Iterator ite = foo.elementIterator("property"); ite.hasNext();) {
                    Element foo2 = (Element) ite.next();
                    
                    //11.获取该property的name属性
                    Attribute name = foo2.attribute("name");
                    String value = null;
                    
                    //12.获取该property的子元素value的值
                    for (Iterator ite1 = foo2.elementIterator("value"); ite1.hasNext();) 
                    {
                        Element node = (Element) ite1.next();
                        value = node.getText();
                        break;
                    }
                    
                    //13.利用Java的反射机制调用对象的某个set方法,并将值设置进去 
                    for (int k = 0; k < pd.length; k++) {
                        if (pd[k].getName().equalsIgnoreCase(name.getText())) 
                        {
                            Method mSet = null;
                            mSet = pd[k].getWriteMethod();
                            mSet.invoke(obj, value);
                        }
                    }
                }
 
                //14.将对象放入beanMap中,其中key为id值,value为对象
                beanMap.put(id.getText(), obj);
            }
        } catch (Exception e) {
            System.out.println(e.toString());
        }
    }
 
    /**
     * 通过bean的id获取bean的对象.
     * 
     * @param beanName
     *            bean的id
     * @return 返回对应对象
     */
    public Object getBean(String beanName) {
        Object obj = beanMap.get(beanName);
        return obj;
    }
 
    /**
     * 测试方法.
     * 
     * @param args
     */
    public static void main(String[] args) {
        BeanFactory factory = new BeanFactory();
        factory.init("src/conf/config.xml");
        JavaBean javaBean = (JavaBean) factory.getBean("javaBean");
        System.out.println("userName=" + javaBean.getUserName());
        System.out.println("password=" + javaBean.getPassword());
    }
}

总结就是利用反射运行相应的set函数。

相关文章

网友评论

      本文标题:Spring中如何实现bean的自动装载之简化

      本文链接:https://www.haomeiwen.com/subject/kwkjjltx.html