博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【Spring4揭秘 BeanFactory】InstantiationStrategy和BeanWrapper
阅读量:4290 次
发布时间:2019-05-27

本文共 3861 字,大约阅读时间需要 12 分钟。

一、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
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"));    }}
你可能感兴趣的文章
JVM内存、堆模型、垃圾回收器总结
查看>>
sql(join中on与where区别) / NVL函数 / oracle存储过程中is和as区别 / JAVA调用数据库存储过程
查看>>
前端开发:一款近年非常受欢迎、简单的WEB弹出层组件(layer)
查看>>
Java中sleep方法和wait方法的区别?
查看>>
Eclipse 下载 开源项目 maven依赖丢失和 Deployment Assembly 丢失
查看>>
MyBatis中对List<Object> 对象List的批处理插入操作
查看>>
mybatis使用foreach批次插入,解决sequence只查询一次的问题(在此,我只看union all 部分)
查看>>
有关分布式 MySQL 数据库中间件 MySQLDA,一文为你深入介绍~
查看>>
小马分享(如何使用Spring实现读写分离(MySQL实现主从复制))
查看>>
使用maven profile实现多环境配置
查看>>
tomcat-自带的简单session共享,小集群适用
查看>>
web.xml 配置中classpath: 与classpath*:的区别
查看>>
分布式实时日志分析解决方案 ELK 部署架构
查看>>
微服务MySQL分库分表数据到MongoDB同步方案
查看>>
kafka知识点整理总结
查看>>
springboot使用JPA创建权限功能,所需要的表
查看>>
介绍Redis的各种用途以及使用场景
查看>>
Oracle分页查询,面试你值得关注!
查看>>
如何把内网IP映射到公网IP
查看>>
【工具篇】Excel文件导出从未如此简单——EasyPOI的使用
查看>>