Spring的IOC,翻译过来,叫控制反转。 指的是在Spring中使用工厂模式,为我们创建了对象,并且将这些对象放在了一个容器中,我们在使用的时候,就不用每次都去new对象了,直接让容器为我们提供这些对象就可以了。 这就是控制反转的思想。
●
而DI,翻译过来,叫依赖注入。 那刚才提到,现在对象已经交给容器管理了,那程序运行时,需要用到某个对象,此时就需要让容器给我们提供,这个过程呢,称之为依赖注入。
可能继续追问的问题:
●
那如何将一个对象,讲给IOC容器管理呢?
那现在项目开发,都是基于Springboot构建的项目,所以呢,声明bean对象,我们只需要在对应的类上加上注解就可以了。 比如:
●
如果是controller层,直接在类上加上 @Controller 或 @RestController 注解。
●
如果是service层,直接在类上加上 @Service 注解。
●
如果是dao层,直接在类上加上 @Repository 注解。当然现在基本都是Mybatis 或 MybatisPlus,所以这个注解很少用了,都用的是 @Mapper 注解。
●
如果是一些其他的工具类、配置类啊,我们可以通过 @Component 、@Configuration 来声明。
●
那如何完成依赖注入操作呢 ? 依赖注入的方式比较多,我们可以使用构造函数注入 或 成员变量输入,也是使用对应的注解就可以了。常用的注解有两个:
○
@Autowired 和 @Resource 注解。 那 @Autowired 默认是根据类型注入,而 @Resource 注解默认是根据名称注入。
Spring容器中的bean是线程安全的吗?
不是线程安全的。
针对于这个问题呢,首先我们知道spring容器的bean默认是单例的。 当多用户同时请求一个服务时,容器会给每一个请求分配一个线程,这时多个线程会并发执行该请求对应的业务逻辑,也就是bean对象的业务方法,那如果在业务方法中操作了共享的成员变量,那可能就会存在线程安全问题。
而在Spring框架中并没有对单例bean进行任何多线程的封装处理,关于单例bean的线程安全和并发问题需要我们自行去搞定。但实际上,大部分情况下Spring 的bean并没有可变的状态(比如Controller、Service、Dao),所以在某种程度上说Spring的单例bean是线程安全的。
如果说存在这种情况,那就需要开发人员自行保证线程安全。要么,通过编码保证线程安全,要么,设置bean的作用域为 prototype。
Spring Bean的作用域如何设置,常见的取值有哪些 ?
Spring Bean的作用域可以通过 @Scope 注解来设置。常见的取值如下:
●
singleton :这种bean范围是默认的,这种范围确保不管接受到多少个请求,每个容器中同一个名称的bean只有一个实例,也就是单例的 。
●
prototype :这种范围,表示非单例的。也就是说每一次用到的bean都是一个新的 。
●
request :同一个请求,使用的是同一个bean。会为每一个来自客户端的请求都创建一个实例,在请求完成以后, bean会失效并被垃圾回收器回收 。
●
session:与request 请求范围类似,确保每个session会话范围内,是同一个实例,在session过期后, bean会随之失效 。
虽然,bean作用域可以设置这些值,但是在项目开发中,绝大部分的bean都不会添加这个 @Scope 注解,也就是说默认都是用的是单例的bean。
Spring容器的bean什么时候初始化的?
嗯~ 这个得分情况来看哈。
●
如果是单例的bean,默认是Spring容器启动的时候,就完成bean的初始化操作,那这是默认情况,我们可以通过 @Lazy 注解来延迟bean的初始化,延迟到第一次使用的时候。
●
而如果是非单例的bean(也就是prototype),则是在每次使用这个bean的时候,都会重新实例化一个新的bean。
聊一聊Bean的生命周期 ?