lombok使用
當我們建立一個類時,裡面會涉及到很多的get,set和構造方法,我們可以使用lombok來簡化代碼
引入依賴
去maven中央倉庫搜尋lombok
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIyZuBnLyETOjBDZ4UDOkNDOzAjM4ADOyQTNhJDNyUTYzMGM3kzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
選擇一個版本
複制其中的代碼
導入到我們的項目中
在idea的設定中添加lombok插件
這樣的話,我們就可以使用注解來替代寫代碼了
lombok常用注解
注解 | 功能 |
---|---|
@Getter | 自動添加Getter方法 |
@Setter | 自動添加Setter方法 |
@ToString | 自動添加toString方法 |
@EqualsAndHashCode | 自動添加equals和hashCode方法 |
@NoArgsConstructor | 自動添加無參數構造方法 |
@AllArgsConstructor | 自動添加全部參數的構造方法 |
@NonNull | 屬性不能為空 |
@RequiredArgsConstructor | 自動添加必需屬性的構造方法 |
@Data | 包含上述注解的所有功能 |
Bean的作用域
代碼案例
當我們建立了一個User類
package com.demo.model;
import lombok.Data;
@Data
public class User {
private int id;
private String name;
private String password;
}
在UserBean中,我們建立了一個user1,将其姓名設定為“san”
@Component
public class UserBeans {
@Bean
public User user1(){
User user = new User();
user.setId(1);
user.setName("san");
user.setPassword("123");
return user;
}
}
小a寫了一個關于UserController的類,在其中,她用屬性注入獲得user1,并且在自己的getUser方法中,用u引用了user1,更改其姓名為“si”,并列印相關屬性
/**
* author:小a
*/
@Controller
public class UserController {
@Autowired
private User user1;
public void getUser(){
System.out.println("User1: " + user1.toString());
User u = user1;
u.setName("si");
System.out.println("U: " + u.toString());
}
}
小b寫了一個UserAdviceController類,也用屬性注入的方式獲得user1,并在getUser方法中列印其相關屬性
/**
* author:小b
*/
@Controller
public class UserAdviceController {
@Resource
private User user1;
public void getUser(){
System.out.println("b的user1 : " + user1);
}
}
在主程式中擷取小a的UserController和小b的UserAdviceController,并分别調用其getUser方法
public class App {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
UserController uc = context.getBean("userController",UserController.class);
uc.getUser();
UserAdviceController uac = context.getBean("userAdviceController", UserAdviceController.class);
uac.getUser();
}
}
最終我們可以發現,小a将user更改了姓名為“si”,導緻小b這裡的user的姓名也被更改為“si”
這是由于Bean的預設作用域為singleton,也就是單例模式,所有人擷取的都是同一個對象,是以一個人改變了對象的屬性,其他人的對象的屬性也會被改變
Bean一共有下面幾種作用域:
- singleton:單例作用域,整個IoC容器隻存在一個執行個體
- prototype:原型作用域,每次Bean請求都建立新的執行個體
- request:請求作用域,每次http請求建立新的執行個體
- session:會話作用域,每次會話建立新的執行個體
- application:全局作用域,一個http servlet context中定義一個Bean執行個體
- websocket:HTTP WebSocket作用域,一個HTTP WebSocket中定義一個Bean執行個體
需要注意的是前兩個作用域是spring中的,後四個是spring mvc中的
設定作用域
使用@Scope注解可以設定Bean的作用域
@Component
public class UserBeans {
@Bean
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public User user1(){
User user = new User();
user.setId(1);
user.setName("san");
user.setPassword("123");
return user;
}
}
設定為原型作用域後,小b的user的姓名就不會改為“si”了
Spring執行流程
Spring執行一般分為下面幾步
- 啟動Spirng容器
- 執行個體話Bean
- 将Bean注冊到Spring中
- 将Bean注入到類中
Bean的生命周期
Bean的生命周期一般為下面幾步:
- 執行個體話Bean(配置設定記憶體空間)
- 設定屬性(Bean的注入)
- Bean的初始化
- 使用Bean
- 銷毀Bean
其中Bean初始化中有這樣幾步:
- 實作各種Aware通知方法
- 執行BeanPostProcessor初始化前置方法
- 執行BeanPostConstruct初始化方法
- 執行自己制定的init-method方法
- 執行BeanPostProcessor初始化後置方法
我們寫一個類,繼承BeanNameAware,可以重寫其中的setBeanName,我們再通過@PostConstruct來執行其方法
//@Component
public class BeanLifeComponent implements BeanNameAware {
@Override
public void setBeanName(String s) {
System.out.println("執行了通知方法");
}
@PostConstruct
public void postConstruct(){
System.out.println("執行了postConstruct");
}
public void init(){
System.out.println("執行了init method方法");
}
@PreDestroy
public void preDestroy(){
System.out.println("執行preDestroy方法");
}
}
在主程式中調用相關的方法
import com.demo.component.BeanLifeComponent;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class App2 {
public static void main(String[] args) {
ClassPathXmlApplicationContext applicationContext =
new ClassPathXmlApplicationContext("spring-config.xml");
BeanLifeComponent beanLifeComponent =
applicationContext.getBean("myComponent", BeanLifeComponent.class);
System.out.println("使用bean");
applicationContext.destroy();
}
}
我們可以看到執行順序和我們的預期是一緻的