您现在的位置是:首页 >其他 >Bean的存取、五大注解、对象的注入方式、Bean的作用域和生命周期网站首页其他
Bean的存取、五大注解、对象的注入方式、Bean的作用域和生命周期
一、Bean 的创建、存储和使用
PS:Java语言中的对象也叫作 Bean。
1、创建一个maven项目
PS:要在 pom.xml 中添加 spring 框架支持
PS:引入 lombok 依赖(可以帮助实现 get 和 set 方法)
2、存对象
2.1、创建类
启动类(包含main方法即可):
创建bean:
2.2、写配置文件并定义bean
配置文件:
注册bean:
3、取对象
PS:ApplicationContext 和 BeanFactory 的区别(两者的效果是一样的,都可以作为 spring 的上下文):
(1)继承关系:ApplicationContext 是 BeanFactory的子类。(2)性能方面:ApplicationContext 是一次性加载并初始化所有的 Bean 对象;而 BeanFactory 是需要哪个加载哪个,更加轻量。
二、更简单的读存 Bean(通过注解实现)
1、存对象
1.1、通过五大注解告诉 spring 要管理哪些类
类注解:@Controller、@Service、@Repository、@Component、@Configuration
注解的作用:便于直接了解类的作用。
1.1.1、@Controller(控制器)——表示的是业务逻辑层,接口的最外层,验证参数接口的正确性或者参数的转换、返回。
存储 bean:
读取 bean:
1.1.2、@Service(服务)——表示的是服务层,一般是服务的编排和汇总。
存储 bean:
读取 bean:
1.1.3、@Repository(仓库)——表示的是持久层,一般是数据库。
1.1.4、@Component(组件)
1.1.5、@Configuration(配置)——表示的是配置层。
PS:各注解之间的关系:
各注解的源码:
通过源码可知,这些注解的注解里都有 @Component,因此说明它们本身就是属于 @Component的子类。
1.2、方法注解:@Bean
PS:需要搭配五大注解使用。
结果:
PS:五大注解和 @Bean 的作用是一样的,都是把对象存到 spring 容器中。
如果一个类无状态(无状态即:不同的线程或者不同的请求,我们创建的对象都是一样的,密钥个性化的属性),就是用五大注解。(一般情况下使用五大注解更多一些)
如果一个类,有个性化的内容、有状态,就可能存在多个对象,此时就使用 @Bean 。
三、从Spring 中取对象(对象的注入)
1、属性注入——通过 @Autowired 注入,将 Service 类注入到 Controller类中。
结果:
2、Setter 注入
PS:在设置 set 方法时要加上 @AutoWired 注解。
3、构造方法注入(构造函数注入)
结果:
PS:如果只有一个构造函数,就不需要加@AutoWired;如果不只有一个构造函数,就需要使用@AutoWired告诉 Spring 使用哪个构造函数。
PS:构造函数可以注入多个对象,它使用 @AutoWired 去查找对象,若一个类型有一个对象时,就使用 @Qualifier 去知道使用。
4、命名规则
4.1、Spring 存
(1)、五大注解
若前两个字母都是大写,那么就是类名。
其他情况类名都是小写。
(2)、@Bean
命名是方法名。
5、优缺点
5.1、属性注入
优点:简洁、使用方便。
缺点:只能用于 IoC 容器,如果是非 IoC 容器不可用,且只有在使用时才会出现 NPE(空指针异常);不能注入一个 final 修饰的属性(final 修饰的属性需要满足:在定义时就进行初始化;构造函数进行初始化)。
5.2、setter 注入
优点:方便在类实例之后重新对该对象进行配置或注入。(Spring 3.x推荐使用的)
缺点:不能注入一个 final 修饰的属性;注入对象可能会被修改,因为 setter 方法可能会被多次调用,就有被修改的风险。
5.3、构造方法注入
优点:可以注入一个 final 修饰的属性;注入的对象不会被修改;依赖对象在使用前一定会被完全初始化(依赖实在类的构造方法中执行的,构造方法是在类加载阶段就会执行的方法);通用性好(Spring 4.x推荐使用的),构造方法是JDK支持的,所以换任何框架都是使用的。
缺点:注入多个对象时代码会比较繁琐。
6、一种注入关键字:@Resource
在进行类注入时,处理可以使用 @AutoWired 关键字进行注入,还可以使用 @Resource 关键字。
PS:如果没有指定名称,就根据类型匹配;若指定了名称,就根据名称匹配。
PS :@AutoWired 和 @Resource 的区别:
(1)来源不同:@AutoWired 来自于Spring ;@Resource 来自于JDK的注释。(2)参数设置不同:相比于@AutoWired,@Resource 支持更多的参数设置。
(3)@AutoWired 可以用属性注入、构造函数注入、setter 注入;@Resource 只能用于属性注入和 setter 注入,不能用于构造函数注入。
四、Bean 的作用域
1、定义
Bean 的作用域指的是 Bean 在这个Spring 框架中的某种行为模式。
2、作用域
2.1、singleton :单例作用域
描述:该作用域下的 Bean 在IoC 容器中只存在一个实例。该作⽤域下的Bean在IoC容器中只存在⼀个实例:获取Bean(即通过 applicationContext.getBean等⽅法获取)及装配Bean(即通@Autowired注⼊)都是同⼀个对象。
场景:通常无状态的 Bean 使用该作用域。(无状态表示 Bean 对象的属性状态不需要更新)
2.2、prototype :原型作用域
描述:每次对该作⽤域下的Bean的请求都会创建新的实例:获取Bean(即通过applicationContext.getBean等⽅法获取)及装配Bean(即通过@Autowired注⼊)都是新的对象
实例。
场景:通常有状态的 Bean 使用该作用域。
2.3、request :请求作用域
描述:每次http请求会创建新的Bean实例,类似于prototype。
场景:⼀次http的请求和响应的共享Bean 。
2.4、session :会话作用域
描述:在⼀个http session中,定义⼀个Bean实例 。
场景:⽤户回话的共享Bean, ⽐如:记录⼀个⽤户的登陆信息 。
2.5、application :全局作用域
描述:在⼀个http servlet Context中,定义⼀个Bean实例 。
场景:Web应⽤的上下⽂信息,⽐如:记录⼀个应⽤的共享信息。
2.6、websocket :HTTP WebSocket作用域
描述:在⼀个HTTP WebSocket的⽣命周期中,定义⼀个Bean 实例。
场景:WebSocket的每次会话中,保存了⼀个Map结构的头信息,将⽤来包裹客户端消息头。第⼀次初始化后,直到 WebSocket 结束都是同一个Bean 。
五、Bean 的生命周期
1、Spring 的执行流程
(1)启动 Spring 容器
(2)根据配置文件进行 Bean 的初始化
(3)存:把这些对象放进 Spring 容器中
(4)取:装配对象(把依赖对象注入进去)
2、Bean 的生命周期
2.1、生命周期
(1)实例化 Bean(为Bean分配内存空间)
(2)设置属性(Bean注入和装配)
(3)Bean 初始化:执行各种通知(如一些接口方法);执行初始化前置方法(xml定义init-method、使用注解的方式@PostConstruct);执行初始化方法;执行初始化后置方法。
(4)使用 Bean
(5)销毁 Bean(如:单例作用域会在容器销毁时销毁 Bean 。请求作用域会在请求结束时就销毁Bean。)
2.2、代码实现
结果:
PS:先执行PostConstruct,再执行init-method。先执行注解,再执行xml。
PS:PostConstruct 和 PreDestroy区别:
PostConstruct 在构造函数之后执行、在init 方法之前执行。PreDestroy 在 Destroy方法之前执行。
具体可参考:注解@PostConstruct与@PreDestroy使用讲解 - 知乎 (zhihu.com)