Bài ghi chép được sự được chấp nhận của người sáng tác Lê Chí Dũng
1. Bean là gì?
Trong documentation của Spring framework, thì bean được khái niệm như sau:
Bạn đang xem: bean là gì
In Spring, the objects that size the backbone of your application and that are managed by the Spring IoC container are called beans. A bean is an object that is instantiated, assembled, and otherwise managed by a Spring IoC container.
Nói một cơ hội đơn giản và giản dị, bean là những module chủ yếu của công tác, được đưa đến và vận hành vị Spring IoC container.
Các bean rất có thể dựa vào cho nhau, như ví dụ về Car
, Engine
và ChinaEngine
từ đầu series cho tới giờ. Sự dựa vào này được tế bào miêu tả mang đến IoC biết nhờ cách thức Dependency injection.
Lúc này chỉ nên biết đơn giản và giản dị nhất là dùng @Component
lên class là class cơ là 1 trong những bean.
Xem tăng nhiều việc thực hiện Spring bổng cao trên TopDev
ApplicationContext là định nghĩa Spring Boot dùng làm chỉ Spring IoC container, tương tự động như bean là thay mặt đại diện cho những dependency.
Ngoài rời khỏi chúng ta cũng có thể tiếp tục nghe nói tới BeanFactory. Nó cũng đại loại như ApplicationContext, thay mặt đại diện mang đến Spring IoC container tuy nhiên ở tại mức cơ phiên bản. ApplicationContext thì ở tại mức cao hơn nữa, cung ứng nhiều tác dụng rộng lớn BeanFactory như i18n, resolving messages, publishing events,…

