Spring(十三,成功跳槽字节跳动

  • SimpleInstantiationStrategy:简单的实例化策略

  • CglibSubclassingInstantiationStrategy:扩展了SimpleInstantiationStrategy,默认的策略就是这个

而调用的instantiate只有SimpleInstantiationStrategy实现了

在这里插入图片描述

源码如下

@Override

public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner,

final Constructor<?> ctor, Object… args) {

//判断RootBeanDefinition是否有覆盖方法

if (!bd.hasMethodOverrides()) {

if (System.getSecurityManager() != null) {

// use own privileged to change accessibility (when security is on)

AccessController.doPrivileged((PrivilegedAction) () -> {

ReflectionUtils.makeAccessible(ctor);

return null;

});

}

//没有动态代理,使用beanUtils去实例化

return BeanUtils.instantiateClass(ctor, args);

}

else {

//如果有覆盖方法,证明出现了代理

//

return instantiateWithMethodInjection(bd, beanName, owner, ctor, args);

}

}

可以看到,这里实例化又分为两种情况

  • 如果有覆盖方法,也就是有replace属性,那就代表要进行代理,交给子类CglibSubclassingInstantiationStrategy策略进行创建,因为Cgl

《一线大厂Java面试题解析+后端开发学习笔记+最新架构讲解视频+实战项目源码讲义》

【docs.qq.com/doc/DSmxTbFJ1cmN1R2dB】 完整内容开源分享

ib是默认的策略

  • 如果没有覆盖方法,也就是没有代理,交给BeanUtils来进行创建
没有覆盖方法的实例化

没有覆盖方法,就不需要Clb进行代理了,交由BeanUtils来进行实例化

源码如下

public static T instantiateClass(Constructor ctor, Object… args) throws BeanInstantiationException {

Assert.notNull(ctor, “Constructor must not be null”);

try {

//如果传进来的构造器为private类型

//则设置构造器的的accessible属性为true,让其可以被访问

ReflectionUtils.makeAccessible(ctor);

//利用反射来进行创建Bean

if (KotlinDetector.isKotlinReflectPresent() && KotlinDetector.isKotlinType(ctor.getDeclaringClass())) {

return KotlinDelegate.instantiateClass(ctor, args);

}

else {

//获取构造器的参数的class类型

Class<?>[] parameterTypes = ctor.getParameterTypes();

//断言构造器使用参数数目与传进来的参数数目是否一样

Assert.isTrue(args.length <= parameterTypes.length, “Can’t specify more arguments than constructor parameters”);

//建立object数组来存放处理后的参数

Object[] argsWithDefaultValues = new Object[args.length];

//遍历参数进行整理

for (int i = 0 ; i < args.length; i++) {

//如果有参数为null

if (args[i] == null) {

//获取这个参数的类型

Class<?> parameterType = parameterTypes[i];

//判断这个参数是不是原始类型,即基本数据类型

//如果是基本数据类型,从DEFAULT_TYPE_VALUES中取默认值

//如果不是基本数据类型,那就为Null

//不过一般都不会为null,因为前面对参数就进行处理了

argsWithDefaultValues[i] = (parameterType.isPrimitive() ? DEFAULT_TYPE_VALUES.get(parameterType) : null);

}

else {

//如果参数不为null,存进数组中

argsWithDefaultValues[i] = args[i];

}

}

//使用反射的方法进行创建!!!

return ctor.newInstance(argsWithDefaultValues);

}

}

catch (InstantiationException ex) {

throw new BeanInstantiationException(ctor, “Is it an abstract class?”, ex);

}

catch (IllegalAccessException ex) {

throw new BeanInstantiationException(ctor, “Is the constructor accessible?”, ex);

}

catch (IllegalArgumentException ex) {

throw new BeanInstantiationException(ctor, “Illegal arguments for constructor”, ex);

}

catch (InvocationTargetException ex) {

throw new BeanInstantiationException(ctor, “Constructor threw exception”, ex.getTargetException());

}

}

默认值的容器如下

在这里插入图片描述

可以看到里面仅仅只有5种,缺少了浮点型和字符型,那么对于浮点型和字符型为空的情况呢???

可见Spring对于浮点型和字符型是没有提供默认值的,如果来到这里发生浮点型和字符型为null,反射后会报IllegalArgumentException异常

拥有覆盖方法的实例化

从上面可以看到,没有覆盖方法的实例化,其实就是使用反射来创建而已

下面看看如果有覆盖方法的实例化

对应的方法为instantiateWithMethodInjection,寓意为进行切入,也就是代理

在这里插入图片描述

可以看到,代理是交由CglibSubClassCreator去负责的,并且通过构造方法已经将RootBeanDefinition和BeanFactory注入进去了

源码如下

public Object instantiate(@Nullable Constructor<?> ctor, Object… args) {

//根据RootBeanDefinition一个增强class

//所谓的增强Class其实就是代理Class,因为被代理了,所以就是增强嘛

Class<?> subclass = createEnhancedSubclass(this.beanDefinition);

Object instance;

//判断构造器是否为空

if (ctor == null) {

//如果构造器为空,直接利用增强class来进行实例化

//BeanUtils其实就是使用反射去创建嘛,就不赘述了

instance = BeanUtils.instantiateClass(subclass);

}

else {

//如果构造器不为空

try {

//利用增强classs去获取构造器

Constructor<?> enhancedSubclassConstructor = subclass.getConstructor(ctor.getParameterTypes());

//利用构造器的增强class来实例化bean

instance = enhancedSubclassConstructor.newInstance(args);

}

catch (Exception ex) {

throw new BeanInstantiationException(this.beanDefinition.getBeanClass(),

“Failed to invoke constructor for CGLIB enhanced subclass [” + subclass.getName() + “]”, ex);

}

}

// SPR-10785: set callbacks directly on the instance instead of in the

// enhanced class (via the Enhancer) in order to avoid memory leaks.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值