5.什么是Spring Bean?
Spring Bean
就是被Spring IOC
容器实例化和管理的对象。
6.配置Bean有哪几种方式?
- 通过注解,
@Component
(@Controller
、@Service
、@Repostory
)或者JavaConfig
提供的@Bean
注解。 - 通过xml,直接在xml中加上一个Bean节点,指定Bean完整的路径。
<bean class="com.tuling.UserService" id="">
8.@Component和@Bean的区别是什么?
@Component
底层是通过反射调用构造方法来实例化Bean对象,@Bean
是标注在一个方法上面,必须返回一个对象。返回的对象就会成为一个Bean,我们可以自己控制实例化过程。通常结合配置类@Configuration
一起使用。
Java反射机制允许在运行时动态获取类的元数据(如属性、方法、构造器),并直接操作对象或调用方法。通过反射,可提前编写通用逻辑(如对象创建、方法执行),以后不论哪个模块都可以直接调用,实现功能复用。例如,Spring框架中
@Component
注解的Bean管理,正是通过反射解析类信息并调用构造器实例化对象。
9.Spring实例化Bean有几种方式?
主要有三种,第一种是通过反射,第二种是静态工厂,第三种是实例工厂。
- 反射,不论是通过xml配置bean节点还是通过注解的方式配置
@Component
,Spring的底层都会通过反射把class里的完整类路径存放在BeanDefinition.beanClass
属性中。Spring在创建Bean的时候,会根据beanClass进行反射,通过反射拿到实例。反射实际上就是调用类的构造函数,从而得到这个实例。 - 静态工厂方式就是给当前Bean配置一个
factory-method
,Spring在实例化的时候就会帮我们调用当前配置bean的factory-mothed所指的的方法,从而帮助我们实例化。 - 实例工厂方式就是在
factory-method
的基础上,再去指定一个factory-bean
,Spring底层在实例化的时候就会调用指定的Bean方法。@Bean
注解的底层就是采用这种factory-method
+factory-bean
的方式,不论是factory-method还是factory-bean都会将对应的定义信息读取到BeanDefinition
中。
10. Bean的生命周期了解吗?
Bean的生命周期就是从创建到销毁的过程,主要分为四大步:
-
实例化
a. 通过反射推断构造函数进行实例化
b. 静态工厂和实例工厂进行实例化 -
属性赋值
a. 在属性上添加注解,进行依赖注入,也是通过反射实现的。由于启动时不报错,调用Bean时才报错,所以可能出现循环依赖。 -
初始化
a. 调用XXXAware
回调方法(前提Bean是实现了Aware接口),BeanNameAware
、BeanClassLoaderAware
和BeanFactoryAware
。
b. 如果Bean实现了AOP
,需要在初始化时实现动态代理。动态代理是一种允许运行时创建代理对象的机制,可以在不修改原始类的情况下,为其添加额外的行为。比如日志记录、性能监控等,动态代理的核心是反射技术。
c. 初始化之后,Bean就可以使用了。
-
销毁
a. 在Spring容器关闭的时候,调用销毁的生命周期回调方法。
11.循环依赖是什么?有什么解决方案?
循环依赖是指两个或多个Bean之间相互依赖,比如在A依赖B,B又依赖A。在创建A的时候,需要先创建B,创建B的时候有需要创建A。
- 可以通过三级缓存来解决循环依赖,一级缓存存放完全初始化好的Bean,二级缓存存放的是提前暴露的Bean,三级缓存存放Bean的工厂对象
ObjectFactory
,它的getObject()
方法可以提前生成提前暴露的Bean。 - 比如在B创建A的过程中发生了循环依赖,由于A没有初始化完成,所以在一二级缓存中肯定没有A。这是需要去三级缓存中调用
getObject()
方法,生成一个A的提前暴露Bean。 - 然后将这个
ObjectFactory
从三级缓存中移除,并将提前暴露对象加入到二级缓存中。B就可以将这个提前暴露对象注入到依赖,解决循环依赖的问题。
12.解释Spring支持的几种Bean的作用域?
配置Bean作用域有两种方式,第一种就是在配置文件Bean节点
里的scope
进行设置,第二种就是通过注解@Scope
设置。
Spring框架支持五种Bean的作用域:
singleton
,单例Bean,Bean在每个Spring IOC
容器中只有一个实例。单例是默认的Bean作用域prototype
,原型Bean,一个Bean的定义可以有多个实例,每次从IOC容器中获取Bean,都会返回一个新的实例对象。request
,每次http
请求都会创建一个Bean,必须引入web
应用才会有request。session
,每次会话都会创建一个Bean,也需要依赖于web应用。application
,一个全局应用共享一个对象。
13.单例Bean的优势?
单例Bean对象只创建一次,节省了内存空间,同时获取对象也更方便,提升了性能。
14.Bean线程安全吗?
不管是不是在Spring框架里,只要某个Java对象中的状态被多个线程修改,就会有线程安全的问题(和单例还有原型没用任何关系)。解决线程安全的常用手段就是加锁串行化,或者原子操作类CAS串行化,亦或者使用线程安全的集合类。
15.Spring 中的BeanFactory和FactoryBean是什么?
BeanFactory
是一个bean工厂类,主要负责生产和管理Bean,是IOC容器最底层的接口。FactoryBean
是一个bean,在IOC容器的基础上给Bean的实现加上了一个简单工厂模式和装饰模式,是一个可以生产对象和装饰对象的工厂Bean。