1. Bean và ApplicationContext là gì?
1.1. Bean là gì?
Trong documentation của Spring framework, thì bean được khái niệm như sau:
Bạn đang xem: spring bean la gi
In Spring, the objects that sườn 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 giản dị và đơn giản, bean là những module chủ yếu của lịch trình, được đưa đến và vận hành bởi vì Spring IoC container.
Các bean hoàn toàn có thể dựa vào cho nhau, như ví dụ về Car
, Engine
và ChinaEngine
từ trên đầu series cho tới giờ. Sự dựa vào này được tế bào miêu tả mang lại IoC biết nhờ hình thức Dependency injection.
Cách lưu lại class là 1 trong những bean thì bản thân tiếp tục trình diễn nhập bài xích tiếp sau. Lúc này chúng ta chỉ nên biết giản dị và đơn giản nhất là sử dụng @Component
lên class là class ê là 1 trong những bean.
1.2. ApplicationContext là gì?
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 đến BeanFactory. Nó cũng đại loại như ApplicationContext, thay mặt đại diện mang lại 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, hỗ trợ nhiều công 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à tiến hành ApplicationContext. Cơ chế này là Component scan, cũng sẽ tiến hành phát biểu cho tới nhập bài xích tiếp sau.
1.3. 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 với context rồi Câu căn vặn đề ra là đổi thay context ở đâu?
Đó là tức thì dòng sản phẩm chính thức lịch trình 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()
tiếp tục return về một object ApplicationContext
interface, thay mặt đại diện mang lại IoC container.
ApplicationContext context = SpringApplication.run(Application.class, args);
Chúng tớ hoàn toàn có thể mang ra bean kể từ phía trên, sử dụng method getBean()
.
// Lấy rời khỏi bean với class cụ thể
Car xế hộp = context.getBean(Car.class);
// Lấy rời khỏi theo dõi 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);
2. Kĩ thuật inject bean nhập bean khác
Ví dụ chúng ta với nhị bean là Car
và Engine
(như ví dụ từ trên đầu series cho tới giờ). Và Car
thì tùy thuộc vào Engine
, bởi vậy theo dõi Dependency injection thì tất cả chúng ta cần thiết inject Engine
nhập vào Car
.
2.1. Sử dụng @Autowired
Chúng tớ dùng annotation @Autowired
nhằm báo mang lại Spring biết tự động hóa lần và inject bean tương thích nhập địa điểm bịa annotation. Ví dụ.
// Annotation chỉ lưu lại lên class
public interface Engine {
void run();
}
Xem thêm: quang vinh nếu lúc trước em đừng tới lời bài hát
@Component
public class ChinaEngine implements Engine {
@Override
public void run() {}
}
@Component
public class Car {
// Báo mang lại Spring lần bean này phù phù hợp với Engine interface
// Và với cùng một bean tương thích là ChinaEngine
// Nó tương tự với = new ChinaEngine()
@Autowired
private final Engine engine;
}
Cách sử dụng @Autowired
bên trên field là ko được khuyến nghị, bởi nó dùng Java reflection nhằm inject. Chúng tớ nên Để ý đến thay đổi qua chuyện sử dụng inject theo phong cách constructor hoặc setter.
2.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à nên. Khi ê 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 thuộc vào constructor Khi gọi.
Ví dụ class Car
đang được sửa lại nhằm inject Engine
nhập 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 kết thúc bean Car
tiếp tục gọi thêm thắt method setEngine()
tiếp sau đó.
@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 thuộc vào B và ngược lại. Do ê, 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.
3. Khi Spring Boot ko biết lựa chọn bean nào?
3.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 thêm thắt class VNEngine
với tác dụng tương tự động 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 vẫn nhìn thấy nhị bean tương thích nhằm inject nhập Car
. Do cả nhị VNEngine
và ChinaEngine
đều implements Engine
, nhưng mà Car
cần thiết Engine
nên ko biết nên lựa chọn loại này.
3.2. Giải pháp
Có nhị cơ hội giải quyết và xử lý yếu tố này. Thứ nhất là sử dụng @Primary
lưu lại lên một bean. Khi ê 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ông ít bean tương thích nhập context.
@Component
@Primary
public class VNEngine implements Engine {
...
}
Cách 2 là hướng dẫn và chỉ định rõ rệt thương hiệu bean (tên class) rõ ràng được inject bởi vì @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ỉ cần phải có @Qualifier
trước thương hiệu field cần thiết inject nhập là được.
Okay thế là nội dung bài viết thời điểm ngày hôm nay vẫn kết thúc. Hai nội dung bài viết về bean và context của tớ mong muốn tiếp tục mang lại mang lại chúng ta đầy đủ những kỹ năng cơ phiên bản nhằm chuồn tiếp những phần sau của series. Cảm ơn và lưu giữ upvote hoặc clip nhằm cỗ vũ bản thân nhé. Thân!
Xem thêm: andiez yêu em hơn mỗi ngày lời bài hát
Bình luận