这里写目录标题
createBeanInstance核心流程
Supplier机制 | FactoryMethod机制 | autowireConstructor机制 | instantiateBean机制 |
---|---|---|---|
通过supplier机制创建实例 | 通过factorymethod创建实例 | 通过含参构造创建实例 | 一般走无参构造创建实例 |
demo讲解supplier与factorymethod
demo一supplier
return obtainFromSupplier(instanceSupplier, beanName);返回创建的对象
public class SupplierBean {
private static User createUser(){
return new User("小薇呀");
}
static class User{
private String name;
public User(String name) {
this.name = name;
}
public String getName() {
return name;
}
@PostConstruct
public void init(){
System.out.println("user 初始化.....");
}
}
}
GenericBeanDefinition beanDefinition = new GenericBeanDefinition();
beanDefinition.setBeanClass(User.class);
beanDefinition.setInstanceSupplier(SupplierBean::createUser);
// 如此初始化之后 则会采用这里的Supplier 创建User对象
// 目的: 避免下面采用反射调用 从而提高相关性能
demo一instantiateUsingFactoryMethod
通过return instantiateUsingFactoryMethod(beanName, mbd, args);完成bean创建
静态工厂和实例化工厂区别 class录入的是工厂类 而不是bean name实际对应的类 实例化工厂还需要 设置一个实例化工厂bean 如: hi13Factory
### 静态工厂
<!-- class 表示工厂bean的类型 但bean的类型是getHi11返回的类型-->
<bean id="hi11" class="com.renxl.demo.Hi12StaticFactory" factory-method="getHi11" />
### 实例化工厂
<bean id="hi13Factory" class="com.renxl.demo.Hi13Factory"/>
<!-- 此时class属性可以省略 -->
<bean id="hi11_1" factory-bean="hi13Factory" factory-method="getHi11_1" />
源码分析
- 先走Supplier机制实例化对象
- 在走factoryMethod机制实例化对象
- 曾经解析过则走缓存策略
- 是否走构造参数注入实例化对象 通过后置处理器决定构造参数
- 走无参构造实例化对象
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
查找类class 对象确保可以实例化
Class<?> beanClass = resolveBeanClass(mbd, beanName);
走supplier策略
Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
if (instanceSupplier != null) {
return obtainFromSupplier(instanceSupplier, beanName);
}
走FactoryMethod策略
if (mbd.getFactoryMethodName() != null) {
return instantiateUsingFactoryMethod(beanName, mbd, args);
}
.......删除创建走缓存相关代码
后置处理器决定构造注入- 也就是说由后置管理器决定选择哪个构造方法
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
可能还是有多个构造参数,需要方法内部进一步决定
return autowireConstructor(beanName, mbd, ctors, args);
}
******************************************************************
一般情况下走的是这个方法进行实例化
业务里面的service ,controller 等基本都是这个地方进行单例的实例化
******************************************************************
return instantiateBean(beanName, mbd);
}
源码分析一构造方法的选择
源码分析一instantiateBean的实现
- 通过CglibSubclassingInstantiationStrategy策略实例化对象
- 策略根据有无需要增强的方法,从而使用jdk反射或者cglib创建对象
protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {
......删除其他代码
Object beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);
BeanWrapper bw = new BeanWrapperImpl(beanInstance);
initBeanWrapper(bw);
return bw;
}
public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {
......删除其他代码
if (!bd.hasMethodOverrides()) {
Constructor<?> constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod;
if (constructorToUse == null) {
final Class<?> clazz = bd.getBeanClass();
constructorToUse = clazz.getDeclaredConstructor();
bd.resolvedConstructorOrFactoryMethod = constructorToUse;
}
走反射创建对象
return BeanUtils.instantiateClass(constructorToUse);
}
else {
// 有@Lookup @Replace注解的情况则需要使用cglib实现代理后的对象
return instantiateWithMethodInjection(bd, beanName, owner);
}
}
jdk创建对象
此处了解spring支持Kotlin即可,一般项目也用不到
public static <T> T instantiateClass(Constructor<T> ctor, Object... args) throws BeanInstantiationException {
如果是Kotlin相关 则引用其jvm技术完成对象创建 如果不是反射创建对象
ReflectionUtils.makeAccessible(ctor);
return (KotlinDetector.isKotlinReflectPresent() && KotlinDetector.isKotlinType(ctor.getDeclaringClass()) ?
KotlinDelegate.instantiateClass(ctor, args) : ctor.newInstance(args));
}
cglib创建对象
两个拦截器不在讲解其实现
同lite与full模式实现,如果要创建的对象存在@Lookup和@Replace方法 则对这些方法增加拦截 不在调用原方法 而是通过beanfactory.getBean实现
protected Object instantiateWithMethodInjection(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner,
@Nullable Constructor<?> ctor, Object... args) {
return new CglibSubclassCreator(bd, owner).instantiate(ctor, args);
}
public Object instantiate(@Nullable Constructor<?> ctor, Object... args) {
...... 删除其他代码
两个拦截器不在讲解其实现和lite与full模式的实现一样
如果要创建的对象存在@Lookup和@Replace方法 则对这些方法增加拦截 不在调用原方法 二是通过beanfactory.getBean实现
factory.setCallbacks(new Callback[] {NoOp.INSTANCE,
new LookupOverrideMethodInterceptor(this.beanDefinition, this.owner),
new ReplaceOverrideMethodInterceptor(this.beanDefinition, this.owner)});
return instance;
}
总结
- 讲解了对象创建的过程,分为supplier,factorymethod和构造实例化三种策略
- 同时讲解了构造函数的选择方式
- 需要注意的是,此时spring容器中bean处于创建中但尚未加入spring容器,也没有完成DI,Wrapper等功能