ali(ArrayList扩容/Spring处理相互依赖的bean/两种代理的区别)

1. List扩容主要实现步骤:
总的来说分两步,1.扩容:把原来的数组复制到另一个内存空间更大的数组中
2.添加元素: 把新元素添加到扩容以后的数组中
扩容的方法就是 add(E e)
ali(ArrayList扩容/Spring处理相互依赖的bean/两种代理的区别)_第1张图片
看,其实add方法就两步,第一步:增加长度,第二步:添加元素到数组,第二步没什么说的,我们看看ensureCapacityInternal(int minCapacity)这个增加长度的方法
ali(ArrayList扩容/Spring处理相互依赖的bean/两种代理的区别)_第2张图片
如果在添加的时候远数组是空的,就直接给一个10的长度,否则的话就加一
ali(ArrayList扩容/Spring处理相互依赖的bean/两种代理的区别)_第3张图片
grow()方法是真正的增加长度,当需要的长度大于原来数组长度的时候就需要扩容了,相反的则不需要扩容。
这个地方注意这一句
int newCapacity = oldCapacity + (oldCapacity >> 1);
oldCapacity >> 1 右移运算符 原来长度的一半 再加上原长度也就是每次扩容是原来的1.5倍
之前的所有都是确定新数组的长度,确定之后就是把老数组copy到新数组中,这样数组的扩容就结束了。

以上的一切都是ArrayList扩容的第一步,第二步就没啥说的了,就是把需要添加的元素添加到数组的最后一位。
2. Spring处理相互依赖的bean

  1. Spring只能解决Setter方法注入的单例bean之间的循环依赖
  2. ClassA依赖ClassB,ClassB又依赖ClassA,形成依赖闭环。Spring在获取ClassA的实例时,不等ClassA完成创建就将其曝光加入正在创建的bean缓存中。在解析ClassA的属性时,又发现依赖于ClassB,再次去获取ClassB,当解析ClassB的属性时,又发现需要ClassA的属性,但此时的ClassA已经被提前曝光加入了正在创建的bean的缓存中,则无需创建新的的ClassA的实例,直接从缓存中获取即可。从而解决循环依赖问题。

3. 两种代理的区别
JDK代理是不需要以来第三方的库,只要JDK环境就可以进行代理,java动态代理是利用反射机制生成一个实现代理接口的匿名类,它有几个要求

  • 实现InvocationHandler
  • 使用Proxy.newProxyInstance产生代理对象
  • 被代理的对象必须要实现接口
    而cglib动态代理是利用asm开源包,是基于类的扩展,为目标类生成一个子类,重写父类的方法。动态代理通过字节码处理框架ASM生成代理类以及代理类的FastClass,能通过FastClass快速找到代理方法,比反射快
    也可以强制使用CGlib
    在spring配置中加入或 @EnableAspectJAutoProxy (proxyTargetClass = true)

4.bean的作用域
使用bean的scope属性来配置bean的作用域
singleton:默认值,容易初始化创建bean的实例,再整个容器的生命周期内只创建这一个bean,单例的。
prototype:原型的,容器初始化时不创建bean的实例,而再每次请求时都创建一个新的bean实例,并返回。
request:每次HTTP请求都会产生一个新得bean,需要注意的是,该作用域仅在基于Web的spring ApplicationContext情形下有,seesion也是。
session:每次会话创建一个实例。

你可能感兴趣的:(ali(ArrayList扩容/Spring处理相互依赖的bean/两种代理的区别))