【Spring4揭秘 BeanFactory】InstantiationStrategy和BeanWrapper

一、InstantiationStrategy

BeanDefinition加入到注册中,并由BeanFactoryPostProcessor的实现类处理后,需要由InstantiationStrategy负责实例化。实例化仅仅是调用构造函数,相当于new了一个对象而已,bean的具体的属性在此时并未赋值 。InstantiationStrategy负责由Bean类的默认构造函数、带参构造函数或者工厂方法等来实例化Bean。

public interface InstantiationStrategy {


    Object instantiate(RootBeanDefinition bd, String beanName, BeanFactory owner)
            throws BeansException;


    Object instantiate(RootBeanDefinition bd, String beanName, BeanFactory owner,
            Constructor<?> ctor, Object... args) throws BeansException;

    Object instantiate(RootBeanDefinition bd, String beanName, BeanFactory owner,
            Object factoryBean, Method factoryMethod, Object... args) throws BeansException;

}

SimpleInstantiationStrategy

是InstantiationStrategy的实现类,该类是一个简单的用于Bean实例化的类,比如,由Bean类的默认构造函数、带参构造函数或者工厂方法等来实例化Bean。

public class StrategyTest {
    private String name;


    private StrategyTest() {
    }

    public StrategyTest(String name) {
        this.name = name;
    }

    private StrategyTest getIntance(String name) {
        return new StrategyTest(name);
    }

    @Override
    public String toString() {
        return "name is " + name;
    }

    public static void main(String[] args) throws NoSuchMethodException {

        RootBeanDefinition definition = new RootBeanDefinition(StrategyTest.class);

        SimpleInstantiationStrategy strategy = new SimpleInstantiationStrategy();

        //因为没有用到BeanFactory和BeanName,所以参数中都设置为null
        //默认构造器
        StrategyTest test = (StrategyTest) strategy.instantiate(definition, null, null);
        System.out.println(test);//输出【name is null】

        //带参数的构造器
        Constructor<StrategyTest> constructor = StrategyTest.class.getConstructor(String.class);
        StrategyTest test2 = (StrategyTest) strategy.instantiate(definition, null, null, constructor, "Jack");
        System.out.println(test2);//输出【name is Jack】

        //private的工厂方法
        Method method = StrategyTest.class.getDeclaredMethod("getIntance", String.class);//因为是private,所以要使用getDeclaredMethod
        StrategyTest test3 = (StrategyTest) strategy.instantiate(definition, null, null, new StrategyTest(), method, "Lily");
        System.out.println(test3);//输出【name is Lily】


    }
}

CglibSubclassingInstantiationStrategy

CglibSubclassingInstantiationStrategy。它继承了SimpleInstantiationStrategy并覆盖了instantiationWithMethodInjection方法。不过使用这个方法必须用到cglib 类库。它利用cglib为bean动态生成子类,这个类叫代理类,在子类中生成方法注入的逻辑,然后使用这个动态生成的子类创建bean的实例。

二、BeanWrapper

BeanWrapper是对Bean的包装,其接口中所定义的功能很简单包括设置获取被包装的对象,获取被包装bean的属性描述器,由于BeanWrapper接口是PropertyAccessor的子接口,因此其也可以设置以及访问被包装对象的属性值。BeanWrapper大部分情况下是在spring ioc内部进行使用,通过BeanWrapper,spring ioc容器可以用统一的方式来访问bean的属性。

public interface BeanWrapper extends ConfigurablePropertyAccessor { 
    void setAutoGrowCollectionLimit(int autoGrowCollectionLimit); 
    int getAutoGrowCollectionLimit(); 
    Object getWrappedInstance(); 
    Class<?> getWrappedClass(); 
    PropertyDescriptor[] getPropertyDescriptors(); 
    PropertyDescriptor getPropertyDescriptor(String propertyName) throws InvalidPropertyException; 
}

BeanWrapperImpl

BeanWrapperImpl类是对BeanWrapper接口的默认实现,它包装了一个bean对象,缓存了bean的内省结果,并可以访问bean的属性、设置bean的属性值。BeanWrapperImpl类提供了许多默认属性编辑器,支持多种不同类型的类型转换,可以将数组、集合类型的属性转换成指定特殊类型的数组或集合。用户也可以注册自定义的属性编辑器在BeanWrapperImpl中。
下面是它的类图:
这里写图片描述
PropertyAccessor:具有访问,赋予属性值的方法

使用

public class Test {
    private String name;

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    @Override
    public String toString() {
        return "Test{name=" + name + '}';
    }

    public static void main(String[] args) throws ClassNotFoundException, IOException {

        BeanWrapperImpl wrapper = new BeanWrapperImpl(Test.class);
        wrapper.setPropertyValue("name", "XiaoM");
        System.out.println(wrapper.getWrappedInstance());
        System.out.println(wrapper.getPropertyValue("name"));

    }
}
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值