Spring作为应用很广泛的开源框架,在面试中肯定少不了
Bean作为我们Spring的一大核心(容器)是非常重要的,下面是自己看周瑜老师学的还有其他一些视频的学习笔记
说一下Bean的加载过程,生命周期 (肯定少不了重要的IOC)
class———>推断构造方法———–>实例化——>对象——> 属性填充(IOC)——>初始化——->AOP------>Bean(这里没总结完)
bean的加载过程
我是这样理解的,从配置文件加载或者组件注解加载我们的Bean的时候会先进入一个叫BeanDefinition中,它是一个Map类型,主要是读取我们的Bean定义信息,注意这个时候我们的Bean中属性并没有进行赋值操作,然后图中的几个接口很重要,一个是Bean工厂,还有两个以Processor结尾的接口,我是这样理解的,他就是来修饰扩展我们的Bean的也可以说是增强我们的Bean,
Spring作为一个框架,必须要有一定的可扩展性,这个Processor就是让我们自定义我们的扩展组件的
总结:作为一个框架,首先要考虑我们的扩展性
Spring提供了什么扩展性
1.在对象创建之前我们可以欠佳某些功能
2.在容器初始化之前添加某些功能
3.在不同的阶段发出不同的时间,完成一些功能
4.抽象出一堆的接口来帮助扩展
FactoryBean中3个方法,是用来根据我们自己的想法步骤去创建出我们想要的Bean的;也就是说这一步肯定要先把Bean定义读取到BeanDefinitionReader的Map结构中,然后Spring提供的增强方法去修饰它,
构造工厂图中也表示出来了,可以看出是根据构造函数来实例化对象的,那么是怎么个原理呢?
推断构造方法,Spring如何判断构造函数来实例化对象
UserService是一个Bean,里面既有默认的无参构造函数,又有一个有参的构造函数(随便就行),那么它是怎么进行实例化的
答案是我们的Spring会调用我们的无参构造函数,我想让Spring用带参构造方法怎么办呢?
我们可以在有参构造函数方法上加@AutoWired注解
如果有两个带参的构造方法,就会报错,因为Spring不知道要用那个构造方法,会爆出No default constructor found
我们Spring对带参 的构造函数的参数是通过byType,byName的顺序一起匹配来找的,这里要区分单例Bean(单例池中)和单例模式的区别(有兴趣的可以看看)
只通过名字:那么我们找到的这个对象有可能跟我们的入参类型不匹配
只通过类型:要是我们的单例池中有好几个OrderService呢?不知道选哪一个
IOC DI 依赖注入
属性填充
**@AutoWired值怎么来的呢?**还是通过buType 和byName来的
AutowiredAnnotationBeanPostProcessor
1.先找注入点(这个类哪里加@AutoWired注解了)
根据我们的byType来找,在根据byName
@Resource注解
CommonAnnotationBeanPostProcessor
首先也会去寻找被@Resource注解了的方法和属性
1.如果@Resource注解指定了name属性,就直接从Spring容器拿对应的Bean,如果不存在则表示没有找到注入对象(报错)
2.如果@Resource注解没有指定了name属性,但是根据属性名字或setXXX中的**xxx在Spring容器中有对应的Bean,(不是根据参数名字找的)**那也直接根据名字拿
3.否则根据注入点Type类型去找Bean
那么怎么把值赋值进去呢?
反射
这里我只写了一个简单的例子,实际上肯定会比较复杂,但是意思就是这么个意思,只是少了很多逻辑,动态改变这些,看明白意思就行
代码准备
UserServiceImpl代码
public class UserServiceImpl {
}
UserController代码
public class UserController {