Supplier机制 | FactoryMethod机制 | autowireConstructor机制 | instantiateBean机制 |
---|---|---|---|
通过supplier机制创建实例 | 通过factorymethod创建实例 | 通过含参构造创建实例 | 一般走无参构造创建实例 |
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对象 // 目的: 避免下面采用反射调用 从而提高相关性能
通过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" />
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); }
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); } }
此处了解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)); }
两个拦截器不在讲解其实现
同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; }