Khi phần mềm Spring chạy, Spring IoC container tiếp tục quét tước toàn cỗ packages, lần rời khỏi những bean và đi vào ApplicationContext. Cơ chế này đó là Component scan.
Cách lấy bean rời khỏi kể từ Context
Tất nhiên trước lúc lấy bean rời khỏi kể từ context thì nên đem context rồi. Câu chất vấn đưa ra là phát triển thành context ở đâu?
Đó là ngay lập tức loại chính thức công tác Spring Boot. Câu mệnh lệnh sau.
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
Dòng method SpringApplication.run()
sẽ return về một object ApplicationContext
interface, thay mặt đại diện mang đến IoC container.
ApplicationContext context = SpringApplication.run(Application.class, args);
Chúng tao rất có thể kéo ra bean kể từ trên đây, sử dụng method getBean()
.
// Lấy rời khỏi bean đem class cụ thể
Car xế hộp = context.getBean(Car.class);
// Lấy rời khỏi bám theo thương hiệu và class
// Tuy là Engine.class tuy nhiên Engine lại là interface
Engine engine = context.getBean("ChinaEngine", Engine.class);
3. Kĩ thuật inject bean nhập bean khác
Ví dụ chúng ta đem nhì bean là Car
và Engine
(như ví dụ từ trên đầu series cho tới giờ). Và Car
thì dựa vào vào Engine
, vì thế bám theo Dependency injection thì tất cả chúng ta cần thiết inject Engine
vào trong Car
.
3.1. Sử dụng @Autowired
Chúng tao dùng annotation @Autowired
để báo mang đến Spring biết tự động hóa lần và inject bean tương thích nhập địa điểm đặt điều annotation. Ví dụ.
// Annotation chỉ lưu lại lên class
public interface Engine {
void run();
}
@Component
public class ChinaEngine implements Engine {
@Override
public void run() {}
}
@Component
public class Car {
// Báo mang đến Spring lần bean này phù phù hợp với Engine interface
// Và mang 1 bean tương thích là ChinaEngine
// Nó tương tự với = new ChinaEngine()
@Autowired
private final Engine engine;
}
Cách dùng @Autowired
trên field là ko được khuyến nghị, bởi nó dùng Java reflection nhằm inject. Chúng tao nên xem xét thay đổi qua chuyện sử dụng inject theo phong cách constructor hoặc setter.
3.2. Inject qua chuyện constructor hoặc setter
Code inject theo phong cách constructor-based nên sử dụng khi những module là yêu cầu. Khi cơ Spring Boot khi tạo ra bean (cũng đơn giản tạo ra object, gọi constructor thôi) thì tiếp tục đem những tùy theo constructor khi gọi.
Ví dụ class Car
đã được sửa lại nhằm inject Engine
vào qua chuyện constructor.
@Component
public class Car {
private final Engine engine;
// Các phiên bản Spring Boot mới nhất thì ko cần thiết @Autowired bên trên constructor
public Car(Engine engine) {
this.engine = engine;
}
}
Hoặc sử dụng loại setter-based như sau. Spring Boot sau khoản thời gian tạo ra đoạn bean Car
sẽ gọi tăng method setEngine()
sau cơ.
@Component
public class Car {
private final Engine engine;
// Thêm @Required nhằm setter luôn luôn được gọi nhằm inject
@Required
public void setEngine(Engine engine) {
this.engine = engine;
}
}
Cách sử dụng setter nhằm inject thông thường sử dụng nhập tình huống dựa vào vòng, module A tùy theo B và ngược lại. Do cơ, nếu như cả nhì đều dùng constructor based injection thì Spring Boot sẽ không còn biết nên tạo ra bean này trước. Vì thế, biện pháp là 1 trong những bean tiếp tục sử dụng constructor, một bean sử dụng setter như bên trên.
4. Khi Spring Boot ko biết lựa chọn bean nào?
4.1. Khi nhìn thấy nhiều bean phù hợp
Cũng lấy ví dụ bên trên, nếu như tất cả chúng ta tạo ra tăng class VNEngine
có tính năng tương tự ChinaEngine
.
@Component
public class VNEngine implements Engine {
@Override
public void run() {}
}
Thì Spring Boot tiếp tục báo lỗi như sau (báo khi chạy và cả nhập IDE nữa.

Có thể hiểu bởi Spring Boot tiếp tục nhìn thấy nhì bean tương thích nhằm inject vào Car
. Do cả hai VNEngine
và ChinaEngine
đều implements Engine
, mà Car
cần Engine
nên ko biết nên lựa chọn cái này.
4.2. Giải pháp
Có nhì cơ hội xử lý yếu tố này. Thứ nhất là dùng @Primary
đánh vết lên một bean. Khi cơ bean này sẽ tiến hành ưu tiên lựa chọn rộng lớn, nhập tình huống có khá nhiều bean tương thích nhập context.
@Component
@Primary
public class VNEngine implements Engine {
...
}
Cách 2 là hướng đẫn rõ ràng thương hiệu bean (tên class) ví dụ được inject bằng @Qualifier
.
@Component
public class Car {
@Autowired
@Qualifier("VNEngine") // Phải khớp hoa thông thường luôn luôn nhe
private final Engine engine;
}
Đối với constructor hoặc setter based cũng tương tự động, chỉ việc có @Qualifier
trước thương hiệu field cần thiết inject nhập là được.
3. Spring Bean Life Cycle
1.1. Bean life cycle
Trong bài bác trước tất cả chúng ta tiếp tục lần hiểu sơ lược về bean là gì, thời điểm hôm nay tất cả chúng ta tiếp tục chuồn thâm thúy rộng lớn tí nhé.
Vòng đời (life cycle) của bean được hiểu là kể từ khi bean được đưa đến cho đến khi bị tiêu diệt chuồn, sẽ sở hữu những sự khiếu nại (event) không giống nhau xẩy ra. Về vòng đời của bean rất có thể tế bào miêu tả vị sơ thiết bị sau.

Nhìn có vẻ như nhiều năm và khó khăn hiểu, tuy nhiên đại loại tiếp tục bao gồm công việc sau:
Xem thêm: hmm là gì
- IoC container tạo ra bean bằng phương pháp gọi constructor (có thể inject những bean dependency nhập đây)
- Gọi những setter method nhằm inject những bean nhập vị setter based injection
- Các method khởi tạo ra không giống được gọi (không cần thiết quan hoài nhiều)
@PostConstructor
được gọi- Init method được gọi
Sau cơ bean tiếp tục sẵn sàng hoạt động và sinh hoạt. Nếu tiếp sau đó bean ko sử dụng nữa thì nó sẽ tiến hành hủy:
- Gọi
@PreDestroy
- Hủy bean tựa như các object thông thường
1.2. @PostConstructor
và @PreDestroy
Đây là nhì sự kiện khá cần thiết với bean, chúng ta cũng có thể hook một method nhập cơ nhằm thực ganh đua khi sự kiện xảy ra:
@PostConstruct
là sau khoản thời gian bean tiếp tục khởi tạo ra xong@PreDestroy
là trước lúc bean bị phá huỷ hủy
Chúng tao sử dụng nhì annotation bên trên lưu lại lên method này cơ, method cơ sẽ tiến hành tự động hóa gọi khi sự khiếu nại bean xẩy ra.
class Car {
@Autowired
private final Engine engine;
@PostConstruct
public void testRun() {
engine.run();
engine.stop();
}
@PreDestroy
public void stopEngine() {
engine.stop();
}
}
Như code ví dụ bên trên, bản thân gắn @PostConstruct
cho method testRun()
. Method này được gọi khi bean Car
được đưa đến và khởi tạo ra hoàn hảo. Và trước khi Car
bị phá huỷ diệt, thì nên cần gọi stopEngine
tương tự động như bên trên.
Dùng nhập thực tiễn thì nhì annotation bên trên thực hiện những trọng trách như:
@PostConstruct
dùng nhằm tiến hành một số trong những task khi khởi tạo ra bean@PreDestroy
thực hiện nay những task nhằm lau chùi bean sau khi sử dụng xong
2. Các loại bean
Nói đúng ra thì gọi là những scope, phân loại dựa vào con số bean được đưa đến. Bean bao gồm đem 5 scope:
- Singleton (mặc định): IoC container chỉ tạo ra trúng độc nhất 1 object kể từ class bean này
- Prototype: return một bean object riêng lẻ cho từng chuyến dùng.
- Request: tạo ra từng bean cho từng request
- Session: tạo ra từng bean cho từng session
- Global session: tạo ra từng bean cho từng global session (cái này không hiểu nhiều lắm)
Trong 5 scope bên trên tất cả chúng ta chỉ quan hoài cho tới nhì scope đầu. Thông thường những các bạn sẽ không nhiều vấp cho tới prototype bean, tuy nhiên tôi cũng ghi chép rời khỏi bên trên trên đây luôn luôn.
Đối với singleton bean thì ngoài cần thiết lưu lại gì không còn, nó là đem ấn định rồi. Còn nếu như muốn hướng đẫn một class là prototype bean thì dùng @Scope
như sau.
@Component
@Scope("prototype")
class PrototypeBean {
...
}
Nói rõ ràng rộng lớn về prototype bean, ví dụ bean X được dùng vị nhì bean không giống là A, B:
- Nếu X là singleton bean, thì có duy nhất một object X được đưa đến. A và B sử dụng công cộng X.
- Nếu X là prototype bean, thì đem 2 X được đưa đến mang đến 2 bean không giống dùng là X mang đến A và X mang đến B.
3. Cách khái niệm bean
Có 3 cơ hội khái niệm class là 1 trong những bean:
- Khai báo nhập tệp tin XML
- Dùng annotation bên trên class
- Dùng
@Configuration
và@Bean
Tùy từng tình huống ví dụ nhưng mà sử dụng mang đến tương thích. Ví dụ nhập series này bản thân ko bàn thâm thúy về thông số kỹ thuật bean vị XML (do Spring Boot sinh rời khỏi ko nên nhằm cấu hình).
3.1. Dùng XML, annotations
Nhưng đơn giản và giản dị, chúng ta cũng nên biết trước đó Spring sử dụng XML nhằm thông số kỹ thuật những bean như sau. Nó khá là vô cùng nên người tao sử dụng cách thứ hai hoặc là hơn.
<?xml version = "1.0" encoding = "UTF-8"?>
<beans xmlns = "http://www.springframework.org/schema/beans"
xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation = "http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<!-- Đây là bean Car -->
<bean id="" class="Car" init-method="testRun">
<!-- Cấu hình tính chất property mang đến bean -->
</bean>
</beans>
Do cơ người tao mới nhất sử dụng cơ hội thông số kỹ thuật bean dựa vào những annotation như @Component
. Cụ thể thì như bài bác trước đem thưa, chỉ việc tiến công dấu @Component
lên bên trên class thì IoC tiếp tục biết và tạo ra bean kể từ class cơ.
@Component
public class Car {
...
}
Ngoài rời khỏi đem những annotations không giống ví dụ rộng lớn như @Service
, @Repository
, @Controller
,… cũng bao gồm @Component
, nên ứng dụng của bọn chúng cũng chính là tạo ra bean.
3.3. Dùng @Bean
bên trong @Configuration
Cách này sử dụng mang đến tình huống bean cần thiết tiến hành nhiều thao tác phức tạp nhằm khởi tạo ra, hoặc có khá nhiều bean tương quan cùng nhau. Do cơ, chứ không khởi tạo ra riêng rẽ rẽ từng class là từng bean, thì gom công cộng những bean cần thiết khởi tạo ra lại cho vô class chứa chấp là @Configuration
.
Thường thì những class tiến công dấu @Configuration
có hậu tố là Config.
@Configuration
public class AppConfig {
// Khởi tạo ra trước những logic phức tạp
// cũng có thể quy ấn định trật tự khởi tạo ra bean vị `@Order`
public AppConfig() {
...
}
@Bean
public Car carBean() {
return new Car();
}
@Bean
public PasswordEncoder passwordEncoderBean() {
return new BCryptPasswordEncoder();
}
// cũng có thể khái niệm nhiều bean không giống với @Bean
}
Khi Spring nhìn thấy class @Configuration
, nó sẽ bị tạo ra bean của class này trước (do @Configuration
cũng là @Component
). Trong khi tạo ra thì những logic khởi tạo ra cũng khá được thực ganh đua, nhằm sẵn sàng sẵn sàng tạo ra các @Bean
bên nhập.
Sau cơ Spring Boot tiếp tục lần những method được tiến công dấu @Bean
bên trong @Configuration
để tạo ra bean. Thông thường những bean dạng này cụt và return ngay lập tức object chứ không hề nên nhằm Spring Boot đưa đến.
Các bean cũng khá được đi vào ApplicationContext như thông thường.
Tuy nhiên, ko nên class này lưu lại cũng khá được tạo ra bean. Mà nên đem ĐK quy trình component scan của IoC nên nhìn thấy nó. Chúng tao tiếp tục chuồn tiếp về component scan ngay lập tức tại đây.
4. Component scan
4.1. Cách component scan hoạt động
Khi phần mềm Spring Boot chính thức chạy, thì nó sẽ bị lần không còn những class lưu lại là bean nhập công tác và tạo ra bean. Quá trình lần tìm tòi những bean này gọi là component scan.
Component scan tiếp tục lần toàn cỗ class ở package nằm trong cấp cho hoặc những package thấp hơn
Do cơ, class tiến công dấu @SpringBootApplication
có chứa chấp main method được xem là điểm chính thức. Spring Boot tiếp tục lần kể từ package này (package gốc) lần xuống muốn tạo những bean.
src/main/java/
com/tonghoangvu/demo/
DemoApplication.java
components/
Engine.java
ChinaEngine.java
Car.java
controllers/
UserController.java
Do cấu tạo folder đem ấn định của Spring Boot nó thế, nên kể từ package gốc có DemoApplication.java
là com.tonghoangvu.demo
, nó sẽ bị tìm:
- Các class nằm trong cấp cho, lần được
DemoApplication
class, tạo ra bean - Tìm xuống những package thấp rộng lớn như
com.tonghoangvu.demo.components
vàcom.tonghoangvu.demo.controllers
, lần tăng được những class nhưChinaEngine
,Car
,UserController
(Engine.java
là interface nhé).
Do cơ, đem ấn định từng class được khai báo là bean đều rất có thể được tìm ra.
4.2. Tùy chỉnh package lần kiếm
Trong tình huống chúng ta chỉ ham muốn Spring Boot lần những bean nhập một package ví dụ, ví dụ chỉ lần nhập thư mục components
thì đem 2 cơ hội như sau.
// Cách 1 sử dụng @ComponentScan với cùng một hoặc nhiều string (cần đem {})
@ComponentScan("com.tonghoangvu.demo.components")
// Cách 2 tăng tính chất @SpringBootApplication scanBasePackages
@SpringBootApplication(scanBasePackages = {
"com.tonghoangvu.demo.components",
"com.tonghoangvu.demo.controllers"
})
public class DemoApplication {
public static void main(String[] args) {
...
}
}
Bài ghi chép thời điểm hôm nay cho tới đó là đoạn, cũng coi như thể chuồn ngay gần không còn phần lý thuyết của Spring Boot rồi.
Xem thêm: name nghĩa là gì
Bài ghi chép gốc được đăng lên bên trên lcdung.top
Có thể chúng ta quan tiền tâm:
- ReactJS – Tìm hiểu về Component Life Cycle
- Gọi những object của Autowired Collections bám theo trật tự nhập Spring Framework
- Giải mến React Component Lifecycle
Xem tăng Việc thực hiện IT hấp dẫn trên TopDev
Bình luận