您现在的位置是:首页 >其他 >Spring的作用域与生命周期网站首页其他
Spring的作用域与生命周期
一、lombok的安装与使用
lombok插件可以提供给我们一些注释,这些注释可以很好的帮助我们消除Java代码中大量冗余的代码,可以使得我们的Java类可以看起来非常的干净整洁
1.安装lombok插件
2.pom.xml导入依赖
<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.24</version>
<scope>provided</scope>
</dependency>
3.基本使用
我们创建一个简单的User实体类
public class User {
private int id;
private String name;
private String password;
}
如果我们手动的在类中加入setter+getter,toString等等,如果属性比较多,代码看起来十分的冗余,我们可以使用lombok提供的注解来帮助我们自动生成
以下就是我们lombok的注解了,我们在这里介绍一些常用的注解:
注解 | 作用 |
---|---|
@Data | 为所有属性提供getting、setting、hashCode、equals、toString等方法 |
@Value | 除了将变量都设置为final |
@Setter | 自动生成setting方法 |
@Getter | 自动生成getting方法 |
@ToString | 自动重写toString方法 |
@EqualsAndHashCode | 自动生成equals和hashCode方法 |
@NoArgsConstructor | 生成无参构造器 |
@AllArgsConstructor | 生成一个包含所有参数的构造器,不包含无参构造 |
@RequireArgsConstructor | 生成特定参数的构造器,特定参数指的是final修饰的变量们 |
此时我们没有写setter方法,只是加入了相应注解,lombok帮我们补全,我们可以看到set方法右下角有个logo,以上就是lombok的功能演示
二、Spring作用域
Spring作用域:Spring的作用域是用来控制Bean实例创建的范围和生命周期的,可以根据具体情况选择不同的作用域来达到性能优化、资源利用最大化和可维护性等目的
Spring Bean作用域(Scope):
1.singleton:单例模式。Spring IoC容器中只会存在一个共享的Bean实例,无论有多少个Bean引用它,始终指向同一对象。Singleton作用域是Spring中的缺省作用域,也可以显示的将Bean定义为singleton模式
2.prototype:原型模式。每次通过Spring容器获取prototype定义的Bean时,容器都将创建一个新的Bean实例,每个Bean实例都有自己的属性和状态,而singleton全局只有一个对象
3.request:请求模式。在一次HTTP请求中,容器会返回该Bean的同一个实例,但在不同的请求中会创建新的实例。仅适用于WebApplicationContext环境
4.session:会话模式。在同一个HTTP Session中,每个Bean定义对应一个实例。仅适用于WebApplicationContext环境
5.global seesion:全局会话模式。仅在使用Portlet上下文时有效,表示整个Web应用中所有Portlet共享同一个Bean实例,仅适用于WebApplicationContext环境
6.websocket:网络长连接,只适用于Spring WebSocket项目
我们可以通过两种方式设置Spring Bean作用域:
1.xml配置文件手动设置作用域
因为我们这里是普通的Spring项目所以只有两种作用域类型
2.使用注解进行设置作用域
我们Scope注解还可以传入另一种参数形式
ConfigurableBeanFactory类为我们提供了静态属性,防止我们手动输错
我们来看一下singleton和prototype到底有什么区别:
singleton:
public static void main(String[] args) {
ApplicationContext context =
new ClassPathXmlApplicationContext("spring-config.xml");
//singleton作用域下
User user1 = context.getBean("user",User.class);
User user2 = context.getBean("user",User.class);
System.out.println(user1 == user2);
}
prototype:
public static void main(String[] args) {
ApplicationContext context =
new ClassPathXmlApplicationContext("spring-config.xml");
//prototype作用域下
User user1 = context.getBean("user",User.class);
User user2 = context.getBean("user",User.class);
System.out.println(user1 == user2);
}
我们可以发现我们singleton每次获取都是同一份对象,而prototype每次获取都会去创建一个新的对象
二、Bean原理分析
执行流程
1.首先启动容器,加载配置文件
2.根据配置文件完成Bean的初始化
配置文件中的Bean是按顺序初始化的
3.注册Bean对象到容器中
扫描com.zd.demo包下的注解进行初始化(@Controller,Service,@Component,@Repository),然后初始化我们手动写的Bean
4.装配Bean的属性
如果Bean对象需要其他的Bean作为属性,可以使用注解的方式注入(@Autowired、Resource)
Bean执行流程:启动容器 -> 实例化Bean(分配空间) -> Bean注册到Spring容器中(存对象) -> 将Bean装配到需要的类中(取对象)
Bean的生命周期
Spring Bean的生命周期是从Bean实例化之后,即通过反射创建出对象之后,到Bean成为一个完整的对象,最终存储到单例池中,这个过程称之为Spring Bean的生命周期,大致为分为5个阶段:
1.实例化阶段:Spring框架会取出BeanDefinition的信息进行判断,Bean作用域是否是singleton,是否延迟加载(lazy-init),是否是FactoryBean等,最终Bean通过反射进行实例化
2.设置属性:Bean的注入与装配
3.Bean的初始化阶段:
执行Aware接口方法,如BeanNameAware、BeanFactoryAware、ApplicationContextAware的接口方法
执行BeanPostProcessor方法(before)
执行@PostConstruct初始化方法
行InitializingBean接口的初始化方法
执行自定义指定的init-method方法
执行BeanPostProcessor初始化后置方法(after)
4.使用Bean
5.销毁Bean
执行PreDestroy、DisposableBean接口方法
执行destroy-method方法
Bean初始化过程设置以下几个过程:
1.Bean实例的属性填充
2.Aware接口属性注入
3.BeanPostProcessor的before()方法回调
4.执行@PostConstruct初始化方法
5.InitializingBean接口的初始化方法回调
6.自定义初始化方法init的回调
7.BeanPostProcessor的after()方法回调