Spring Bean的加载过程以及一些生命周期
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 {//这只是声明了引用,并没有new对象//@AutoWired是怎么实现的呢?//spring的就是反射来实现的//我自己写一个@AutoWired//这是我自己写的private UserServiceImpl userServiceImpl;public UserServiceImpl getUserServiceImpl(){return userServiceImpl;}
}
实现@Autowired功能
/*** @author 王xx* @version 1.0* @date 20xxx 22:45* @Description TODO* @pojectname 自己实现我们的@AutoWired功能*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)//作用在属性字段上
@Inherited
@Documentedpublic @interface AutoWired {}
下面就是我们怎么样通过反射的方式,实现我们的Autowired功能,将我们的UserServiceImpl对象,赋值给我们的UserController
//测试我们自己写的注解,也是我们IOC怎么实现的核心@Testpublic void testAutoWired(){UserController userController = new UserController();//获取Class对象Class<? extends UserController> aClass = userController.getClass();//获取所有属性值Stream.of(aClass.getDeclaredFields()).forEach(field -> {//获取属性名String name = field.getName();//获取属性名上的注解信息AutoWired annotation = field.getAnnotation(AutoWired.class);//判断我们的属性名是否备注解if (annotation != null){//设置访问属性field.setAccessible(true);//获取我们属性的类型,得到要注入的目标值Class<?> type = field.getType();//创建我们的注入对象的实例try {Object o = type.newInstance();//为我们的UserController注入对象field.set(userController,o);} catch (InstantiationException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();}}});System.out.println(userController.getUserServiceImpl());}
初始化
这里的初始化指的是我们的类中可能还有没有被@Autowired注解的属性,普通属性,怎么初始化呢?
eg:
public class UserService{@AutoWiredprivate OrderService orderService;//我们没用注解标识,不会通过反射去动态的为其注入依赖private User defaultuser;
}
让我们的这个类实现我们的InitializingBean接口,并重写他的方法,这个方法就是在我们的属性注入之后来进行这个类的初始化的
public class UserService implements InitializingBean{@AutoWiredprivate OrderService orderService;//我们没用注解标识,不会通过反射去动态的为其注入依赖private User defaultuser;@Overridepublic void afterPropertiesSet() throws Exception {//我们可以设置我们的逻辑//比如从数据库查数据在给我们的默认user赋值defauteUser = new User(xxxx);}
}
或者使用他的注解**@PostConstruct**,表明我们这个方式是个初始化的方法
初始化完成后,就看看我们是否有AOP的支持
比如我们的UserService的其中一个方法需要AOP支持,那么我们的Spring就会用CGLB代理生成一个UserServiceProxy的代理对象,但是需要注意的是,我们的这个UserServiceProxy中的有些属性是没有值的!!!(小坑)
public class UserService {@AutoWiredprivate OrderService orderService;public void test(){//xxxxxxxxx}
}
实际上我们产生的代理类是这样的(模拟的)
class UserServiceProxy extend UserService{//目标对象private UserService target;public void test(){//先执行我们的代理逻辑//我这里想表达的就是只有一个前置方法//也就是我们的切面Bean的那个增强方法(我是这样理解的)UserServiceAspect.testBefore();//然后执行我们的目标方法target.test();//有可能还有后置方法,我这就不写了}
}
我们的代理类生成了一个目标对象,而且这个目标对象里也有一个OrderService对象,为啥为空?
我们的这个AOP逻辑处理的时候,我们是不会在进行属性注入的,就不会回去了,但是,我们的这个UserServiceProxy里面其实是有一个UserService对象的,而且我们点开这个对象发现,它里面的OrderService对象是有值的。
其余的还没总结完,下次聊
Spring Bean的加载过程以及一些生命周期相关推荐
- 尚硅谷2020最新版宋红康JVM教程-中篇-第3章类的加载过程(类的生命周期)详解-4-过程三:Initialization(初始化)阶段
static与final的搭配问题 初始化阶段,简言之,为类的静态变量赋予正确的初始值. 具体描述 类的初始化是类装载的最后一个阶段.如果前面的步骤都没有问题,那么表示类可以顺利装载到系统中.此时,类 ...
- Spring框架—SpringBean加载过程
原文作者:RunAlgorithm 原文地址:图文并茂,揭秘 Spring 的 Bean 的加载过程 1. 概述 Spring 作为 Ioc 框架,实现了依赖注入,由一个中心化的 Bean 工厂来负责 ...
- miniui datagrid 隐藏列默认赋值_「小程序JAVA实战」 小程序默认加载的页面和生命周期(八)...
小程序如何加载的呢?生命周期!源码:https://github.com/limingios/wxProgram.git 中的No.3 加载页面 小程序默认加载的pages中的第一个目录 不管你的名称 ...
- 面试官:讲讲Spring框架Bean的加载过程
spring作为目前我们开发的基础框架,每天的开发工作基本和他形影不离,作为管理bean的最经典.优秀的框架,它的复杂程度往往令人望而却步. 不过作为朝夕相处的框架,我们必须得明白一个问题就是spri ...
- 面试官:讲讲Bean的加载过程
spring作为目前我们开发的基础框架,每天的开发工作基本和他形影不离,作为管理bean的最经典.优秀的框架,它的复杂程度往往令人望而却步. 不过作为朝夕相处的框架,我们必须得明白一个问题就是spri ...
- Springboot之Bean的加载过程
加载和实例化bean分以下几个重要步骤: 1.根据package扫描出需要被管理的类 2.将这些类封装成BeanDefinition并注册到BeanFactory容器 3.实例化所有扫描到的BeanD ...
- Spring Bean懒加载与非懒加载
懒加载:对象使用的时候才去创建.节省资源,但是不利于提前发现错误: 提前加载:容器启动时立马创建.消耗资源,但有利于提前发现错误 Spring 默认设置是非懒加载 1,由于在controller中会注 ...
- Spring bean 标签加载、解析过程分析
概述 上一篇[Spring 加载.解析applicationContext.xml 流程]分析了从xml文件加载到开始解析xml里面的标签为止,基本都是跟spring 真正的核心没什么关系. 这篇我们 ...
- 28 Java类的加载机制、什么是类的加载、类的生命周期、加载:查找并加载类的二进制数据、连接、初始化、类加载器、双亲委派模型、自定义类加载器
28Java类的加载机制 28.1.什么是类的加载 28.2.类的生命周期 28.2.1.加载:查找并加载类的二进制数据 28.2.2.连接 28.2.3.初始化 28.3.类加载器 28.4.类的加 ...
- 页面加载时,vue生命周期的触发顺序
那么进入某个路由对应的组件的时候,我们会触发哪些类型的周期呢? 根实例的加载相关的生命周期(beforeCreate.created.beforeMount.mounted) 组件实例的加载相关的生命 ...
最新文章
- 《Java8实战》-第六章读书笔记(用流收集数据-01)
- 利用耦合隐马尔可夫模型改进交易策略
- DDOS压力测试系统
- mysql数据库 day02
- Unity屏幕坐标转UI坐标
- no cortex-m sw device found_SW大模块水箱桂林厂家图纸
- 目标跟踪之光流法---光流法简单介绍
- opencv 实现图像形态学操作 膨胀和腐蚀 开闭运算 形态学梯度 顶帽和黑帽
- Python进阶(三)单例设计模式
- java课设——租房管理系统
- JAVA集合和guava集合使用和原理解析
- Java 内存模型(Java Memory Model)
- Ubuntu 14.04常用软件的安装
- CIS芯片测试到底怎么测?
- iOS 修改app名称
- css代码中的ul和li是什么意思呢
- uni-app实现本地打包安卓APK
- 数据增强:YoloV4当中的Mosaic数据增强方法
- Mac ps 2021 3D功能无法使用问题,怎么办?
- 至少连接一个aura sync兼容设备_医疗设备10个常见电磁兼容干扰问题-优德分享