spring基础知识
1.什么是BeanDefinition?
表示bean定义,spring根据BeanDefinition来创建Bean对象。
重要属性:
beanClass:表示bean类型
scope:作用域,singleton表示单例,prototype表示原型(单例是一直用这个对象,原型表示对一个对象进行复制)
isLazy:原型bean懒加载不会起作用
dependsOn:创建一个bean之前所依赖的其他bean
primary:表示一个主bean,当需要按类型注入时,会有多个bean,如果存在主bean,会将主bean进行注入
initMethodName:初始化方法
@Component、@Bean、<bean/>都会被解析为BeanDefinition
2.什么是BeanFactory?
是一种“Spring容器”,翻译过来就是Bean工厂,顾名思义,他可以用来创建bean、获取bean。
3.BeanDefinition、BeanFactory、Bean三者的关系?
BeanFactory利用BeanDefinition定义来生成Bean对象。
4.BeanFactory的核心子接口和实现类?
ListableBeanFactory:
ConfigurableBeanFactory:
AutowireCapableBeanFactory:
AbstractBeanFactory:
DefaultListableBeanFactory:最重要,支持单例Bean、支持Bean别名、支持父子BeanFactory、支持Bean类型装换、支持Bean后置处理、支持FactoryBean、支持自动装配等等。
5.什么是Bean生命周期?
Bean生命周期描述的是Spring中一个Bean创建过程和销毁过程中所经历的步骤,其中Bean创建过程是重点。
我们可以利用Bean生命周期机制对Bean进行自定义加工。
A、BeanDefinition:进行Bean定义
B、构造方法:推断选出一个构造方法
C、实例化:构造方法反射得到对象
D、属性填充:给属性进行自动填充(反射得到的对象属性还是不完整的,通过自动注入、依赖注入来注入属性)
E、初始化:对其他属性赋值、校验(利用初始化机制对Bean进行自定义加工,比如可以利用InitializingBean接口来对Bean中的其他属性进行赋值或者校验)
F、初始化后AOP、生成代理对象。
6.@Autowired注入过程:
spring会先根据属性的类型去spring容器中找出该类型的所有bean对象,如果找出来多个,则再根据属性的名字从多个中在确定一个,如果required属性为true,找不到注入对象则抛异常。
当@Autowired注解写在某个方法上时,Spring在Bean生命周期的属性填充阶段,会根据方法的参数类型、参数名字从Spring容器中找到对象当做方法入参,自动反射调用该对象。如果不想
写在方法上,可以写在属性上,效果是一样的。
@Service public class OrderSercice{ private UserService userService; @Autowired public void setUserService(UserService userService){ this.userService = userService } }
当@Autowired加在构造方法上时,Spring会在推断构造方法阶段,选择该构造方法来进行实例化,在反射调用构造方法之前,会先根据构造方法参数类型、参数名从Spring容器中找到Bean对象,当做构造方法入参。
@Service public class OrderService{ @Autowired public OrderService(UserService userService){ this.userService = userService } }
7.@Resource是什么?
@Resource注解与@Autowried类似,也是用来进行依赖注入的。@Resoruce是java层面所提供的注解,@Autowried是Spring所提供的注解,他们依赖注入的底层实现逻辑也不同。
@Resource如果name属性有值,那么Spring会直接根据所指定的name值去Spring容器中找bean对象,如果找到了则成功,如果没有找到,则报错。
如果@Resoruce的name属性没有值,首先1、先判断该属性名字在spring容器中是否存在bean。2.如果存在,则成功找到bean对象注入。3、如果不存在,则根据属性类型去spring容器中找bean对象。
8.@Value是什么?
@Value注解和@Resource、@Autowired类型,也是用来对属性进行依赖注入的,只不过@Value是用来从Properties文件中来获取值的,并且@Value可以解析SpEL
${}配置文件、#{}内容值充当beanName去spring容器中找bean,找到注入,没有报错
9.BeanFactory与FactoryBean的区别:BeanFactory是个Factory,也就是IOC容器或对象工厂,FactoryBean是个Bean。在Spring中,所有的Bean都是由BeanFactory(也就是IOC容器)来进行管理的。但对FactoryBean而言,这个Bean不是简单的Bean,而是一个能生产或者修饰对象生成的工厂Bean,它的实现与设计模式中的工厂模式和修饰器模式类似。
10.ApplicationContext是什么?
ApplicationContext是比BeanFactory更加强大的Spring容器,它既可以创建Bean、获取Bean,还可以支持国际化、事件广播、获取资源等BeanFactory不具备的功能。
11.生成bean的几种方式
A.通过<bean/>标签
ClassPathXmlApplicationContext classPathXmlApplicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
User user = classPathXmlApplicationContext.getBean("user", User.class);
B.@Component、@Service等等
C.@Bean
public class Config {
@Bean
public User user(){
return new User();
}
}
AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(Config.class);
annotationConfigApplicationContext.getBean("user", User.class);
同时举例了通过两种不同的spring容器获取bean
D.BeanDefinition方式(这是编程式,上面的都是声明式),上面三种实现的本质都是基于BeanDefinition
12.Import的使用
@Configuration @Import(OrderService.class) public class Config { }
@Configuration的作用让springboot扫描这个类,@Import可以直接生成orderservice对象放入IOC
13.spring的注入和自动装配
注入可以有set注入和构造器注入,当加载到xml的配置文件时,ioc去执行这个类的构造方法(如果是有参的构造器注入),从而new出一个对象,然后使用set方法将xml中的属性进行注入。如果有选择自动装配byname,这样xml中的属性可以不用写。执行set方法的时候,直接根据ioc容器中是否有对应的属性注入进来。
自动装配可以看成是一个对象里面的属性的装配,虽然可以不用显式的写明注入的属性,但是还是需要注入,而注入的方式就是一个对象里面属性装配的手段是那种
14.BeanFactory和ApplicationContext的区别?
》BeanFactory采用的是延迟加载形式来注入Bean的,即只有在使用到某个Bean时(调用getBean()),才对该Bean进行加载实例化。这样,我们就不能发现一些存在的Spring的配置问题。如果Bean的某一个属性没有注入,BeanFactory加载后,直至第一次使用调用getBean方法才会抛出异常。
》ApplicationContext,它是在容器启动时,一次性创建了所有的Bean。这样,在容器启动时,我们就可以发现Spring中存在的配置错误,这样有利于检查所依赖属性是否注入。ApplicationContext启动后预载入所有的单实例Bean,通过预载入单实例bean,确保当你需要的时候,你就不用等待,因为他们已经创建好了。
》相对于基本的BeanFactory,ApplicationContext唯一的不足是占用内存空间。当应用程序配置Bean较多时,程序启动较慢。
15.Spring Bean的生命周期?
》1.解析类得到BeanDefinition
》2.如果有多个构造方法,则要推断构造方法
》3.确定好构造方法后,进行实例化得到一个对象
》4.对 对象中加了@Autowired注解的属性进行属性填充
》5.回调Aware方法,比如BeanNameAware,BeanFactoryAware
》6.调用BeanPostProcessor的初始化钱的方法
》7.调用初始化方法
》8.调用BeanPostProcessor的初始化后的方法,在这里会进行AOP
》9.如果当前创建的bean是单例的 则会把bean放入单例池
》10.使用bean
》11.Spring容器关闭时调用DisposableBean中destory方法。
16.Spring支持的几种bean的作用域?
》singleton:默认,每个容器中只有一个bean实例,单例的模式由BeanFactory自身来维护。该对象的生命周期是与spring IOC容易是一致的。
》prototype:为每个bean请求提供一个实例。在每次注入时都会创建一个新的对象
》request:bean被定义为在每个HTTP请求中创建一个单例对象,也就是说在单个请求中都会复用这一个单例对象。
是每次发送的的http请求就创建一个。
》session:与request范围类似,确保每个session中有一个bean实例,在session过期后,bean会随之失效。
》application:bean被定义为在ServletContext的生命周期中复用一个单例对象。
》websocket:bean被定义为在websocket的生命周期中复用一个单例对象。
17.Spring框架中的单例Bean是线程安全的吗?
Spring中的Bean默认是单例的,框架并没有对bean进行多线程的封装处理。
如果bean是无状态的,说明是线程安全的。一个bean中注入了其他的属性,但是这些属性也是无状态的话,那依旧是安全的。
如果bean是有状态的,说明是线程不安全的。有状态是指有数据保存,比如一些变量啥的,多线程操作下,这些变量肯定是不安全的。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix