Spring记录之模拟IoC(二)

本文详细介绍了如何模拟Spring的IoC容器2.0,利用Introspector进行Java Bean属性和依赖关系的设置。通过解析XML文件,创建Bean对象并封装到Map中,实现了对象的注入和依赖管理。在测试部分展示了不同scope下对象的创建情况,验证了单例和非单例模式的工作原理。
摘要由CSDN通过智能技术生成

模拟Spring IoC容器 2.0

Spring的IoC容器通过解析xml文件,读取当中的配置关系,从而在对象中注入值或其他对象。反射机制在当中扮演重要角色,为了更简便地操作反射,Java中有一种技术Introspector(网上翻译为内省),模拟中,有了它,配置Bean标签的属性和依赖关系,会简便得多。当然,直接用反射也是可以的。

Introspector

  • java.beans.Introspector

源码如是说:Introspector 提供一种标准方法来访问目标Java Bean的属性、事件、方法。对于一个Java Bean的这3种信息,Introspector 会别分析,还会分析父类的这3种信息,不论是显式还是隐式。Introspector会根据这些信息创建一个BeanInfo对象来描述这个Java Bean。就像有个Class类来描述class,当中渗透着面向对象思想。

此2.0模拟,运用面向对象思想,把xml解析出来的对象封装到Bean对象中

The Introspector class provides a standard way for tools to learn about the properties, events, and methods supported by a target Java Bean.

该技术的关键方法有

  • getBeanInfo(),获得JavaBean的信息。JDK1.7后,增加能够标识分析到哪个父类为止的方法重载
public static BeanInfo getBeanInfo(Class<?> beanClass, Class<?> stopClass, int flags){...}
//Instrospect一个Java Bean,获取其属性、事件、方法。若已经Instropect过,则从缓存中取相关信息
 public static BeanInfo getBeanInfo(Class<?> beanClass)
        throws IntrospectionException
    {
        if (!ReflectUtil.isPackageAccessible(beanClass)) {
            return (new Introspector(beanClass, null, USE_ALL_BEANINFO)).getBeanInfo();
        }
        ThreadGroupContext context = ThreadGroupContext.getContext();
        BeanInfo beanInfo;
        synchronized (declaredMethodCache) {
            beanInfo = context.getBeanInfo(beanClass);
        }
        if (beanInfo == null) {
            beanInfo = new Introspector(beanClass, null, USE_ALL_BEANINFO).getBeanInfo();
            synchronized (declaredMethodCache) {
                context.putBeanInfo(beanClass, beanInfo);
            }
        }
        return beanInfo;
    }
  • getPropertyDescriptors(),获得属性的描述,可以采用遍历BeanInfo的方法,来查找、设置类的属性。该方法在BeanInfo类下。Spring的org.springframework.beans.ExtendedBeanInfo继承了BeanInfo.源码如下:
public ExtendedBeanInfo(BeanInfo delegate) throws IntrospectionException {
        this.delegate = delegate;
        //获取属性描述器
        for (PropertyDescriptor pd : delegate.getPropertyDescriptors()) {
            try {
                this.propertyDescriptors.add(pd instanceof IndexedPropertyDescriptor ?
                        new SimpleIndexedPropertyDescriptor((IndexedPropertyDescriptor) pd) :
                        new SimplePropertyDescriptor(pd));
            }
            catch (IntrospectionException ex) {
                // 可能没有按照JavaBean规范些方法...
                if (logger.isDebugEnabled()) {
                    logger.debug("Ignoring invalid bean property '" + pd.getName() + "': " + ex.getMessage());
                }
            }
        }
        //获取方法描述器
        MethodDescriptor[] methodDescriptors = delegate.getMethodDescriptors();
        if (methodDescriptors != null) {
        //获取setter
            for (Method method : findCandidateWriteMethods(methodDescriptors)) {
                try {
                    handleCandidateWriteMethod(method);
                }
                catch (IntrospectionException ex) {
                    // We're only trying to find candidates, can easily ignore extra ones here...
                    if (logger.isDebugEnabled()) {
                        logger.debug("Ignoring candidate write method [" + method + "]: " + ex.getMessage());
                    }
                }
            }
        }
    }

对于内省操作,Apache开发了一套简单、易用的API来操作Bean的属性——BeanUtils工具包,地址http://commons.apache.org/proper/commons-beanutils/

模拟IoC 2.0

目录结构

这里写图片描述

准备xml文件


                
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值