本文共 3861 字,大约阅读时间需要 12 分钟。
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;}
是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】 //带参数的构造器 Constructorconstructor = 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。它继承了SimpleInstantiationStrategy并覆盖了instantiationWithMethodInjection方法。不过使用这个方法必须用到cglib 类库。它利用cglib为bean动态生成子类,这个类叫代理类,在子类中生成方法注入的逻辑,然后使用这个动态生成的子类创建bean的实例。
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类是对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")); }}