一、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"));
}
}