Spring - Hướng dẫn nhanh
Spring là khung phát triển ứng dụng phổ biến nhất cho Java doanh nghiệp. Hàng triệu nhà phát triển trên khắp thế giới sử dụng Spring Framework để tạo mã hiệu suất cao, dễ kiểm tra và có thể sử dụng lại.
Spring framework là một nền tảng Java mã nguồn mở. Ban đầu nó được viết bởi Rod Johnson và được phát hành lần đầu tiên theo giấy phép Apache 2.0 vào tháng 6 năm 2003.
Lò xo nhẹ khi nói đến kích thước và độ trong suốt. Phiên bản cơ bản của Spring framework có dung lượng khoảng 2MB.
Các tính năng cốt lõi của Spring Framework có thể được sử dụng để phát triển bất kỳ ứng dụng Java nào, nhưng có những phần mở rộng để xây dựng các ứng dụng web trên nền tảng Java EE. Spring framework nhắm mục tiêu làm cho việc phát triển J2EE dễ sử dụng hơn và thúc đẩy các phương pháp lập trình tốt bằng cách cho phép mô hình lập trình dựa trên POJO.
Lợi ích của việc sử dụng Spring Framework
Sau đây là danh sách một số lợi ích tuyệt vời của việc sử dụng Spring Framework:
Spring cho phép các nhà phát triển phát triển các ứng dụng cấp doanh nghiệp bằng cách sử dụng POJO. Lợi ích của việc chỉ sử dụng POJO là bạn không cần sản phẩm vùng chứa EJB chẳng hạn như máy chủ ứng dụng nhưng bạn có tùy chọn chỉ sử dụng vùng chứa servlet mạnh mẽ như Tomcat hoặc một số sản phẩm thương mại.
Mùa xuân được tổ chức theo kiểu mô-đun. Mặc dù số lượng gói và lớp là đáng kể, nhưng bạn chỉ phải lo lắng về những gói và lớp bạn cần và bỏ qua phần còn lại.
Spring không phát minh lại bánh xe, thay vào đó nó thực sự sử dụng một số công nghệ hiện có như một số khung ORM, khung ghi nhật ký, bộ định thời JEE, Quartz và JDK và các công nghệ chế độ xem khác.
Việc kiểm tra một ứng dụng được viết bằng Spring rất đơn giản vì mã phụ thuộc vào môi trường được chuyển vào khuôn khổ này. Hơn nữa, bằng cách sử dụng JavaBeanstyle POJOs, việc sử dụng phương pháp tiêm phụ thuộc để đưa dữ liệu thử nghiệm trở nên dễ dàng hơn.
Khung công tác web của Spring là một khung công tác web MVC được thiết kế tốt, cung cấp một giải pháp thay thế tuyệt vời cho các khung công tác web như Struts hoặc các khung công tác web được thiết kế quá mức hoặc ít phổ biến hơn.
Spring cung cấp một API thuận tiện để dịch các ngoại lệ dành riêng cho công nghệ (ví dụ như được ném bởi JDBC, Hibernate hoặc JDO) thành các ngoại lệ nhất quán, không được kiểm tra.
Ví dụ, các thùng chứa IoC nhẹ có xu hướng nhẹ, đặc biệt là khi so sánh với các thùng chứa EJB. Điều này có lợi cho việc phát triển và triển khai các ứng dụng trên máy tính có bộ nhớ và tài nguyên CPU hạn chế.
Spring cung cấp một giao diện quản lý giao dịch nhất quán có thể giảm quy mô xuống giao dịch cục bộ (ví dụ: sử dụng một cơ sở dữ liệu duy nhất) và mở rộng quy mô lên các giao dịch toàn cầu (ví dụ: sử dụng JTA).
Tiêm phụ thuộc (DI)
Công nghệ mà Spring được xác định nhiều nhất là Dependency Injection (DI)hương vị của Inversion of Control. CácInversion of Control (IoC)là một khái niệm chung, và nó có thể được diễn đạt theo nhiều cách khác nhau. Dependency Injection chỉ là một ví dụ cụ thể về Inversion of Control.
Khi viết một ứng dụng Java phức tạp, các lớp ứng dụng phải độc lập nhất có thể với các lớp Java khác để tăng khả năng sử dụng lại các lớp này và kiểm tra chúng độc lập với các lớp khác trong khi kiểm thử đơn vị. Dependency Injection giúp dán các lớp này lại với nhau và đồng thời giữ cho chúng độc lập.
Tiêm phụ thuộc chính xác là gì? Chúng ta hãy xem xét hai từ này riêng biệt. Ở đây phần phụ thuộc chuyển thành sự liên kết giữa hai lớp. Ví dụ, lớp A là phụ thuộc của lớp B. Bây giờ, hãy xem phần thứ hai, tiêm. Tất cả điều này có nghĩa là, lớp B sẽ được IoC đưa vào lớp A.
Việc chèn phụ thuộc có thể xảy ra theo cách truyền các tham số cho hàm tạo hoặc bằng cách sử dụng các phương thức setter sau khi xây dựng. Vì Dependency Injection là trung tâm của Spring Framework, chúng tôi sẽ giải thích khái niệm này trong một chương riêng với ví dụ liên quan.
Lập trình hướng theo khía cạnh (AOP)
Một trong những thành phần quan trọng của Spring là Aspect Oriented Programming (AOP)khuôn khổ. Các hàm mở rộng nhiều điểm của một ứng dụng được gọi làcross-cutting concernsvà những mối quan tâm xuyên suốt này tách biệt về mặt khái niệm với logic nghiệp vụ của ứng dụng. Có nhiều ví dụ điển hình phổ biến về các khía cạnh bao gồm ghi nhật ký, giao dịch khai báo, bảo mật, bộ nhớ đệm, v.v.
Đơn vị quan trọng của mô-đun trong OOP là lớp, trong khi trong AOP, đơn vị mô-đun là khía cạnh. DI giúp bạn tách các đối tượng ứng dụng của mình khỏi nhau, trong khi AOP giúp bạn tách các mối quan tâm xuyên suốt khỏi các đối tượng mà chúng ảnh hưởng.
Mô-đun AOP của Spring Framework cung cấp một triển khai lập trình hướng khía cạnh cho phép bạn xác định các phương thức chặn và các phím tắt để phân tách rõ ràng mã thực thi chức năng cần được tách biệt. Chúng ta sẽ thảo luận thêm về các khái niệm Spring AOP trong một chương riêng.
Spring có thể là điểm dừng chân duy nhất cho tất cả các ứng dụng doanh nghiệp của bạn. Tuy nhiên, Spring là mô-đun, cho phép bạn chọn và chọn mô-đun nào có thể áp dụng cho bạn mà không cần phải mang phần còn lại. Phần sau cung cấp chi tiết về tất cả các mô-đun có sẵn trong Spring Framework.
Spring Framework cung cấp khoảng 20 mô-đun có thể được sử dụng dựa trên yêu cầu ứng dụng.
Thùng chứa lõi
Vùng chứa lõi bao gồm các mô-đun Core, Beans, Context và Expression Language, chi tiết về chúng như sau:
Các Core mô-đun cung cấp các phần cơ bản của khuôn khổ, bao gồm các tính năng IoC và Dependency Injection.
Các Bean mô-đun cung cấp BeanFactory, là một triển khai phức tạp của mẫu nhà máy.
Các Contextmô-đun xây dựng dựa trên nền tảng vững chắc do mô-đun Core và Beans cung cấp và nó là phương tiện để truy cập bất kỳ đối tượng nào được xác định và cấu hình. Giao diện ApplicationContext là tâm điểm của mô-đun Ngữ cảnh.
Các SpEL mô-đun cung cấp một ngôn ngữ biểu thức mạnh mẽ để truy vấn và thao tác một biểu đồ đối tượng trong thời gian chạy.
Tích hợp / Truy cập Dữ liệu
Lớp Tích hợp / Truy cập Dữ liệu bao gồm các mô-đun JDBC, ORM, OXM, JMS và Giao dịch có chi tiết như sau:
Các JDBC mô-đun cung cấp một lớp trừu tượng JDBC loại bỏ nhu cầu mã hóa liên quan đến JDBC tẻ nhạt.
Các ORM mô-đun cung cấp các lớp tích hợp cho các API ánh xạ quan hệ đối tượng phổ biến, bao gồm JPA, JDO, Hibernate và iBatis.
Các OXM mô-đun cung cấp một lớp trừu tượng hỗ trợ triển khai ánh xạ đối tượng / XML cho JAXB, Castor, XMLBeans, JiBX và XStream.
Dịch vụ nhắn tin Java JMS mô-đun chứa các tính năng để sản xuất và tiêu thụ thông điệp.
Các Transaction mô-đun hỗ trợ quản lý giao dịch theo chương trình và khai báo cho các lớp triển khai các giao diện đặc biệt và cho tất cả các POJO của bạn.
Web
Lớp Web bao gồm các mô-đun Web, Web-MVC, Web-Socket và Web-Portlet, chi tiết về chúng như sau:
Các Web mô-đun cung cấp các tính năng tích hợp hướng web cơ bản như chức năng tải lên tệp nhiều phần và khởi tạo vùng chứa IoC bằng trình nghe servlet và ngữ cảnh ứng dụng hướng web.
Các Web-MVC mô-đun chứa triển khai Model-View-Controller (MVC) của Spring cho các ứng dụng web.
Các Web-Socket mô-đun cung cấp hỗ trợ cho giao tiếp hai chiều dựa trên WebSocket giữa máy khách và máy chủ trong các ứng dụng web.
Các Web-Portlet mô-đun cung cấp triển khai MVC được sử dụng trong môi trường portlet và phản ánh chức năng của mô-đun Web-Servlet.
Điều khoản khác
Có một số mô-đun quan trọng khác như mô-đun AOP, Aspects, Instrumentation, Web và Test. Chi tiết về chúng như sau:
Các AOP mô-đun cung cấp một triển khai lập trình hướng khía cạnh cho phép bạn xác định các phương thức chặn và các phím tắt để tách mã rõ ràng triển khai chức năng cần được tách biệt.
Các Aspects mô-đun cung cấp tích hợp với AspectJ, một lần nữa là một khung AOP mạnh mẽ và trưởng thành.
Các Instrumentation mô-đun cung cấp hỗ trợ thiết bị đo lớp và triển khai trình nạp lớp được sử dụng trong các máy chủ ứng dụng nhất định.
Các Messagingmô-đun cung cấp hỗ trợ cho STOMP dưới dạng giao thức phụ WebSocket để sử dụng trong các ứng dụng. Nó cũng hỗ trợ mô hình lập trình chú thích để định tuyến và xử lý các thông điệp STOMP từ các máy khách WebSocket.
Các Test mô-đun hỗ trợ kiểm tra các thành phần Spring với các khung JUnit hoặc TestNG.
Chương này sẽ hướng dẫn bạn cách chuẩn bị một môi trường phát triển để bắt đầu công việc của bạn với Spring Framework. Nó cũng sẽ dạy bạn cách thiết lập JDK, Tomcat và Eclipse trên máy tính của bạn trước khi bạn thiết lập Spring Framework -
Bước 1 - Thiết lập Bộ phát triển Java (JDK)
Bạn có thể tải xuống phiên bản SDK mới nhất từ trang web Java của Oracle - Java SE Downloads. Bạn sẽ tìm thấy hướng dẫn cài đặt JDK trong các tệp đã tải xuống, hãy làm theo hướng dẫn đã cho để cài đặt và định cấu hình thiết lập. Cuối cùng đặt các biến môi trường PATH và JAVA_HOME để tham chiếu đến thư mục chứa java và javac, thường là java_install_dir / bin và java_install_dir tương ứng.
Nếu bạn đang chạy Windows và đã cài đặt JDK trong C: \ jdk1.6.0_15, bạn sẽ phải đặt dòng sau vào tệp C: \ autoexec.bat của mình.
set PATH=C:\jdk1.6.0_15\bin;%PATH%
set JAVA_HOME=C:\jdk1.6.0_15
Ngoài ra, trên Windows NT / 2000 / XP, bạn sẽ phải nhấp chuột phải vào Máy tính của tôi, chọn Thuộc tính → Nâng cao → Biến môi trường. Sau đó, bạn sẽ phải cập nhật giá trị PATH và nhấp vào nút OK.
Trên Unix (Solaris, Linux, v.v.), nếu SDK được cài đặt trong /usr/local/jdk1.6.0_15 và bạn sử dụng trình bao C, bạn sẽ phải đặt phần sau vào tệp .cshrc của mình.
setenv PATH /usr/local/jdk1.6.0_15/bin:$PATH
setenv JAVA_HOME /usr/local/jdk1.6.0_15
Ngoài ra, nếu bạn sử dụng Môi trường phát triển tích hợp (IDE) như Borland JBuilder, Eclipse, IntelliJ IDEA hoặc Sun ONE Studio, bạn sẽ phải biên dịch và chạy một chương trình đơn giản để xác nhận rằng IDE biết bạn đã cài đặt Java ở đâu. Nếu không, bạn sẽ phải thực hiện thiết lập thích hợp như được cung cấp trong tài liệu của IDE.
Bước 2 - Cài đặt API ghi nhật ký chung Apache
Bạn có thể tải xuống phiên bản mới nhất của Apache Commons Logging API từ https://commons.apache.org/logging/. Sau khi bạn tải xuống bản cài đặt, hãy giải nén bản phân phối nhị phân vào một vị trí thuận tiện. Ví dụ: trong C: \ commons-logging-1.1.1 trên Windows hoặc /usr/local/commons-logging-1.1.1 trên Linux / Unix. Thư mục này sẽ có các tệp jar sau và các tài liệu hỗ trợ khác, v.v.
Đảm bảo rằng bạn đặt biến CLASSPATH của mình trên thư mục này đúng cách, nếu không bạn sẽ gặp sự cố khi chạy ứng dụng của mình.
Bước 3 - Thiết lập IDE Eclipse
Tất cả các ví dụ trong hướng dẫn này đã được viết bằng Eclipse IDE. Vì vậy, chúng tôi khuyên bạn nên cài đặt phiên bản Eclipse mới nhất trên máy tính của mình.
Để cài đặt Eclipse IDE, hãy tải xuống các tệp nhị phân Eclipse mới nhất từ https://www.eclipse.org/downloads/. Sau khi bạn tải xuống bản cài đặt, hãy giải nén bản phân phối nhị phân vào một vị trí thuận tiện. Ví dụ: trong C: \ eclipse trên Windows hoặc / usr / local / eclipse trên Linux / Unix và cuối cùng đặt biến PATH một cách thích hợp.
Eclipse có thể được khởi động bằng cách thực hiện các lệnh sau trên máy Windows hoặc bạn có thể chỉ cần nhấp đúp vào eclipse.exe
%C:\eclipse\eclipse.exe
Eclipse có thể được khởi động bằng cách thực hiện các lệnh sau trên máy Unix (Solaris, Linux, v.v.) -
$/usr/local/eclipse/eclipse
Sau khi khởi động thành công, nếu mọi thứ đều ổn thì nó sẽ hiển thị kết quả sau:
Bước 4 - Thiết lập Thư viện Spring Framework
Bây giờ nếu mọi thứ đều ổn, thì bạn có thể tiến hành thiết lập Spring framework của mình. Sau đây là các bước đơn giản để tải xuống và cài đặt framework trên máy tính của bạn.
Chọn xem bạn muốn cài đặt Spring trên Windows hay Unix, sau đó tiến hành bước tiếp theo để tải xuống tệp .zip cho Windows và tệp .tz cho Unix.
Tải xuống phiên bản mới nhất của mã nhị phân khuôn khổ Spring từ https://repo.spring.io/release/org/springframework/spring.
Tại thời điểm phát triển hướng dẫn này, spring-framework-4.1.6.RELEASE-dist.zipđã được tải xuống trên máy Windows. Sau khi tệp đã tải xuống được giải nén, nó cung cấp cấu trúc thư mục sau bên trong E: \ spring.
Bạn sẽ tìm thấy tất cả các thư viện Spring trong thư mục E:\spring\libs. Đảm bảo rằng bạn đặt biến CLASSPATH của mình trên thư mục này đúng cách, nếu không bạn sẽ gặp sự cố khi chạy ứng dụng của mình. Nếu bạn đang sử dụng Eclipse, thì không bắt buộc phải đặt CLASSPATH vì tất cả cài đặt sẽ được thực hiện thông qua Eclipse.
Khi bạn đã hoàn thành bước cuối cùng này, bạn đã sẵn sàng tiếp tục với Ví dụ mùa xuân đầu tiên của mình trong chương tiếp theo.
Hãy để chúng tôi bắt đầu lập trình thực tế với Spring Framework. Trước khi bắt đầu viết ví dụ đầu tiên bằng cách sử dụng Spring framework, bạn phải đảm bảo rằng bạn đã thiết lập môi trường Spring đúng cách như đã giải thích trong Chương Thiết lập Môi trường - Spring . Chúng tôi cũng giả định rằng bạn có một chút kiến thức về Eclipse IDE.
Bây giờ chúng ta hãy tiến hành viết một ứng dụng mùa xuân đơn giản, nó sẽ in "Hello World!" hoặc bất kỳ thông báo nào khác dựa trên cấu hình được thực hiện trong tệp Cấu hình Đậu Mùa Xuân.
Bước 1 - Tạo dự án Java
Bước đầu tiên là tạo một Dự án Java đơn giản bằng Eclipse IDE. Làm theo tùy chọnFile → New → Project và cuối cùng chọn Java Projectwizard từ danh sách wizard. Bây giờ đặt tên cho dự án của bạn làHelloSpring bằng cách sử dụng cửa sổ thuật sĩ như sau:
Khi dự án của bạn được tạo thành công, bạn sẽ có nội dung sau trong Project Explorer -
Bước 2 - Thêm Thư viện Bắt buộc
Bước thứ hai, chúng ta hãy thêm Spring Framework và các thư viện API ghi nhật ký chung vào dự án của mình. Để làm điều này, hãy nhấp chuột phải vào tên dự án của bạnHelloSpring và sau đó làm theo tùy chọn sau có sẵn trong menu ngữ cảnh - Build Path → Configure Build Path để hiển thị cửa sổ Java Build Path như sau:
Bây giờ sử dụng Add External JARs nút có sẵn dưới Libraries để thêm các JAR cốt lõi sau từ thư mục cài đặt Spring Framework và Common Logging -
commons-logging-1.1.1
spring-aop-4.1.6.RELEASE
spring-aspects-4.1.6.RELEASE
spring-beans-4.1.6.RELEASE
spring-context-4.1.6.RELEASE
spring-context-support-4.1.6.RELEASE
spring-core-4.1.6.RELEASE
spring-expression-4.1.6.RELEASE
spring-instrument-4.1.6.RELEASE
spring-instrument-tomcat-4.1.6.RELEASE
spring-jdbc-4.1.6.RELEASE
spring-jms-4.1.6.RELEASE
spring-messaging-4.1.6.RELEASE
spring-orm-4.1.6.RELEASE
spring-oxm-4.1.6.RELEASE
spring-test-4.1.6.RELEASE
spring-tx-4.1.6.RELEASE
spring-web-4.1.6.RELEASE
spring-webmvc-4.1.6.RELEASE
spring-webmvc-portlet-4.1.6.RELEASE
spring-websocket-4.1.6.RELEASE
Bước 3 - Tạo tệp nguồn
Bây giờ chúng ta hãy tạo các tệp nguồn thực tế trong HelloSpringdự án. Trước tiên, chúng ta cần tạo một gói có têncom.tutorialspoint. Để làm điều này, nhấp chuột phải vàosrc trong phần trình khám phá gói và làm theo tùy chọn - New → Package.
Tiếp theo chúng ta sẽ tạo HelloWorld.java và MainApp.java các tệp trong gói com.tutorialspoint.
Đây là nội dung của HelloWorld.java tập tin -
package com.tutorialspoint;
public class HelloWorld {
private String message;
public void setMessage(String message){
this.message = message;
}
public void getMessage(){
System.out.println("Your Message : " + message);
}
}
Sau đây là nội dung của tệp thứ hai MainApp.java -
package com.tutorialspoint;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MainApp {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");
HelloWorld obj = (HelloWorld) context.getBean("helloWorld");
obj.getMessage();
}
}
Hai điểm quan trọng cần lưu ý sau đây về chương trình chính:
Bước đầu tiên là tạo bối cảnh ứng dụng nơi chúng tôi đã sử dụng API khung ClassPathXmlApplicationContext(). API này tải tệp cấu hình bean và cuối cùng dựa trên API được cung cấp, nó sẽ đảm nhận việc tạo và khởi tạo tất cả các đối tượng, tức là các bean được đề cập trong tệp cấu hình.
Bước thứ hai được sử dụng để lấy đậu cần thiết bằng cách sử dụng getBean()phương pháp của bối cảnh đã tạo. Phương thức này sử dụng bean ID để trả về một đối tượng chung, đối tượng này cuối cùng có thể được ép vào đối tượng thực. Khi bạn có một đối tượng, bạn có thể sử dụng đối tượng này để gọi bất kỳ phương thức lớp nào.
Bước 4 - Tạo tệp cấu hình Bean
Bạn cần tạo tệp Cấu hình hạt đậu, là tệp tin XML và hoạt động như một chất kết dính các hạt đậu, tức là các lớp lại với nhau. Tệp này cần được tạo trongsrc thư mục như được hiển thị trong ảnh chụp màn hình sau -
Thông thường các nhà phát triển đặt tên tệp này là Beans.xml, nhưng bạn có thể độc lập để chọn bất kỳ tên nào bạn thích. Bạn phải đảm bảo rằng tệp này có sẵn trong CLASSPATH và sử dụng cùng tên trong ứng dụng chính trong khi tạo ngữ cảnh ứng dụng như được hiển thị trong tệp MainApp.java.
Beans.xml được sử dụng để gán các ID duy nhất cho các bean khác nhau và kiểm soát việc tạo các đối tượng với các giá trị khác nhau mà không ảnh hưởng đến bất kỳ tệp nguồn Spring nào. Ví dụ: sử dụng tệp sau, bạn có thể chuyển bất kỳ giá trị nào cho biến "message" và bạn có thể in các giá trị khác nhau của message mà không ảnh hưởng đến các tệp HelloWorld.java và MainApp.java. Hãy để chúng tôi xem nó hoạt động như thế nào -
<?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">
<bean id = "helloWorld" class = "com.tutorialspoint.HelloWorld">
<property name = "message" value = "Hello World!"/>
</bean>
</beans>
Khi ứng dụng Spring được tải vào bộ nhớ, Framework sử dụng tệp cấu hình ở trên để tạo tất cả các bean được xác định và gán cho chúng một ID duy nhất như được định nghĩa trong <bean>nhãn. Bạn có thể dùng<property> để chuyển các giá trị của các biến khác nhau được sử dụng tại thời điểm tạo đối tượng.
Bước 5 - Chạy chương trình
Khi bạn đã hoàn tất việc tạo tệp cấu hình nguồn và tệp, bạn đã sẵn sàng cho bước này, bước này đang biên dịch và chạy chương trình của bạn. Để thực hiện việc này, hãy giữ cho tab tệp MainApp.Java hoạt động và sử dụngRun tùy chọn có sẵn trong IDE Eclipse hoặc sử dụng Ctrl + F11 để biên dịch và chạy MainAppứng dụng. Nếu mọi thứ đều ổn với ứng dụng của bạn, điều này sẽ in ra thông báo sau trong bảng điều khiển của Eclipse IDE:
Your Message : Hello World!
Xin chúc mừng, bạn đã tạo thành công Đơn đăng ký mùa xuân đầu tiên của mình. Bạn có thể thấy sự linh hoạt của ứng dụng Spring ở trên bằng cách thay đổi giá trị của thuộc tính "message" và giữ nguyên cả hai tệp nguồn.
Vùng chứa Spring là cốt lõi của Spring Framework. Vùng chứa sẽ tạo các đối tượng, kết nối chúng lại với nhau, cấu hình chúng và quản lý vòng đời hoàn chỉnh của chúng từ khi tạo ra cho đến khi bị phá hủy. Spring container sử dụng DI để quản lý các thành phần tạo nên một ứng dụng. Những vật thể này được gọi là Spring Beans, chúng ta sẽ thảo luận trong chương sau.
Vùng chứa nhận hướng dẫn về những đối tượng nào cần khởi tạo, cấu hình và lắp ráp bằng cách đọc siêu dữ liệu cấu hình được cung cấp. Siêu dữ liệu cấu hình có thể được biểu diễn bằng XML, chú thích Java hoặc mã Java. Biểu đồ sau đây thể hiện chế độ xem cấp cao về cách hoạt động của Spring. Vùng chứa Spring IoC sử dụng các lớp Java POJO và siêu dữ liệu cấu hình để tạo ra một hệ thống hoặc ứng dụng được định cấu hình và thực thi đầy đủ.
Spring cung cấp hai loại thùng chứa riêng biệt sau đây.
Sr.No. | Vùng chứa & Mô tả |
---|---|
1 | Spring BeanFactory Container Đây là vùng chứa đơn giản nhất cung cấp hỗ trợ cơ bản cho DI và được định nghĩa bởi giao diện org.springframework.beans.factory.BeanFactory . BeanFactory và các giao diện liên quan, chẳng hạn như BeanFactoryAware, InitializingBean, DisposableBean, vẫn hiện diện trong Spring với mục đích tương thích ngược với một số lượng lớn các khuôn khổ bên thứ ba tích hợp với Spring. |
2 | Spring ApplicationContext Container Vùng chứa này bổ sung thêm chức năng dành riêng cho doanh nghiệp, chẳng hạn như khả năng giải quyết thông báo văn bản từ tệp thuộc tính và khả năng xuất bản các sự kiện ứng dụng cho những người nghe sự kiện quan tâm. Vùng chứa này được xác định bởi giao diện org.springframework.context.ApplicationContext . |
Vùng chứa ApplicationContext bao gồm tất cả các chức năng của vùng chứa BeanFactory , do đó, nó thường được khuyến nghị hơn BeanFactory . BeanFactory vẫn có thể được sử dụng cho các ứng dụng nhẹ như thiết bị di động hoặc các ứng dụng dựa trên applet, nơi lưu lượng và tốc độ dữ liệu là đáng kể.
Các đối tượng tạo thành xương sống của ứng dụng của bạn và được quản lý bởi vùng chứa Spring IoC được gọi là beans. Bean là một đối tượng được khởi tạo, lắp ráp và quản lý bởi một vùng chứa Spring IoC. Các bean này được tạo bằng siêu dữ liệu cấu hình mà bạn cung cấp cho vùng chứa. Ví dụ, ở dạng định nghĩa XML <bean /> mà bạn đã thấy trong các chương trước.
Định nghĩa Bean chứa thông tin được gọi là configuration metadata, cần thiết cho vùng chứa biết những điều sau:
- Cách tạo hạt đậu
- Chi tiết về vòng đời của Bean
- Bean's phụ thuộc
Tất cả siêu dữ liệu cấu hình ở trên chuyển thành một tập hợp các thuộc tính sau đây tạo nên mỗi định nghĩa bean.
Sr.No. | Thuộc tính & Mô tả |
---|---|
1 | class Thuộc tính này là bắt buộc và chỉ định lớp bean được sử dụng để tạo bean. |
2 | name Thuộc tính này chỉ định mã định danh bean duy nhất. Trong siêu dữ liệu cấu hình dựa trên XML, bạn sử dụng thuộc tính id và / hoặc tên để chỉ định (các) mã định danh bean. |
3 | scope Thuộc tính này chỉ định phạm vi của các đối tượng được tạo từ một định nghĩa bean cụ thể và nó sẽ được thảo luận trong chương phạm vi bean. |
4 | constructor-arg Điều này được sử dụng để chèn các phụ thuộc và sẽ được thảo luận trong các chương tiếp theo. |
5 | properties Điều này được sử dụng để chèn các phụ thuộc và sẽ được thảo luận trong các chương tiếp theo. |
6 | autowiring mode Điều này được sử dụng để chèn các phụ thuộc và sẽ được thảo luận trong các chương tiếp theo. |
7 | lazy-initialization mode Một bean khởi tạo lười biếng yêu cầu vùng chứa IoC tạo một cá thể bean khi nó được yêu cầu lần đầu, thay vì khi khởi động. |
số 8 | initialization method Một lệnh gọi lại được gọi ngay sau khi tất cả các thuộc tính cần thiết trên bean đã được thiết lập bởi vùng chứa. Nó sẽ được thảo luận trong chương vòng đời của đậu. |
9 | destruction method Một lệnh gọi lại sẽ được sử dụng khi vùng chứa chứa bean bị phá hủy. Nó sẽ được thảo luận trong chương vòng đời của đậu. |
Siêu dữ liệu cấu hình mùa xuân
Vùng chứa Spring IoC hoàn toàn được tách biệt khỏi định dạng mà siêu dữ liệu cấu hình này thực sự được viết. Sau đây là ba phương pháp quan trọng để cung cấp siêu dữ liệu cấu hình cho Spring Container:
- Tệp cấu hình dựa trên XML.
- Cấu hình dựa trên chú thích
- Cấu hình dựa trên Java
Bạn đã thấy cách siêu dữ liệu cấu hình dựa trên XML được cung cấp cho vùng chứa, nhưng chúng ta hãy xem một mẫu tệp cấu hình dựa trên XML khác với các định nghĩa bean khác nhau bao gồm khởi tạo lười biếng, phương thức khởi tạo và phương thức hủy -
<?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">
<!-- A simple bean definition -->
<bean id = "..." class = "...">
<!-- collaborators and configuration for this bean go here -->
</bean>
<!-- A bean definition with lazy init set on -->
<bean id = "..." class = "..." lazy-init = "true">
<!-- collaborators and configuration for this bean go here -->
</bean>
<!-- A bean definition with initialization method -->
<bean id = "..." class = "..." init-method = "...">
<!-- collaborators and configuration for this bean go here -->
</bean>
<!-- A bean definition with destruction method -->
<bean id = "..." class = "..." destroy-method = "...">
<!-- collaborators and configuration for this bean go here -->
</bean>
<!-- more bean definitions go here -->
</beans>
Bạn có thể kiểm tra Ví dụ Spring Hello World để hiểu cách xác định, cấu hình và tạo Spring Beans.
Chúng ta sẽ thảo luận về Cấu hình Dựa trên Chú thích trong một chương riêng biệt. Nó có chủ ý được thảo luận trong một chương riêng vì chúng tôi muốn bạn nắm bắt một vài khái niệm Spring quan trọng khác, trước khi bạn bắt đầu lập trình với Spring Dependency Injection with Annotations.
Khi xác định một <bean>, bạn có tùy chọn khai báo phạm vi cho bean đó. Ví dụ: để buộc Spring tạo ra một thể hiện bean mới mỗi khi cần một phiên bản, bạn nên khai báo thuộc tính phạm vi của bean làprototype. Tương tự như vậy, nếu bạn muốn Spring trả về cùng một cá thể bean mỗi khi cần, bạn nên khai báo thuộc tính phạm vi của bean làsingleton.
Spring Framework hỗ trợ năm phạm vi sau, ba trong số đó chỉ khả dụng nếu bạn sử dụng ApplicationContext nhận biết web.
Sr.No. | Phạm vi & Mô tả |
---|---|
1 | singleton Điều này mở rộng định nghĩa bean thành một thể hiện duy nhất cho mỗi vùng chứa Spring IoC (mặc định). |
2 | prototype Điều này bao gồm một định nghĩa bean đơn để có bất kỳ số lượng cá thể đối tượng nào. |
3 | request Điều này bao gồm một định nghĩa bean cho một yêu cầu HTTP. Chỉ hợp lệ trong ngữ cảnh của một Spring ApplicationContext nhận biết web. |
4 | session Điều này bao gồm một định nghĩa bean cho một phiên HTTP. Chỉ hợp lệ trong ngữ cảnh của một Spring ApplicationContext nhận biết web. |
5 | global-session Điều này bao gồm một định nghĩa bean cho một phiên HTTP toàn cầu. Chỉ hợp lệ trong ngữ cảnh của một Spring ApplicationContext nhận biết web. |
Trong chương này, chúng ta sẽ thảo luận về hai phạm vi đầu tiên và ba phạm vi còn lại sẽ được thảo luận khi chúng ta thảo luận về Spring ApplicationContext nhận biết web.
Phạm vi singleton
Nếu một phạm vi được đặt thành singleton, vùng chứa Spring IoC sẽ tạo chính xác một thể hiện của đối tượng được xác định bởi định nghĩa bean đó. Cá thể đơn lẻ này được lưu trữ trong bộ đệm ẩn của các hạt đậu đơn như vậy, và tất cả các yêu cầu và tham chiếu tiếp theo cho hạt đậu có tên đó sẽ trả về đối tượng được lưu trong bộ nhớ cache.
Phạm vi mặc định luôn là singleton. Tuy nhiên, khi bạn cần một và chỉ một phiên bản của bean, bạn có thể đặtscope tài sản để singleton trong tệp cấu hình bean, như được hiển thị trong đoạn mã sau:
<!-- A bean definition with singleton scope -->
<bean id = "..." class = "..." scope = "singleton">
<!-- collaborators and configuration for this bean go here -->
</bean>
Thí dụ
Hãy để chúng tôi có một IDE Eclipse hoạt động tại chỗ và thực hiện các bước sau để tạo một ứng dụng Spring -
Các bước | Sự miêu tả |
---|---|
1 | Tạo một dự án với tên SpringExample và tạo một gói com.tutorialspoint trongsrc thư mục trong dự án đã tạo. |
2 | Thêm các thư viện Spring bắt buộc bằng cách sử dụng tùy chọn Thêm JAR bên ngoài như được giải thích trong chương Ví dụ về Spring Hello World . |
3 | Tạo các lớp Java HelloWorld và MainApp trong gói com.tutorialspoint . |
4 | Tạo tệp cấu hình Đậu Beans.xml trongsrc thư mục. |
5 | Bước cuối cùng là tạo nội dung của tất cả các tệp Java và tệp Cấu hình Bean và chạy ứng dụng như được giải thích bên dưới. |
Đây là nội dung của HelloWorld.java tập tin -
package com.tutorialspoint;
public class HelloWorld {
private String message;
public void setMessage(String message){
this.message = message;
}
public void getMessage(){
System.out.println("Your Message : " + message);
}
}
Sau đây là nội dung của MainApp.java tập tin -
package com.tutorialspoint;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MainApp {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");
HelloWorld objA = (HelloWorld) context.getBean("helloWorld");
objA.setMessage("I'm object A");
objA.getMessage();
HelloWorld objB = (HelloWorld) context.getBean("helloWorld");
objB.getMessage();
}
}
Sau đây là tệp cấu hình Beans.xml cần thiết cho phạm vi singleton -
<?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">
<bean id = "helloWorld" class = "com.tutorialspoint.HelloWorld" scope = "singleton">
</bean>
</beans>
Khi bạn đã hoàn tất việc tạo tệp nguồn và tệp cấu hình bean, hãy để chúng tôi chạy ứng dụng. Nếu mọi thứ đều ổn với ứng dụng của bạn, nó sẽ in ra thông báo sau:
Your Message : I'm object A
Your Message : I'm object A
Phạm vi nguyên mẫu
Nếu phạm vi được đặt thành nguyên mẫu, vùng chứa Spring IoC sẽ tạo một thể hiện bean mới của đối tượng mỗi khi yêu cầu cho bean cụ thể đó được thực hiện. Theo quy tắc, hãy sử dụng phạm vi nguyên mẫu cho tất cả các đậu trạng thái đầy đủ và phạm vi singleton cho các hạt không trạng thái.
Để xác định phạm vi nguyên mẫu, bạn có thể đặt scope tài sản để prototype trong tệp cấu hình bean, như được hiển thị trong đoạn mã sau:
<!-- A bean definition with prototype scope -->
<bean id = "..." class = "..." scope = "prototype">
<!-- collaborators and configuration for this bean go here -->
</bean>
Thí dụ
Hãy để chúng tôi có IDE Eclipse đang hoạt động tại chỗ và làm theo các bước sau để tạo một ứng dụng Spring -
Các bước | Sự miêu tả |
---|---|
1 | Tạo một dự án với tên SpringExample và tạo một gói com.tutorialspoint trongsrc thư mục trong dự án đã tạo. |
2 | Thêm các thư viện Spring bắt buộc bằng cách sử dụng tùy chọn Thêm JAR bên ngoài như được giải thích trong chương Ví dụ về Spring Hello World . |
3 | Tạo các lớp Java HelloWorld và MainApp trong gói com.tutorialspoint . |
4 | Tạo tệp cấu hình Đậu Beans.xml trongsrc thư mục. |
5 | Bước cuối cùng là tạo nội dung của tất cả các tệp Java và tệp Cấu hình Bean và chạy ứng dụng như được giải thích bên dưới. |
Đây là nội dung của HelloWorld.java tập tin
package com.tutorialspoint;
public class HelloWorld {
private String message;
public void setMessage(String message){
this.message = message;
}
public void getMessage(){
System.out.println("Your Message : " + message);
}
}
Sau đây là nội dung của MainApp.java tập tin -
package com.tutorialspoint;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MainApp {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");
HelloWorld objA = (HelloWorld) context.getBean("helloWorld");
objA.setMessage("I'm object A");
objA.getMessage();
HelloWorld objB = (HelloWorld) context.getBean("helloWorld");
objB.getMessage();
}
}
Sau đây là tệp cấu hình Beans.xml cần thiết cho phạm vi nguyên mẫu -
<?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">
<bean id = "helloWorld" class = "com.tutorialspoint.HelloWorld" scope = "prototype">
</bean>
</beans>
Khi bạn đã hoàn tất việc tạo tệp nguồn và tệp cấu hình bean, hãy để chúng tôi chạy ứng dụng. Nếu mọi thứ đều ổn với ứng dụng của bạn, nó sẽ in ra thông báo sau:
Your Message : I'm object A
Your Message : null
Vòng đời của Spring bean rất dễ hiểu. Khi một bean được khởi tạo, nó có thể được yêu cầu thực hiện một số khởi tạo để đưa nó vào trạng thái có thể sử dụng được. Tương tự, khi đậu không còn cần thiết và được lấy ra khỏi thùng chứa, có thể cần phải dọn dẹp một chút.
Mặc dù vậy, có danh sách các hoạt động diễn ra đằng sau hậu trường giữa thời điểm bean Instantiation và sự phá hủy của nó, chương này sẽ chỉ thảo luận về hai phương pháp gọi lại vòng đời bean quan trọng, được yêu cầu tại thời điểm khởi tạo bean và sự phá hủy của nó.
Để xác định thiết lập và chia nhỏ cho một bean, chúng ta chỉ cần khai báo <bean> với initmethod và / hoặc destroy-methodthông số. Thuộc tính init-method chỉ định một phương thức sẽ được gọi trên bean ngay sau khi khởi tạo. Tương tự, Destmethod chỉ định một phương thức được gọi ngay trước khi một bean bị xóa khỏi vùng chứa.
Gọi lại khởi tạo
Giao diện org.springframework.beans.factory.InitializingBean chỉ định một phương thức duy nhất:
void afterPropertiesSet() throws Exception;
Do đó, bạn có thể thực hiện giao diện trên một cách đơn giản và công việc khởi tạo có thể được thực hiện bên trong phương thức afterPropertiesSet () như sau:
public class ExampleBean implements InitializingBean {
public void afterPropertiesSet() {
// do some initialization work
}
}
Trong trường hợp siêu dữ liệu cấu hình dựa trên XML, bạn có thể sử dụng init-methodđể xác định tên của phương thức có chữ ký void no-đối số. Ví dụ -
<bean id = "exampleBean" class = "examples.ExampleBean" init-method = "init"/>
Sau đây là định nghĩa lớp -
public class ExampleBean {
public void init() {
// do some initialization work
}
}
Lệnh gọi lại hủy
Các org.springframework.beans.factory.DisposableBean giao diện xác định một phương pháp duy nhất -
void destroy() throws Exception;
Vì vậy, bạn có thể thực hiện đơn giản giao diện trên và công việc hoàn thiện có thể được thực hiện bên trong phương thức hủy () như sau:
public class ExampleBean implements DisposableBean {
public void destroy() {
// do some destruction work
}
}
Trong trường hợp siêu dữ liệu cấu hình dựa trên XML, bạn có thể sử dụng destroy-methodđể xác định tên của phương thức có chữ ký void no-đối số. Ví dụ -
<bean id = "exampleBean" class = "examples.ExampleBean" destroy-method = "destroy"/>
Sau đây là định nghĩa lớp -
public class ExampleBean {
public void destroy() {
// do some destruction work
}
}
Nếu bạn đang sử dụng vùng chứa IoC của Spring trong môi trường ứng dụng không phải web; ví dụ: trong môi trường máy tính để bàn ứng dụng khách phong phú, bạn đăng ký một hook tắt với JVM. Làm như vậy đảm bảo việc tắt một cách duyên dáng và gọi các phương thức hủy có liên quan trên các hạt đậu đơn của bạn để tất cả tài nguyên được giải phóng.
Bạn không nên sử dụng lệnh gọi lại InitializingBean hoặc DisposableBean, bởi vì cấu hình XML mang lại nhiều tính linh hoạt trong việc đặt tên cho phương thức của bạn.
Thí dụ
Hãy để chúng tôi có một IDE Eclipse hoạt động tại chỗ và thực hiện các bước sau để tạo một ứng dụng Spring -
Các bước | Sự miêu tả |
---|---|
1 | Tạo một dự án với tên SpringExample và tạo một gói com.tutorialspoint trongsrc thư mục trong dự án đã tạo. |
2 | Thêm các thư viện Spring bắt buộc bằng cách sử dụng tùy chọn Thêm JAR bên ngoài như được giải thích trong chương Ví dụ về Spring Hello World . |
3 | Tạo các lớp Java HelloWorld và MainApp trong gói com.tutorialspoint . |
4 | Tạo tệp cấu hình Đậu Beans.xml trongsrc thư mục. |
5 | Bước cuối cùng là tạo nội dung của tất cả các tệp Java và tệp Cấu hình Bean và chạy ứng dụng như được giải thích bên dưới. |
Đây là nội dung của HelloWorld.java tập tin -
package com.tutorialspoint;
public class HelloWorld {
private String message;
public void setMessage(String message){
this.message = message;
}
public void getMessage(){
System.out.println("Your Message : " + message);
}
public void init(){
System.out.println("Bean is going through init.");
}
public void destroy() {
System.out.println("Bean will destroy now.");
}
}
Sau đây là nội dung của MainApp.javatập tin. Ở đây bạn cần đăng ký một hook tắt máyregisterShutdownHook()phương thức được khai báo trên lớp AbstractApplicationContext. Điều này sẽ đảm bảo tắt máy một cách duyên dáng và gọi các phương thức hủy có liên quan.
package com.tutorialspoint;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MainApp {
public static void main(String[] args) {
AbstractApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");
HelloWorld obj = (HelloWorld) context.getBean("helloWorld");
obj.getMessage();
context.registerShutdownHook();
}
}
Sau đây là tệp cấu hình Beans.xml cần thiết cho các phương thức init và hủy -
<?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">
<bean id = "helloWorld" class = "com.tutorialspoint.HelloWorld" init-method = "init"
destroy-method = "destroy">
<property name = "message" value = "Hello World!"/>
</bean>
</beans>
Khi bạn đã hoàn tất việc tạo tệp nguồn và tệp cấu hình bean, hãy để chúng tôi chạy ứng dụng. Nếu mọi thứ đều ổn với ứng dụng của bạn, nó sẽ in ra thông báo sau:
Bean is going through init.
Your Message : Hello World!
Bean will destroy now.
Phương thức khởi tạo và hủy mặc định
Nếu bạn có quá nhiều bean có các phương thức khởi tạo và / hoặc hủy có cùng tên, bạn không cần khai báo init-method và destroy-methodtrên từng hạt đậu. Thay vào đó, khuôn khổ cung cấp sự linh hoạt để định cấu hình tình huống như vậy bằng cách sử dụngdefault-init-method và default-destroy-method các thuộc tính trên phần tử <beans> như sau:
<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"
default-init-method = "init"
default-destroy-method = "destroy">
<bean id = "..." class = "...">
<!-- collaborators and configuration for this bean go here -->
</bean>
</beans>
Các BeanPostProcessor interface xác định các phương thức gọi lại mà bạn có thể triển khai để cung cấp logic khởi tạo của riêng bạn, logic phân giải phụ thuộc, v.v. Bạn cũng có thể triển khai một số logic tùy chỉnh sau khi vùng chứa Spring hoàn thành việc khởi tạo, cấu hình và khởi tạo bean bằng cách cắm một hoặc nhiều triển khai BeanPostProcessor .
Bạn có thể định cấu hình nhiều giao diện BeanPostProcessor và bạn có thể kiểm soát thứ tự mà các giao diện BeanPostProcessor này thực thi bằng cách đặt order thuộc tính miễn là BeanPostProcessor triển khai Ordered giao diện.
BeanPostProcessor hoạt động trên các cá thể bean (hoặc đối tượng), có nghĩa là vùng chứa Spring IoC khởi tạo một cá thể bean và sau đó các giao diện BeanPostProcessor thực hiện công việc của chúng.
An ApplicationContext tự động phát hiện bất kỳ hạt đậu nào được xác định với việc triển khai BeanPostProcessor giao diện và đăng ký các bean này dưới dạng bộ xử lý hậu kỳ, sau đó được vùng chứa gọi một cách thích hợp khi tạo bean.
Thí dụ
Các ví dụ sau đây cho thấy cách viết, đăng ký và sử dụng BeanPostProcessors trong ngữ cảnh của ApplicationContext.
Hãy để chúng tôi có một IDE Eclipse hoạt động tại chỗ và thực hiện các bước sau để tạo một ứng dụng Spring -
Các bước | Sự miêu tả |
---|---|
1 | Tạo một dự án với tên SpringExample và tạo một gói com.tutorialspoint trongsrc thư mục trong dự án đã tạo. |
2 | Thêm các thư viện Spring bắt buộc bằng cách sử dụng tùy chọn Thêm JAR bên ngoài như được giải thích trong chương Ví dụ về Spring Hello World . |
3 | Tạo các lớp Java HelloWorld , InitHelloWorld và MainApp trong gói com.tutorialspoint . |
4 | Tạo tệp cấu hình Đậu Beans.xml trongsrc thư mục. |
5 | Bước cuối cùng là tạo nội dung của tất cả các tệp Java và tệp Cấu hình Bean và chạy ứng dụng như được giải thích bên dưới. |
Đây là nội dung của HelloWorld.java tập tin -
package com.tutorialspoint;
public class HelloWorld {
private String message;
public void setMessage(String message){
this.message = message;
}
public void getMessage(){
System.out.println("Your Message : " + message);
}
public void init(){
System.out.println("Bean is going through init.");
}
public void destroy(){
System.out.println("Bean will destroy now.");
}
}
Đây là một ví dụ rất cơ bản về việc triển khai BeanPostProcessor, nó in ra một tên bean trước và sau khi khởi tạo bất kỳ bean nào. Bạn có thể triển khai logic phức tạp hơn trước và sau khi intializing một bean vì bạn có quyền truy cập vào đối tượng bean bên trong cả hai phương thức post processor.
Đây là nội dung của InitHelloWorld.java tập tin -
package com.tutorialspoint;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.beans.BeansException;
public class InitHelloWorld implements BeanPostProcessor {
public Object postProcessBeforeInitialization(Object bean, String beanName)
throws BeansException {
System.out.println("BeforeInitialization : " + beanName);
return bean; // you can return any other object as well
}
public Object postProcessAfterInitialization(Object bean, String beanName)
throws BeansException {
System.out.println("AfterInitialization : " + beanName);
return bean; // you can return any other object as well
}
}
Sau đây là nội dung của MainApp.javatập tin. Ở đây bạn cần đăng ký một hook tắt máyregisterShutdownHook()phương thức được khai báo trên lớp AbstractApplicationContext. Điều này sẽ đảm bảo việc tắt một cách duyên dáng và gọi các phương thức hủy có liên quan.
package com.tutorialspoint;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MainApp {
public static void main(String[] args) {
AbstractApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");
HelloWorld obj = (HelloWorld) context.getBean("helloWorld");
obj.getMessage();
context.registerShutdownHook();
}
}
Sau đây là tệp cấu hình Beans.xml cần thiết cho các phương thức init và hủy -
<?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">
<bean id = "helloWorld" class = "com.tutorialspoint.HelloWorld"
init-method = "init" destroy-method = "destroy">
<property name = "message" value = "Hello World!"/>
</bean>
<bean class = "com.tutorialspoint.InitHelloWorld" />
</beans>
Khi bạn đã hoàn tất việc tạo tệp nguồn và tệp cấu hình bean, hãy để chúng tôi chạy ứng dụng. Nếu mọi thứ đều ổn với ứng dụng của bạn, nó sẽ in ra thông báo sau:
BeforeInitialization : helloWorld
Bean is going through init.
AfterInitialization : helloWorld
Your Message : Hello World!
Bean will destroy now.
Định nghĩa bean có thể chứa rất nhiều thông tin cấu hình, bao gồm các đối số của phương thức khởi tạo, giá trị thuộc tính và thông tin về vùng chứa cụ thể như phương thức khởi tạo, tên phương thức nhà máy tĩnh, v.v.
Định nghĩa bean con kế thừa dữ liệu cấu hình từ định nghĩa cha. Định nghĩa con có thể ghi đè một số giá trị hoặc thêm các giá trị khác nếu cần.
Kế thừa định nghĩa Spring Bean không liên quan gì đến kế thừa lớp Java nhưng khái niệm kế thừa thì giống nhau. Bạn có thể xác định một định nghĩa bean mẹ như một khuôn mẫu và các bean con khác có thể kế thừa cấu hình bắt buộc từ bean mẹ.
Khi bạn sử dụng siêu dữ liệu cấu hình dựa trên XML, bạn chỉ ra định nghĩa bean con bằng cách sử dụng parent , chỉ định bean cha làm giá trị của thuộc tính này.
Thí dụ
Hãy để chúng tôi có một IDE Eclipse hoạt động tại chỗ và thực hiện các bước sau để tạo một ứng dụng Spring -
Các bước | Sự miêu tả |
---|---|
1 | Tạo một dự án với tên SpringExample và tạo một gói com.tutorialspoint trongsrc thư mục trong dự án đã tạo. |
2 | Thêm các thư viện Spring bắt buộc bằng cách sử dụng tùy chọn Thêm JAR bên ngoài như được giải thích trong chương Ví dụ về Spring Hello World . |
3 | Tạo các lớp Java HelloWorld , HelloIndia và MainApp trong gói com.tutorialspoint . |
4 | Tạo tệp cấu hình Đậu Beans.xml trongsrc thư mục. |
5 | Bước cuối cùng là tạo nội dung của tất cả các tệp Java và tệp Cấu hình Bean và chạy ứng dụng như được giải thích bên dưới. |
Sau đây là tệp cấu hình Beans.xmltrong đó chúng tôi đã xác định bean "helloWorld" có hai thuộc tính message1 và message2 . Đậu "helloIndia" tiếp theo đã được xác định là con của bean "helloWorld" bằng cách sử dụngparentthuộc tính. Các kế thừa đậu con message2 tài sản như nguyên trạng và ghi đè message1 bất động sản và giới thiệu thêm một tài sản message3 .
<?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">
<bean id = "helloWorld" class = "com.tutorialspoint.HelloWorld">
<property name = "message1" value = "Hello World!"/>
<property name = "message2" value = "Hello Second World!"/>
</bean>
<bean id ="helloIndia" class = "com.tutorialspoint.HelloIndia" parent = "helloWorld">
<property name = "message1" value = "Hello India!"/>
<property name = "message3" value = "Namaste India!"/>
</bean>
</beans>
Đây là nội dung của HelloWorld.java tập tin -
package com.tutorialspoint;
public class HelloWorld {
private String message1;
private String message2;
public void setMessage1(String message){
this.message1 = message;
}
public void setMessage2(String message){
this.message2 = message;
}
public void getMessage1(){
System.out.println("World Message1 : " + message1);
}
public void getMessage2(){
System.out.println("World Message2 : " + message2);
}
}
Đây là nội dung của HelloIndia.java tập tin -
package com.tutorialspoint;
public class HelloIndia {
private String message1;
private String message2;
private String message3;
public void setMessage1(String message){
this.message1 = message;
}
public void setMessage2(String message){
this.message2 = message;
}
public void setMessage3(String message){
this.message3 = message;
}
public void getMessage1(){
System.out.println("India Message1 : " + message1);
}
public void getMessage2(){
System.out.println("India Message2 : " + message2);
}
public void getMessage3(){
System.out.println("India Message3 : " + message3);
}
}
Sau đây là nội dung của MainApp.java tập tin -
package com.tutorialspoint;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MainApp {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");
HelloWorld objA = (HelloWorld) context.getBean("helloWorld");
objA.getMessage1();
objA.getMessage2();
HelloIndia objB = (HelloIndia) context.getBean("helloIndia");
objB.getMessage1();
objB.getMessage2();
objB.getMessage3();
}
}
Khi bạn đã hoàn tất việc tạo tệp nguồn và tệp cấu hình bean, hãy để chúng tôi chạy ứng dụng. Nếu mọi thứ đều ổn với ứng dụng của bạn, nó sẽ in ra thông báo sau:
World Message1 : Hello World!
World Message2 : Hello Second World!
India Message1 : Hello India!
India Message2 : Hello Second World!
India Message3 : Namaste India!
Nếu bạn quan sát ở đây, chúng tôi đã không chuyển message2 khi tạo bean "helloIndia", nhưng nó đã được thông qua do Kế thừa Định nghĩa Bean.
Mẫu định nghĩa Bean
Bạn có thể tạo một mẫu định nghĩa Bean, có thể được sử dụng bởi các định nghĩa bean con khác mà không cần tốn nhiều công sức. Trong khi xác định Mẫu Định nghĩa Bean, bạn không nên chỉ địnhclass thuộc tính và nên chỉ định abstract và nên chỉ định thuộc tính trừu tượng có giá trị là true như được hiển thị trong đoạn mã sau -
<?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">
<bean id = "beanTeamplate" abstract = "true">
<property name = "message1" value = "Hello World!"/>
<property name = "message2" value = "Hello Second World!"/>
<property name = "message3" value = "Namaste India!"/>
</bean>
<bean id = "helloIndia" class = "com.tutorialspoint.HelloIndia" parent = "beanTeamplate">
<property name = "message1" value = "Hello India!"/>
<property name = "message3" value = "Namaste India!"/>
</bean>
</beans>
Không thể khởi tạo bean mẹ một mình vì nó chưa hoàn chỉnh và nó cũng được đánh dấu rõ ràng là trừu tượng . Khi một định nghĩa trừu tượng như thế này, nó chỉ có thể được sử dụng như một định nghĩa bean mẫu thuần túy dùng làm định nghĩa cha cho các định nghĩa con.
Mỗi ứng dụng dựa trên Java đều có một vài đối tượng hoạt động cùng nhau để trình bày những gì người dùng cuối coi là một ứng dụng đang hoạt động. Khi viết một ứng dụng Java phức tạp, các lớp ứng dụng phải độc lập nhất có thể với các lớp Java khác để tăng khả năng sử dụng lại các lớp này và kiểm tra chúng độc lập với các lớp khác trong khi kiểm thử đơn vị. Dependency Injection (hay đôi khi được gọi là nối dây) giúp dán các lớp này lại với nhau và đồng thời giữ chúng độc lập.
Hãy xem xét bạn có một ứng dụng có thành phần soạn thảo văn bản và bạn muốn cung cấp tính năng kiểm tra chính tả. Mã chuẩn của bạn sẽ trông giống như thế này -
public class TextEditor {
private SpellChecker spellChecker;
public TextEditor() {
spellChecker = new SpellChecker();
}
}
Những gì chúng tôi đã làm ở đây là tạo sự phụ thuộc giữa TextEditor và SpellChecker. Trong một kịch bản điều khiển đảo ngược, thay vào đó chúng tôi sẽ làm điều gì đó như thế này -
public class TextEditor {
private SpellChecker spellChecker;
public TextEditor(SpellChecker spellChecker) {
this.spellChecker = spellChecker;
}
}
Ở đây, TextEditor không nên lo lắng về việc triển khai SpellChecker. SpellChecker sẽ được triển khai độc lập và sẽ được cung cấp cho TextEditor tại thời điểm khởi tạo TextEditor. Toàn bộ quy trình này được kiểm soát bởi Spring Framework.
Ở đây, chúng tôi đã xóa toàn bộ quyền kiểm soát khỏi TextEditor và giữ nó ở một nơi khác (tức là tệp cấu hình XML) và phần phụ thuộc (tức là lớp SpellChecker) đang được đưa vào lớp TextEditor thông qua một Class Constructor. Do đó, luồng kiểm soát đã bị "đảo ngược" bởi Dependency Injection (DI) vì bạn đã ủy quyền một cách hiệu quả các phụ thuộc cho một số hệ thống bên ngoài.
Phương pháp tiêm phụ thuộc thứ hai là thông qua Setter Methodscủa lớp TextEditor nơi chúng ta sẽ tạo một phiên bản SpellChecker. Thể hiện này sẽ được sử dụng để gọi các phương thức setter để khởi tạo các thuộc tính của TextEditor.
Do đó, DI tồn tại trong hai biến thể chính và hai chương phụ sau đây sẽ bao gồm cả hai biến thể với các ví dụ:
Sr.No. | Mô tả & Loại tiêm phụ thuộc |
---|---|
1 | Chèn phụ thuộc dựa trên cấu trúc DI dựa trên phương thức xây dựng được thực hiện khi vùng chứa gọi một phương thức khởi tạo lớp với một số đối số, mỗi đối số đại diện cho một sự phụ thuộc vào lớp kia. |
2 | Tiêm phụ thuộc dựa trên setter DI dựa trên setter được thực hiện bởi vùng chứa gọi các phương thức setter trên bean của bạn sau khi gọi một phương thức khởi tạo không đối số hoặc phương thức nhà máy tĩnh không đối số để khởi tạo bean của bạn. |
Bạn có thể kết hợp cả hai, DI dựa trên Constructor và dựa trên Setter nhưng nguyên tắc chung là sử dụng các đối số của constructor cho các phụ thuộc bắt buộc và setter cho các phụ thuộc tùy chọn.
Mã rõ ràng hơn với nguyên tắc DI và việc tách sẽ hiệu quả hơn khi các đối tượng được cung cấp các phụ thuộc của chúng. Đối tượng không tra cứu các phụ thuộc của nó và không biết vị trí hoặc lớp của các phụ thuộc, thay vào đó mọi thứ đều do Spring Framework đảm nhận.
Như bạn đã biết, các lớp bên trong Java được định nghĩa trong phạm vi của các lớp khác, tương tự, inner beanslà các loại đậu được xác định trong phạm vi của một loại đậu khác. Do đó, một phần tử <bean /> bên trong các phần tử <property /> hoặc <constructor-arg /> được gọi là bên trong bean và nó được hiển thị bên dưới.
<?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">
<bean id = "outerBean" class = "...">
<property name = "target">
<bean id = "innerBean" class = "..."/>
</property>
</bean>
</beans>
Thí dụ
Hãy để chúng tôi có IDE Eclipse đang hoạt động tại chỗ và làm theo các bước sau để tạo một ứng dụng Spring -
Các bước | Sự miêu tả |
---|---|
1 | Tạo một dự án với tên SpringExample và tạo một gói com.tutorialspoint trongsrc thư mục trong dự án đã tạo. |
2 | Thêm các thư viện Spring bắt buộc bằng cách sử dụng tùy chọn Thêm JAR bên ngoài như được giải thích trong chương Ví dụ về Spring Hello World . |
3 | Tạo các lớp Java TextEditor , SpellChecker và MainApp trong gói com.tutorialspoint . |
4 | Tạo tệp cấu hình Đậu Beans.xml trongsrc thư mục. |
5 | Bước cuối cùng là tạo nội dung của tất cả các tệp Java và tệp Cấu hình Bean và chạy ứng dụng như được giải thích bên dưới. |
Đây là nội dung của TextEditor.java tập tin -
package com.tutorialspoint;
public class TextEditor {
private SpellChecker spellChecker;
// a setter method to inject the dependency.
public void setSpellChecker(SpellChecker spellChecker) {
System.out.println("Inside setSpellChecker." );
this.spellChecker = spellChecker;
}
// a getter method to return spellChecker
public SpellChecker getSpellChecker() {
return spellChecker;
}
public void spellCheck() {
spellChecker.checkSpelling();
}
}
Sau đây là nội dung của một tệp lớp phụ thuộc khác SpellChecker.java -
package com.tutorialspoint;
public class SpellChecker {
public SpellChecker(){
System.out.println("Inside SpellChecker constructor." );
}
public void checkSpelling(){
System.out.println("Inside checkSpelling." );
}
}
Sau đây là nội dung của MainApp.java tập tin -
package com.tutorialspoint;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MainApp {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");
TextEditor te = (TextEditor) context.getBean("textEditor");
te.spellCheck();
}
}
Sau đây là tệp cấu hình Beans.xml có cấu hình cho tiêm dựa trên setter nhưng sử dụng inner beans -
<?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">
<!-- Definition for textEditor bean using inner bean -->
<bean id = "textEditor" class = "com.tutorialspoint.TextEditor">
<property name = "spellChecker">
<bean id = "spellChecker" class = "com.tutorialspoint.SpellChecker"/>
</property>
</bean>
</beans>
Khi bạn đã hoàn tất việc tạo tệp nguồn và tệp cấu hình bean, hãy để chúng tôi chạy ứng dụng. Nếu mọi thứ đều ổn với ứng dụng của bạn, nó sẽ in ra thông báo sau:
Inside SpellChecker constructor.
Inside setSpellChecker.
Inside checkSpelling.
Bạn đã thấy cách định cấu hình kiểu dữ liệu nguyên thủy bằng cách sử dụng value tham chiếu thuộc tính và đối tượng bằng cách sử dụng refthuộc tính của thẻ <property> trong tệp cấu hình Bean của bạn. Cả hai trường hợp đều xử lý việc chuyển giá trị số ít cho bean.
Bây giờ điều gì sẽ xảy ra nếu bạn muốn truyền các giá trị số nhiều như kiểu Bộ sưu tập Java như Danh sách, Tập hợp, Bản đồ và Thuộc tính. Để xử lý tình huống này, Spring cung cấp bốn loại phần tử cấu hình bộ sưu tập như sau:
Sr.No | Yếu tố & Mô tả |
---|---|
1 | <list> Điều này giúp ích trong việc nối dây, tức là đưa vào danh sách các giá trị, cho phép các bản sao. |
2 | <set> Điều này giúp nối dây một bộ giá trị nhưng không có bất kỳ bản sao nào. |
3 | <map> Điều này có thể được sử dụng để đưa vào một tập hợp các cặp tên-giá trị trong đó tên và giá trị có thể thuộc bất kỳ loại nào. |
4 | <props> Điều này có thể được sử dụng để đưa vào một bộ sưu tập các cặp tên-giá trị trong đó tên và giá trị đều là Chuỗi. |
Bạn có thể sử dụng <list> hoặc <set> để kết nối bất kỳ triển khai nào của java.util.Collection hoặc array.
Bạn sẽ gặp hai tình huống (a) Truyền các giá trị trực tiếp của tập hợp và (b) Truyền một tham chiếu của bean làm một trong các phần tử của tập hợp.
Thí dụ
Hãy để chúng tôi có một IDE Eclipse hoạt động tại chỗ và thực hiện các bước sau để tạo một ứng dụng Spring -
Các bước | Sự miêu tả |
---|---|
1 | Tạo một dự án với tên SpringExample và tạo một gói com.tutorialspoint trongsrc thư mục trong dự án đã tạo. |
2 | Thêm các thư viện Spring bắt buộc bằng cách sử dụng tùy chọn Thêm JAR bên ngoài như được giải thích trong chương Ví dụ về Spring Hello World . |
3 | Tạo các lớp Java JavaCollection và MainApp trong gói com.tutorialspoint . |
4 | Tạo tệp cấu hình Đậu Beans.xml trongsrc thư mục. |
5 | Bước cuối cùng là tạo nội dung của tất cả các tệp Java và tệp Cấu hình Bean và chạy ứng dụng như được giải thích bên dưới. |
Đây là nội dung của JavaCollection.java tập tin -
package com.tutorialspoint;
import java.util.*;
public class JavaCollection {
List addressList;
Set addressSet;
Map addressMap;
Properties addressProp;
// a setter method to set List
public void setAddressList(List addressList) {
this.addressList = addressList;
}
// prints and returns all the elements of the list.
public List getAddressList() {
System.out.println("List Elements :" + addressList);
return addressList;
}
// a setter method to set Set
public void setAddressSet(Set addressSet) {
this.addressSet = addressSet;
}
// prints and returns all the elements of the Set.
public Set getAddressSet() {
System.out.println("Set Elements :" + addressSet);
return addressSet;
}
// a setter method to set Map
public void setAddressMap(Map addressMap) {
this.addressMap = addressMap;
}
// prints and returns all the elements of the Map.
public Map getAddressMap() {
System.out.println("Map Elements :" + addressMap);
return addressMap;
}
// a setter method to set Property
public void setAddressProp(Properties addressProp) {
this.addressProp = addressProp;
}
// prints and returns all the elements of the Property.
public Properties getAddressProp() {
System.out.println("Property Elements :" + addressProp);
return addressProp;
}
}
Sau đây là nội dung của MainApp.java tập tin -
package com.tutorialspoint;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MainApp {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");
JavaCollection jc=(JavaCollection)context.getBean("javaCollection");
jc.getAddressList();
jc.getAddressSet();
jc.getAddressMap();
jc.getAddressProp();
}
}
Sau đây là tệp cấu hình Beans.xml có cấu hình cho tất cả các loại bộ sưu tập -
<?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">
<!-- Definition for javaCollection -->
<bean id = "javaCollection" class = "com.tutorialspoint.JavaCollection">
<!-- results in a setAddressList(java.util.List) call -->
<property name = "addressList">
<list>
<value>INDIA</value>
<value>Pakistan</value>
<value>USA</value>
<value>USA</value>
</list>
</property>
<!-- results in a setAddressSet(java.util.Set) call -->
<property name = "addressSet">
<set>
<value>INDIA</value>
<value>Pakistan</value>
<value>USA</value>
<value>USA</value>
</set>
</property>
<!-- results in a setAddressMap(java.util.Map) call -->
<property name = "addressMap">
<map>
<entry key = "1" value = "INDIA"/>
<entry key = "2" value = "Pakistan"/>
<entry key = "3" value = "USA"/>
<entry key = "4" value = "USA"/>
</map>
</property>
<!-- results in a setAddressProp(java.util.Properties) call -->
<property name = "addressProp">
<props>
<prop key = "one">INDIA</prop>
<prop key = "one">INDIA</prop>
<prop key = "two">Pakistan</prop>
<prop key = "three">USA</prop>
<prop key = "four">USA</prop>
</props>
</property>
</bean>
</beans>
Khi bạn đã hoàn tất việc tạo tệp nguồn và tệp cấu hình bean, hãy để chúng tôi chạy ứng dụng. Nếu mọi thứ đều ổn với ứng dụng của bạn, nó sẽ in ra thông báo sau:
List Elements :[INDIA, Pakistan, USA, USA]
Set Elements :[INDIA, Pakistan, USA]
ap Elements :{1 = INDIA, 2 = Pakistan, 3 = USA, 4 = USA}
Property Elements :{two = Pakistan, one = INDIA, three = USA, four = USA}
Tham khảo về việc tiêm đậu
Định nghĩa Bean sau đây sẽ giúp bạn hiểu cách đưa các tham chiếu bean làm một trong những phần tử của bộ sưu tập. Thậm chí, bạn có thể kết hợp tất cả các tham chiếu và giá trị với nhau như được hiển thị trong đoạn mã sau -
<?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">
<!-- Bean Definition to handle references and values -->
<bean id = "..." class = "...">
<!-- Passing bean reference for java.util.List -->
<property name = "addressList">
<list>
<ref bean = "address1"/>
<ref bean = "address2"/>
<value>Pakistan</value>
</list>
</property>
<!-- Passing bean reference for java.util.Set -->
<property name = "addressSet">
<set>
<ref bean = "address1"/>
<ref bean = "address2"/>
<value>Pakistan</value>
</set>
</property>
<!-- Passing bean reference for java.util.Map -->
<property name = "addressMap">
<map>
<entry key = "one" value = "INDIA"/>
<entry key = "two" value-ref = "address1"/>
<entry key = "three" value-ref = "address2"/>
</map>
</property>
</bean>
</beans>
Để sử dụng định nghĩa bean ở trên, bạn cần xác định các phương thức setter của mình theo cách mà chúng cũng có thể xử lý các tham chiếu.
Tiêm các giá trị chuỗi rỗng và rỗng
Nếu bạn cần chuyển một chuỗi trống làm giá trị, thì bạn có thể chuyển nó như sau:
<bean id = "..." class = "exampleBean">
<property name = "email" value = ""/>
</bean>
Ví dụ trước tương đương với mã Java: exampleBean.setEmail ("")
Nếu bạn cần chuyển một giá trị NULL, thì bạn có thể chuyển nó như sau:
<bean id = "..." class = "exampleBean">
<property name = "email"><null/></property>
</bean>
Ví dụ trước tương đương với mã Java: exampleBean.setEmail (null)
Bạn đã học cách khai báo bean bằng cách sử dụng phần tử <bean> và chèn <bean> bằng cách sử dụng các phần tử <constructor-arg> và <property> trong tệp cấu hình XML.
Hộp đựng Spring có thể autowire mối quan hệ giữa các bean cộng tác mà không sử dụng các phần tử <constructor-arg> và <property>, giúp cắt giảm lượng cấu hình XML mà bạn viết cho một ứng dụng lớn dựa trên Spring.
Chế độ tự động
Sau đây là các chế độ tự động phân bổ, có thể được sử dụng để hướng dẫn vùng chứa Spring sử dụng tính năng tự động phân bổ để chèn phụ thuộc. Bạn sử dụng thuộc tính autowire của phần tử <bean /> để chỉ địnhautowire chế độ cho một định nghĩa bean.
Sr.No | Chế độ & Mô tả |
---|---|
1 | no Đây là cài đặt mặc định có nghĩa là không có tự động kết nối và bạn nên sử dụng tham chiếu bean rõ ràng để nối dây. Bạn không có gì để làm đặc biệt cho hệ thống dây điện này. Đây là những gì bạn đã thấy trong chương Dependency Injection. |
2 | bằng tên Autowiring theo tên thuộc tính. Spring container xem xét các thuộc tính của bean mà thuộc tính autowire được đặt thành byName trong tệp cấu hình XML. Sau đó, nó cố gắng khớp và nối các thuộc tính của nó với các bean được xác định bởi cùng tên trong tệp cấu hình. |
3 | theo loại Tự động tạo theo kiểu dữ liệu thuộc tính. Spring container xem xét các thuộc tính của bean mà thuộc tính autowire được đặt thành byType trong tệp cấu hình XML. Sau đó, nó cố gắng khớp và nối một thuộc tính nếutypekhớp với chính xác một trong các tên bean trong tệp cấu hình. Nếu có nhiều hơn một hạt đậu như vậy, một ngoại lệ chết người sẽ bị loại bỏ. |
4 | constructor Similar to byType, but type applies to constructor arguments. If there is not exactly one bean of the constructor argument type in the container, a fatal error is raised. |
5 | autodetect Spring first tries to wire using autowire by constructor, if it does not work, Spring tries to autowire by byType. |
You can use byType or constructor autowiring mode to wire arrays and other typed-collections.
Limitations with autowiring
Autowiring works best when it is used consistently across a project. If autowiring is not used in general, it might be confusing for developers to use it to wire only one or two bean definitions. Though, autowiring can significantly reduce the need to specify properties or constructor arguments but you should consider the limitations and disadvantages of autowiring before using them.
Sr.No. | Limitations & Description |
---|---|
1 | Overriding possibility You can still specify dependencies using <constructor-arg> and <property> settings which will always override autowiring. |
2 | Primitive data types You cannot autowire so-called simple properties such as primitives, Strings, and Classes. |
3 | Confusing nature Autowiring is less exact than explicit wiring, so if possible prefer using explict wiring. |
Starting from Spring 2.5 it became possible to configure the dependency injection using annotations. So instead of using XML to describe a bean wiring, you can move the bean configuration into the component class itself by using annotations on the relevant class, method, or field declaration.
Annotation injection is performed before XML injection. Thus, the latter configuration will override the former for properties wired through both approaches.
Annotation wiring is not turned on in the Spring container by default. So, before we can use annotation-based wiring, we will need to enable it in our Spring configuration file. So consider the following configuration file in case you want to use any annotation in your Spring application.
<?xml version = "1.0" encoding = "UTF-8"?>
<beans xmlns = "http://www.springframework.org/schema/beans"
xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
xmlns:context = "http://www.springframework.org/schema/context"
xsi:schemaLocation = "http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<context:annotation-config/>
<!-- bean definitions go here -->
</beans>
Once <context:annotation-config/> is configured, you can start annotating your code to indicate that Spring should automatically wire values into properties, methods, and constructors. Let us look at a few important annotations to understand how they work −
Sr.No. | Annotation & Description |
---|---|
1 | @Required The @Required annotation applies to bean property setter methods. |
2 | @Autowired The @Autowired annotation can apply to bean property setter methods, non-setter methods, constructor and properties. |
3 | @Qualifier The @Qualifier annotation along with @Autowired can be used to remove the confusion by specifiying which exact bean will be wired. |
4 | JSR-250 Annotations Spring supports JSR-250 based annotations which include @Resource, @PostConstruct and @PreDestroy annotations. |
So far you have seen how we configure Spring beans using XML configuration file. If you are comfortable with XML configuration, then it is really not required to learn how to proceed with Java-based configuration as you are going to achieve the same result using either of the configurations available.
Java-based configuration option enables you to write most of your Spring configuration without XML but with the help of few Java-based annotations explained in this chapter.
@Configuration & @Bean Annotations
Annotating a class with the @Configuration indicates that the class can be used by the Spring IoC container as a source of bean definitions. The @Bean annotation tells Spring that a method annotated with @Bean will return an object that should be registered as a bean in the Spring application context. The simplest possible @Configuration class would be as follows −
package com.tutorialspoint;
import org.springframework.context.annotation.*;
@Configuration
public class HelloWorldConfig {
@Bean
public HelloWorld helloWorld(){
return new HelloWorld();
}
}
The above code will be equivalent to the following XML configuration −
<beans>
<bean id = "helloWorld" class = "com.tutorialspoint.HelloWorld" />
</beans>
Here, the method name is annotated with @Bean works as bean ID and it creates and returns the actual bean. Your configuration class can have a declaration for more than one @Bean. Once your configuration classes are defined, you can load and provide them to Spring container using AnnotationConfigApplicationContext as follows −
public static void main(String[] args) {
ApplicationContext ctx = new AnnotationConfigApplicationContext(HelloWorldConfig.class);
HelloWorld helloWorld = ctx.getBean(HelloWorld.class);
helloWorld.setMessage("Hello World!");
helloWorld.getMessage();
}
You can load various configuration classes as follows −
public static void main(String[] args) {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
ctx.register(AppConfig.class, OtherConfig.class);
ctx.register(AdditionalConfig.class);
ctx.refresh();
MyService myService = ctx.getBean(MyService.class);
myService.doStuff();
}
Example
Let us have a working Eclipse IDE in place and take the following steps to create a Spring application −
Steps | Description |
---|---|
1 | Create a project with a name SpringExample and create a package com.tutorialspoint under the src folder in the created project. |
2 | Add required Spring libraries using Add External JARs option as explained in the Spring Hello World Example chapter. |
3 | Because you are using Java-based annotations, so you also need to add CGLIB.jar from your Java installation directory and ASM.jar library which can be downloaded from asm.ow2.org. |
4 | Create Java classes HelloWorldConfig, HelloWorld and MainApp under the com.tutorialspoint package. |
5 | The final step is to create the content of all the Java files and Bean Configuration file and run the application as explained below. |
Here is the content of HelloWorldConfig.java file
package com.tutorialspoint;
import org.springframework.context.annotation.*;
@Configuration
public class HelloWorldConfig {
@Bean
public HelloWorld helloWorld(){
return new HelloWorld();
}
}
Here is the content of HelloWorld.java file
package com.tutorialspoint;
public class HelloWorld {
private String message;
public void setMessage(String message){
this.message = message;
}
public void getMessage(){
System.out.println("Your Message : " + message);
}
}
Following is the content of the MainApp.java file
package com.tutorialspoint;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.*;
public class MainApp {
public static void main(String[] args) {
ApplicationContext ctx =
new AnnotationConfigApplicationContext(HelloWorldConfig.class);
HelloWorld helloWorld = ctx.getBean(HelloWorld.class);
helloWorld.setMessage("Hello World!");
helloWorld.getMessage();
}
}
Once you are done creating all the source files and adding the required additional libraries, let us run the application. You should note that there is no configuration file required. If everything is fine with your application, it will print the following message −
Your Message : Hello World!
Injecting Bean Dependencies
When @Beans have dependencies on one another, expressing that the dependency is as simple as having one bean method calling another as follows −
package com.tutorialspoint;
import org.springframework.context.annotation.*;
@Configuration
public class AppConfig {
@Bean
public Foo foo() {
return new Foo(bar());
}
@Bean
public Bar bar() {
return new Bar();
}
}
Here, the foo bean receives a reference to bar via the constructor injection. Now let us look at another working example.
Example
Let us have a working Eclipse IDE in place and take the following steps to create a Spring application −
Steps | Description |
---|---|
1 | Create a project with a name SpringExample and create a package com.tutorialspoint under the src folder in the created project. |
2 | Add required Spring libraries using Add External JARs option as explained in the Spring Hello World Example chapter. |
3 | Because you are using Java-based annotations, so you also need to add CGLIB.jar from your Java installation directory and ASM.jar library which can be downloaded from asm.ow2.org. |
4 | Create Java classes TextEditorConfig, TextEditor, SpellChecker and MainApp under the com.tutorialspoint package. |
5 | The final step is to create the content of all the Java files and Bean Configuration file and run the application as explained below. |
Here is the content of TextEditorConfig.java file
package com.tutorialspoint;
import org.springframework.context.annotation.*;
@Configuration
public class TextEditorConfig {
@Bean
public TextEditor textEditor(){
return new TextEditor( spellChecker() );
}
@Bean
public SpellChecker spellChecker(){
return new SpellChecker( );
}
}
Here is the content of TextEditor.java file
package com.tutorialspoint;
public class TextEditor {
private SpellChecker spellChecker;
public TextEditor(SpellChecker spellChecker){
System.out.println("Inside TextEditor constructor." );
this.spellChecker = spellChecker;
}
public void spellCheck(){
spellChecker.checkSpelling();
}
}
Following is the content of another dependent class file SpellChecker.java
package com.tutorialspoint;
public class SpellChecker {
public SpellChecker(){
System.out.println("Inside SpellChecker constructor." );
}
public void checkSpelling(){
System.out.println("Inside checkSpelling." );
}
}
Following is the content of the MainApp.java file
package com.tutorialspoint;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.*;
public class MainApp {
public static void main(String[] args) {
ApplicationContext ctx =
new AnnotationConfigApplicationContext(TextEditorConfig.class);
TextEditor te = ctx.getBean(TextEditor.class);
te.spellCheck();
}
}
Once you are done creating all the source files and adding the required additional libraries, let us run the application. You should note that there is no configuration file required. If everything is fine with your application, it will print the following message −
Inside SpellChecker constructor.
Inside TextEditor constructor.
Inside checkSpelling.
The @Import Annotation
The @Import annotation allows for loading @Bean definitions from another configuration class. Consider a ConfigA class as follows −
@Configuration
public class ConfigA {
@Bean
public A a() {
return new A();
}
}
You can import above Bean declaration in another Bean Declaration as follows −
@Configuration
@Import(ConfigA.class)
public class ConfigB {
@Bean
public B b() {
return new B();
}
}
Now, rather than needing to specify both ConfigA.class and ConfigB.class when instantiating the context, only ConfigB needs to be supplied as follows −
public static void main(String[] args) {
ApplicationContext ctx = new AnnotationConfigApplicationContext(ConfigB.class);
// now both beans A and B will be available...
A a = ctx.getBean(A.class);
B b = ctx.getBean(B.class);
}
Gọi lại vòng đời
Chú thích @Bean hỗ trợ chỉ định các phương thức gọi lại khởi tạo và hủy tùy ý, giống như các thuộc tính init-method và hủy-method của Spring XML trên phần tử bean -
public class Foo {
public void init() {
// initialization logic
}
public void cleanup() {
// destruction logic
}
}
@Configuration
public class AppConfig {
@Bean(initMethod = "init", destroyMethod = "cleanup" )
public Foo foo() {
return new Foo();
}
}
Chỉ định phạm vi đậu
Phạm vi mặc định là singleton, nhưng bạn có thể ghi đè điều này bằng chú thích @Scope như sau:
@Configuration
public class AppConfig {
@Bean
@Scope("prototype")
public Foo foo() {
return new Foo();
}
}
Bạn đã thấy trong tất cả các chương rằng cốt lõi của Mùa xuân là ApplicationContext, quản lý vòng đời hoàn chỉnh của hạt cà phê. ApplicationContext xuất bản các loại sự kiện nhất định khi tải các bean. Ví dụ: ContextStartedEvent được xuất bản khi khởi động ngữ cảnh và ContextStoppedEvent được xuất bản khi ngữ cảnh bị dừng.
Xử lý trong trường hợp ApplicationContext được cung cấp thông qua các ApplicationEvent lớp và ApplicationListener giao diện. Do đó, nếu một bean triển khai ApplicationListener , thì mỗi khi một ApplicationEvent được xuất bản lên ApplicationContext, bean đó sẽ được thông báo.
Spring cung cấp các sự kiện tiêu chuẩn sau:
Sr.No. | Sự kiện & mô tả tích hợp trong mùa xuân |
---|---|
1 | ContextRefreshedEvent Sự kiện này được xuất bản khi ApplicationContext được khởi tạo hoặc làm mới. Điều này cũng có thể được nêu ra bằng cách sử dụng phương thức refresh () trên giao diện ConfigurableApplicationContext . |
2 | ContextStartedEvent Sự kiện này được xuất bản khi ApplicationContext được khởi động bằng phương thức start () trên giao diện ConfigurableApplicationContext . Bạn có thể thăm dò cơ sở dữ liệu của mình hoặc bạn có thể khởi động lại bất kỳ ứng dụng nào đã dừng sau khi nhận được sự kiện này. |
3 | ContextStoppedEvent Sự kiện này được xuất bản khi ApplicationContext bị dừng bằng phương thức stop () trên giao diện ConfigurableApplicationContext . Bạn có thể làm công việc quản gia bắt buộc sau khi nhận được sự kiện này. |
4 | ContextClosedEvent Sự kiện này được xuất bản khi ApplicationContext được đóng bằng phương thức close () trên giao diện ConfigurableApplicationContext . Một bối cảnh khép kín đến cuối đời; nó không thể được làm mới hoặc khởi động lại. |
5 | RequestHandledEvent Đây là một sự kiện dành riêng cho web nói với tất cả các bean rằng một yêu cầu HTTP đã được phục vụ. |
Việc xử lý sự kiện của Spring là một luồng nên nếu một sự kiện được xuất bản, cho đến khi và trừ khi tất cả người nhận nhận được thông báo, các quá trình sẽ bị chặn và luồng sẽ không tiếp tục. Do đó, nên cẩn thận khi thiết kế ứng dụng của bạn nếu xử lý sự kiện được sử dụng.
Nghe các sự kiện theo ngữ cảnh
Để lắng nghe một sự kiện ngữ cảnh, một bean phải triển khai giao diện ApplicationListener chỉ có một phương thứconApplicationEvent(). Vì vậy, hãy để chúng tôi viết một ví dụ để xem cách các sự kiện lan truyền và cách bạn có thể đặt mã của mình để thực hiện tác vụ cần thiết dựa trên các sự kiện nhất định.
Hãy để chúng tôi có một IDE Eclipse hoạt động tại chỗ và thực hiện các bước sau để tạo một ứng dụng Spring -
Bươc | Sự miêu tả |
---|---|
1 | Tạo một dự án với tên SpringExample và tạo một gói com.tutorialspoint trongsrc thư mục trong dự án đã tạo. |
2 | Thêm các thư viện Spring bắt buộc bằng cách sử dụng tùy chọn Thêm JAR bên ngoài như được giải thích trong chương Ví dụ về Spring Hello World . |
3 | Tạo các lớp Java HelloWorld , CStartEventHandler , CStopEventHandler và MainApp trong gói com.tutorialspoint . |
4 | Tạo tệp cấu hình Đậu Beans.xml trongsrc thư mục. |
5 | Bước cuối cùng là tạo nội dung của tất cả các tệp Java và tệp Cấu hình Bean và chạy ứng dụng như được giải thích bên dưới. |
Đây là nội dung của HelloWorld.java tập tin
package com.tutorialspoint;
public class HelloWorld {
private String message;
public void setMessage(String message){
this.message = message;
}
public void getMessage(){
System.out.println("Your Message : " + message);
}
}
Sau đây là nội dung của CStartEventHandler.java tập tin
package com.tutorialspoint;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextStartedEvent;
public class CStartEventHandler
implements ApplicationListener<ContextStartedEvent>{
public void onApplicationEvent(ContextStartedEvent event) {
System.out.println("ContextStartedEvent Received");
}
}
Sau đây là nội dung của CStopEventHandler.java tập tin
package com.tutorialspoint;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextStoppedEvent;
public class CStopEventHandler
implements ApplicationListener<ContextStoppedEvent>{
public void onApplicationEvent(ContextStoppedEvent event) {
System.out.println("ContextStoppedEvent Received");
}
}
Sau đây là nội dung của MainApp.java tập tin
package com.tutorialspoint;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MainApp {
public static void main(String[] args) {
ConfigurableApplicationContext context =
new ClassPathXmlApplicationContext("Beans.xml");
// Let us raise a start event.
context.start();
HelloWorld obj = (HelloWorld) context.getBean("helloWorld");
obj.getMessage();
// Let us raise a stop event.
context.stop();
}
}
Sau đây là tệp cấu hình Beans.xml
<?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">
<bean id = "helloWorld" class = "com.tutorialspoint.HelloWorld">
<property name = "message" value = "Hello World!"/>
</bean>
<bean id = "cStartEventHandler" class = "com.tutorialspoint.CStartEventHandler"/>
<bean id = "cStopEventHandler" class = "com.tutorialspoint.CStopEventHandler"/>
</beans>
Khi bạn đã hoàn tất việc tạo tệp nguồn và tệp cấu hình bean, hãy để chúng tôi chạy ứng dụng. Nếu mọi thứ đều ổn với ứng dụng của bạn, nó sẽ in ra thông báo sau:
ContextStartedEvent Received
Your Message : Hello World!
ContextStoppedEvent Received
Nếu muốn, bạn có thể xuất bản các sự kiện tùy chỉnh của riêng mình và sau đó, bạn có thể nắm bắt tương tự để thực hiện bất kỳ hành động nào đối với các sự kiện tùy chỉnh đó. Nếu bạn quan tâm đến việc viết các sự kiện tùy chỉnh của riêng mình, bạn có thể kiểm tra Sự kiện tùy chỉnh trong mùa xuân.
Có một số bước cần thực hiện để viết và xuất bản các sự kiện tùy chỉnh của riêng bạn. Thực hiện theo các hướng dẫn được cung cấp trong chương này để viết, xuất bản và xử lý các Sự kiện Mùa xuân Tùy chỉnh.
Các bước | Sự miêu tả |
---|---|
1 | Tạo một dự án với tên SpringExample và tạo một gói com.tutorialspoint trongsrcthư mục trong dự án đã tạo. Tất cả các lớp sẽ được tạo trong gói này. |
2 | Thêm các thư viện Spring bắt buộc bằng cách sử dụng tùy chọn Thêm JAR bên ngoài như được giải thích trong chương Ví dụ về Spring Hello World . |
3 | Tạo một lớp sự kiện, CustomEvent bằng cách mở rộngApplicationEvent. Lớp này phải xác định một phương thức khởi tạo mặc định sẽ kế thừa phương thức khởi tạo từ lớp ApplicationEvent. |
4 | Khi lớp sự kiện của bạn được xác định, bạn có thể xuất bản nó từ bất kỳ lớp nào, giả sử như EventClassPublisher triển khai ApplicationEventPublisherAware . Bạn cũng sẽ cần khai báo lớp này trong tệp cấu hình XML dưới dạng bean để vùng chứa có thể xác định bean là nhà xuất bản sự kiện vì nó triển khai giao diện ApplicationEventPublisherAware. |
5 | Một sự kiện đã xuất bản có thể được xử lý trong một lớp, giả sử EventClassHandler triển khai giao diện ApplicationListener và triển khai phương thức onApplicationEvent cho sự kiện tùy chỉnh. |
6 | Tạo tệp cấu hình đậu Beans.xml trongsrcthư mục và một lớp MainApp sẽ hoạt động như ứng dụng Spring. |
7 | Bước cuối cùng là tạo nội dung của tất cả các tệp Java và tệp Cấu hình Bean và chạy ứng dụng như được giải thích bên dưới. |
Đây là nội dung của CustomEvent.java tập tin
package com.tutorialspoint;
import org.springframework.context.ApplicationEvent;
public class CustomEvent extends ApplicationEvent{
public CustomEvent(Object source) {
super(source);
}
public String toString(){
return "My Custom Event";
}
}
Sau đây là nội dung của CustomEventPublisher.java tập tin
package com.tutorialspoint;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
public class CustomEventPublisher implements ApplicationEventPublisherAware {
private ApplicationEventPublisher publisher;
public void setApplicationEventPublisher (ApplicationEventPublisher publisher) {
this.publisher = publisher;
}
public void publish() {
CustomEvent ce = new CustomEvent(this);
publisher.publishEvent(ce);
}
}
Sau đây là nội dung của CustomEventHandler.java tập tin
package com.tutorialspoint;
import org.springframework.context.ApplicationListener;
public class CustomEventHandler implements ApplicationListener<CustomEvent> {
public void onApplicationEvent(CustomEvent event) {
System.out.println(event.toString());
}
}
Sau đây là nội dung của MainApp.java tập tin
package com.tutorialspoint;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MainApp {
public static void main(String[] args) {
ConfigurableApplicationContext context =
new ClassPathXmlApplicationContext("Beans.xml");
CustomEventPublisher cvp =
(CustomEventPublisher) context.getBean("customEventPublisher");
cvp.publish();
cvp.publish();
}
}
Sau đây là tệp cấu hình Beans.xml
<?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">
<bean id = "customEventHandler" class = "com.tutorialspoint.CustomEventHandler"/>
<bean id = "customEventPublisher" class = "com.tutorialspoint.CustomEventPublisher"/>
</beans>
Khi bạn đã hoàn tất việc tạo tệp nguồn và tệp cấu hình bean, hãy để chúng tôi chạy ứng dụng. Nếu mọi thứ đều ổn với ứng dụng của bạn, nó sẽ in ra thông báo sau:
y Custom Event
y Custom Event
Một trong những thành phần chính của Spring Framework là Aspect oriented programming (AOP)khuôn khổ. Lập trình hướng theo khía cạnh đòi hỏi phải chia logic chương trình thành các phần riêng biệt được gọi là cái gọi là mối quan tâm. Các hàm mở rộng nhiều điểm của một ứng dụng được gọi làcross-cutting concernsvà những mối quan tâm xuyên suốt này tách biệt về mặt khái niệm với logic nghiệp vụ của ứng dụng. Có nhiều ví dụ điển hình phổ biến về các khía cạnh như ghi nhật ký, kiểm toán, giao dịch khai báo, bảo mật, bộ nhớ đệm, v.v.
Đơn vị quan trọng của mô-đun trong OOP là lớp, trong khi trong AOP, đơn vị mô-đun là khía cạnh. Dependency Injection giúp bạn tách các đối tượng ứng dụng của mình khỏi nhau và AOP giúp bạn tách các mối quan tâm xuyên suốt khỏi các đối tượng mà chúng ảnh hưởng. AOP giống như các trình kích hoạt trong các ngôn ngữ lập trình như Perl, .NET, Java và các ngôn ngữ khác.
Mô-đun AOP mùa xuân cung cấp các bộ đánh chặn để chặn một ứng dụng. Ví dụ: khi một phương thức được thực thi, bạn có thể thêm chức năng bổ sung trước hoặc sau khi thực thi phương thức.
Thuật ngữ AOP
Trước khi bắt đầu làm việc với AOP, chúng ta hãy làm quen với các khái niệm và thuật ngữ AOP. Các thuật ngữ này không dành riêng cho Spring, thay vào đó chúng có liên quan đến AOP.
Sr.No | Điều khoản & Mô tả |
---|---|
1 | Aspect Đây là một mô-đun có một tập hợp các API cung cấp các yêu cầu xuyên suốt. Ví dụ, một mô-đun ghi nhật ký sẽ được gọi là khía cạnh AOP để ghi nhật ký. Một ứng dụng có thể có bất kỳ khía cạnh nào tùy thuộc vào yêu cầu. |
2 | Join point Điều này thể hiện một điểm trong ứng dụng của bạn, nơi bạn có thể bổ sung khía cạnh AOP. Bạn cũng có thể nói, đó là vị trí thực tế trong ứng dụng nơi một hành động sẽ được thực hiện bằng cách sử dụng Spring AOP framework. |
3 | Advice Đây là hành động thực sự được thực hiện trước hoặc sau khi thực thi phương thức. Đây là một đoạn mã thực tế được gọi trong quá trình thực thi chương trình bởi Spring AOP framework. |
4 | Pointcut Đây là một tập hợp của một hoặc nhiều điểm nối mà một lời khuyên nên được thực hiện. Bạn có thể chỉ định phím tắt bằng cách sử dụng các biểu thức hoặc mẫu như chúng ta sẽ thấy trong các ví dụ AOP của mình. |
5 | Introduction Phần giới thiệu cho phép bạn thêm các phương thức hoặc thuộc tính mới vào các lớp hiện có. |
6 | Target object Đối tượng được tư vấn bởi một hoặc nhiều khía cạnh. Đối tượng này sẽ luôn là một đối tượng được hỗ trợ, còn được gọi là đối tượng được tư vấn. |
7 | Weaving Dệt là quá trình liên kết các khía cạnh với các loại ứng dụng hoặc đối tượng khác để tạo ra một đối tượng được tư vấn. Điều này có thể được thực hiện tại thời gian biên dịch, thời gian tải hoặc trong thời gian chạy. |
Các loại lời khuyên
Các khía cạnh mùa xuân có thể hoạt động với năm loại lời khuyên được đề cập như sau:
Sr.No | Lời khuyên & Mô tả |
---|---|
1 | before Chạy lời khuyên trước khi thực thi một phương thức. |
2 | after Chạy lời khuyên sau khi thực hiện phương pháp, bất kể kết quả của nó. |
3 | after-returning Chỉ chạy lời khuyên sau khi thực thi phương thức nếu phương thức hoàn tất thành công. |
4 | after-throwing Chỉ chạy lời khuyên sau khi thực thi một phương thức nếu phương thức thoát bằng cách ném một ngoại lệ. |
5 | around Chạy lời khuyên trước và sau khi phương pháp đã khuyên được gọi. |
Triển khai các khía cạnh tùy chỉnh
Mùa xuân hỗ trợ @AspectJ annotation style cách tiếp cận và schema-basedcách tiếp cận để thực hiện các khía cạnh tùy chỉnh. Hai cách tiếp cận này đã được giải thích chi tiết trong các phần sau.
Sr.No | Cách tiếp cận & Mô tả |
---|---|
1 | Dựa trên lược đồ XML Các khía cạnh được triển khai bằng cách sử dụng các lớp thông thường cùng với cấu hình dựa trên XML. |
2 | Dựa trên @AspectJ @AspectJ đề cập đến một kiểu khai báo các khía cạnh như các lớp Java thông thường được chú thích bằng các chú thích Java 5. |
Trong khi làm việc với cơ sở dữ liệu bằng cách sử dụng JDBC cũ, việc viết mã không cần thiết để xử lý các ngoại lệ, mở và đóng các kết nối cơ sở dữ liệu, v.v. Tuy nhiên, Spring JDBC Framework sẽ quản lý tất cả các chi tiết cấp thấp bắt đầu từ việc mở kết nối, chuẩn bị và thực hiện câu lệnh SQL, xử lý ngoại lệ, xử lý các giao dịch và cuối cùng là đóng kết nối.
Vì vậy, những gì bạn phải làm chỉ là xác định các tham số kết nối và chỉ định câu lệnh SQL được thực thi và thực hiện công việc cần thiết cho mỗi lần lặp trong khi tìm nạp dữ liệu từ cơ sở dữ liệu.
Spring JDBC cung cấp một số cách tiếp cận và các lớp tương ứng khác nhau để giao tiếp với cơ sở dữ liệu. Tôi sẽ sử dụng cách tiếp cận cổ điển và phổ biến nhất sử dụngJdbcTemplatelớp của khuôn khổ. Đây là lớp khung trung tâm quản lý tất cả các giao tiếp cơ sở dữ liệu và xử lý ngoại lệ.
Lớp JdbcTemplate
Lớp JDBC Template thực hiện các truy vấn SQL, cập nhật các câu lệnh, lưu trữ các lệnh gọi thủ tục, thực hiện lặp qua ResultSets và trích xuất các giá trị tham số trả về. Nó cũng bắt các ngoại lệ JDBC và dịch chúng sang hệ thống phân cấp ngoại lệ chung, nhiều thông tin hơn, được xác định trong gói org.springframework.dao.
Các phiên bản của lớp JdbcTemplate là luồng an toàn sau khi được cấu hình. Vì vậy, bạn có thể định cấu hình một phiên bản JdbcTemplate và sau đó đưa tham chiếu được chia sẻ này vào nhiều DAO một cách an toàn.
Một thực tiễn phổ biến khi sử dụng lớp Mẫu JDBC là định cấu hình một DataSource trong tệp cấu hình Spring của bạn, sau đó đưa phụ thuộc vào hạt DataSource được chia sẻ đó vào các lớp DAO của bạn và JdbcTemplate được tạo trong bộ định danh cho DataSource.
Định cấu hình nguồn dữ liệu
Hãy để chúng tôi tạo một bảng cơ sở dữ liệu Student trong cơ sở dữ liệu của chúng tôi TEST. Chúng tôi giả sử bạn đang làm việc với cơ sở dữ liệu MySQL, nếu bạn làm việc với bất kỳ cơ sở dữ liệu nào khác thì bạn có thể thay đổi các truy vấn DDL và SQL của mình cho phù hợp.
CREATE TABLE Student(
ID INT NOT NULL AUTO_INCREMENT,
NAME VARCHAR(20) NOT NULL,
AGE INT NOT NULL,
PRIMARY KEY (ID)
);
Bây giờ chúng ta cần cung cấp Nguồn dữ liệu cho Mẫu JDBC để nó có thể tự cấu hình để có quyền truy cập cơ sở dữ liệu. Bạn có thể định cấu hình Nguồn dữ liệu trong tệp XML bằng một đoạn mã như được hiển thị trong đoạn mã sau:
<bean id = "dataSource"
class = "org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name = "driverClassName" value = "com.mysql.jdbc.Driver"/>
<property name = "url" value = "jdbc:mysql://localhost:3306/TEST"/>
<property name = "username" value = "root"/>
<property name = "password" value = "password"/>
</bean>
Đối tượng truy cập dữ liệu (DAO)
DAO là viết tắt của Data Access Object, thường được sử dụng để tương tác với cơ sở dữ liệu. Các DAO tồn tại để cung cấp một phương tiện để đọc và ghi dữ liệu vào cơ sở dữ liệu và chúng sẽ hiển thị chức năng này thông qua một giao diện mà phần còn lại của ứng dụng sẽ truy cập chúng.
Hỗ trợ DAO trong Spring giúp bạn dễ dàng làm việc với các công nghệ truy cập dữ liệu như JDBC, Hibernate, JPA hoặc JDO một cách nhất quán.
Thực thi câu lệnh SQL
Hãy để chúng tôi xem cách chúng tôi có thể thực hiện thao tác CRUD (Tạo, Đọc, Cập nhật và Xóa) trên các bảng cơ sở dữ liệu bằng cách sử dụng đối tượng Mẫu JDBC và SQL.
Querying for an integer
String SQL = "select count(*) from Student";
int rowCount = jdbcTemplateObject.queryForInt( SQL );
Querying for a long
String SQL = "select count(*) from Student";
long rowCount = jdbcTemplateObject.queryForLong( SQL );
A simple query using a bind variable
String SQL = "select age from Student where id = ?";
int age = jdbcTemplateObject.queryForInt(SQL, new Object[]{10});
Querying for a String
String SQL = "select name from Student where id = ?";
String name = jdbcTemplateObject.queryForObject(SQL, new Object[]{10}, String.class);
Querying and returning an object
String SQL = "select * from Student where id = ?";
Student student = jdbcTemplateObject.queryForObject(
SQL, new Object[]{10}, new StudentMapper());
public class StudentMapper implements RowMapper<Student> {
public Student mapRow(ResultSet rs, int rowNum) throws SQLException {
Student student = new Student();
student.setID(rs.getInt("id"));
student.setName(rs.getString("name"));
student.setAge(rs.getInt("age"));
return student;
}
}
Querying and returning multiple objects
String SQL = "select * from Student";
List<Student> students = jdbcTemplateObject.query(
SQL, new StudentMapper());
public class StudentMapper implements RowMapper<Student> {
public Student mapRow(ResultSet rs, int rowNum) throws SQLException {
Student student = new Student();
student.setID(rs.getInt("id"));
student.setName(rs.getString("name"));
student.setAge(rs.getInt("age"));
return student;
}
}
Inserting a row into the table
String SQL = "insert into Student (name, age) values (?, ?)";
jdbcTemplateObject.update( SQL, new Object[]{"Zara", 11} );
Updating a row into the table
String SQL = "update Student set name = ? where id = ?";
jdbcTemplateObject.update( SQL, new Object[]{"Zara", 10} );
Deleting a row from the table
String SQL = "delete Student where id = ?";
jdbcTemplateObject.update( SQL, new Object[]{20} );
Thực thi các câu lệnh DDL
Bạn có thể dùng execute(..)từ jdbcTemplate để thực thi bất kỳ câu lệnh SQL hoặc câu lệnh DDL nào. Sau đây là một ví dụ sử dụng câu lệnh CREATE để tạo một bảng:
String SQL = "CREATE TABLE Student( " +
"ID INT NOT NULL AUTO_INCREMENT, " +
"NAME VARCHAR(20) NOT NULL, " +
"AGE INT NOT NULL, " +
"PRIMARY KEY (ID));"
jdbcTemplateObject.execute( SQL );
Ví dụ về khung JDBC mùa xuân
Dựa trên các khái niệm trên, chúng ta hãy kiểm tra một số ví dụ quan trọng sẽ giúp bạn hiểu cách sử dụng JDBC framework trong Spring -
Sr.No. | Ví dụ & Mô tả |
---|---|
1 | Ví dụ về Spring JDBC Ví dụ này sẽ giải thích cách viết một ứng dụng Spring dựa trên JDBC đơn giản. |
2 | Thủ tục lưu trữ SQL trong mùa xuân Tìm hiểu cách gọi thủ tục được lưu trữ trong SQL khi sử dụng JDBC trong Spring. |
Một giao dịch cơ sở dữ liệu là một chuỗi các hành động được coi như một đơn vị công việc duy nhất. Những hành động này sẽ hoàn thành toàn bộ hoặc không có hiệu lực. Quản lý giao dịch là một phần quan trọng của ứng dụng doanh nghiệp theo định hướng RDBMS để đảm bảo tính toàn vẹn và nhất quán của dữ liệu. Khái niệm về giao dịch có thể được mô tả với bốn thuộc tính chính sau đây được mô tả nhưACID -
Atomicity - Một giao dịch nên được coi như một đơn vị hoạt động duy nhất, có nghĩa là toàn bộ chuỗi hoạt động thành công hoặc không thành công.
Consistency - Điều này thể hiện tính nhất quán về tính toàn vẹn tham chiếu của cơ sở dữ liệu, các khóa chính duy nhất trong bảng, v.v.
Isolation- Có thể thực hiện đồng thời nhiều xử lý giao dịch với cùng một tập dữ liệu. Mỗi giao dịch phải được cách ly với các giao dịch khác để ngăn chặn dữ liệu bị hỏng.
Durability - Khi một giao dịch đã hoàn tất, kết quả của giao dịch này phải được thực hiện vĩnh viễn và không thể xóa khỏi cơ sở dữ liệu do lỗi hệ thống.
Một hệ thống cơ sở dữ liệu RDBMS thực sự sẽ đảm bảo tất cả bốn thuộc tính cho mỗi giao dịch. Chế độ xem đơn giản của một giao dịch được cấp cho cơ sở dữ liệu bằng SQL như sau:
Bắt đầu giao dịch bằng lệnh bắt đầu giao dịch .
Thực hiện các thao tác xóa, cập nhật hoặc chèn khác nhau bằng cách sử dụng truy vấn SQL.
Nếu tất cả các hoạt động đều thành công thì hãy thực hiện cam kết nếu không thì sẽ quay lại tất cả các hoạt động.
Spring framework cung cấp một lớp trừu tượng nằm trên các API quản lý giao dịch cơ bản khác nhau. Hỗ trợ giao dịch của Spring nhằm mục đích cung cấp một giải pháp thay thế cho các giao dịch EJB bằng cách thêm các khả năng giao dịch vào POJO. Spring hỗ trợ cả quản lý giao dịch theo chương trình và khai báo. Các EJB yêu cầu máy chủ ứng dụng, nhưng quản lý giao dịch Spring có thể được thực hiện mà không cần máy chủ ứng dụng.
Giao dịch địa phương so với toàn cầu
Các giao dịch cục bộ dành riêng cho một tài nguyên giao dịch đơn lẻ như kết nối JDBC, trong khi các giao dịch toàn cầu có thể kéo dài nhiều tài nguyên giao dịch giống như giao dịch trong hệ thống phân tán.
Quản lý giao dịch cục bộ có thể hữu ích trong môi trường máy tính tập trung nơi các thành phần và tài nguyên ứng dụng được đặt tại một trang web và quản lý giao dịch chỉ liên quan đến trình quản lý dữ liệu cục bộ chạy trên một máy duy nhất. Giao dịch địa phương dễ dàng được thực hiện hơn.
Quản lý giao dịch toàn cầu được yêu cầu trong môi trường máy tính phân tán, nơi tất cả các tài nguyên được phân phối trên nhiều hệ thống. Trong trường hợp như vậy, việc quản lý giao dịch cần được thực hiện ở cả cấp địa phương và toàn cầu. Một giao dịch phân tán hoặc toàn cầu được thực hiện trên nhiều hệ thống và việc thực hiện nó đòi hỏi sự phối hợp giữa hệ thống quản lý giao dịch toàn cầu và tất cả các nhà quản lý dữ liệu cục bộ của tất cả các hệ thống liên quan.
Có lập trình so với Khai báo
Spring hỗ trợ hai loại quản lý giao dịch -
Quản lý giao dịch có lập trình - Điều này có nghĩa là bạn phải quản lý giao dịch với sự trợ giúp của lập trình. Điều đó mang lại cho bạn sự linh hoạt cao độ, nhưng rất khó để duy trì.
Quản lý giao dịch khai báo - Điều này có nghĩa là bạn tách biệt quản lý giao dịch khỏi mã doanh nghiệp. Bạn chỉ sử dụng chú thích hoặc cấu hình dựa trên XML để quản lý các giao dịch.
Quản lý giao dịch khai báo được ưu tiên hơn quản lý giao dịch có lập trình mặc dù nó kém linh hoạt hơn quản lý giao dịch có lập trình, cho phép bạn kiểm soát các giao dịch thông qua mã của mình. Nhưng như một loại mối quan tâm xuyên suốt, quản lý giao dịch khai báo có thể được mô-đun hóa với cách tiếp cận AOP. Spring hỗ trợ quản lý giao dịch khai báo thông qua khuôn khổ Spring AOP.
Tóm tắt giao dịch mùa xuân
Chìa khóa của sự trừu tượng hóa giao dịch Spring được xác định bởi giao diện org.springframework.transaction.PlatformTransactionManager , như sau:
public interface PlatformTransactionManager {
TransactionStatus getTransaction(TransactionDefinition definition);
throws TransactionException;
void commit(TransactionStatus status) throws TransactionException;
void rollback(TransactionStatus status) throws TransactionException;
}
Sr.No | Phương pháp & Mô tả |
---|---|
1 | TransactionStatus getTransaction(TransactionDefinition definition) Phương thức này trả về một giao dịch hiện đang hoạt động hoặc tạo một giao dịch mới, theo hành vi lan truyền được chỉ định. |
2 | void commit(TransactionStatus status) Phương thức này cam kết giao dịch nhất định, liên quan đến trạng thái của nó. |
3 | void rollback(TransactionStatus status) Phương thức này thực hiện khôi phục giao dịch đã cho. |
Các TransactionDefinition là giao diện cốt lõi của sự hỗ trợ giao dịch trong mùa xuân và nó được định nghĩa như sau -
public interface TransactionDefinition {
int getPropagationBehavior();
int getIsolationLevel();
String getName();
int getTimeout();
boolean isReadOnly();
}
Sr.No | Phương pháp & Mô tả |
---|---|
1 | int getPropagationBehavior() Phương thức này trả về hành vi lan truyền. Spring cung cấp tất cả các tùy chọn truyền bá giao dịch quen thuộc từ EJB CMT. |
2 | int getIsolationLevel() Phương pháp này trả về mức độ mà giao dịch này bị cô lập với công việc của các giao dịch khác. |
3 | String getName() Phương thức này trả về tên của giao dịch này. |
4 | int getTimeout() Phương thức này trả về thời gian tính bằng giây mà giao dịch phải hoàn tất. |
5 | boolean isReadOnly() Phương thức này trả về liệu giao dịch có ở chế độ chỉ đọc hay không. |
Sau đây là các giá trị có thể có cho mức cô lập:
Sr.No | Cô lập & Mô tả |
---|---|
1 | TransactionDefinition.ISOLATION_DEFAULT Đây là mức cô lập mặc định. |
2 | TransactionDefinition.ISOLATION_READ_COMMITTED Cho biết rằng việc đọc bẩn được ngăn chặn; đọc không lặp lại và đọc ảo có thể xảy ra. |
3 | TransactionDefinition.ISOLATION_READ_UNCOMMITTED Chỉ ra rằng các lần đọc bẩn, đọc không lặp lại và đọc ảo có thể xảy ra. |
4 | TransactionDefinition.ISOLATION_REPEATABLE_READ Cho biết rằng việc đọc bẩn và đọc không lặp lại được ngăn chặn; đọc ảo có thể xảy ra. |
5 | TransactionDefinition.ISOLATION_SERIALIZABLE Cho biết rằng việc đọc bẩn, đọc không lặp lại và đọc ảo bị ngăn chặn. |
Sau đây là các giá trị có thể có cho các kiểu lan truyền:
Sr.No. | Tuyên truyền & Mô tả |
---|---|
1 | TransactionDefinition.PROPAGATION_MANDATORY Hỗ trợ giao dịch hiện tại; ném một ngoại lệ nếu không có giao dịch hiện tại nào tồn tại. |
2 | TransactionDefinition.PROPAGATION_NESTED Thực thi trong một giao dịch lồng nhau nếu tồn tại một giao dịch hiện tại. |
3 | TransactionDefinition.PROPAGATION_NEVER Không hỗ trợ giao dịch hiện tại; ném một ngoại lệ nếu một giao dịch hiện tại tồn tại. |
4 | TransactionDefinition.PROPAGATION_NOT_SUPPORTED Không hỗ trợ giao dịch hiện tại; thay vì luôn thực thi không giao dịch. |
5 | TransactionDefinition.PROPAGATION_REQUIRED Hỗ trợ giao dịch hiện tại; tạo một cái mới nếu không có cái nào tồn tại. |
6 | TransactionDefinition.PROPAGATION_REQUIRES_NEW Tạo giao dịch mới, tạm dừng giao dịch hiện tại nếu có. |
7 | TransactionDefinition.PROPAGATION_SUPPORTS Hỗ trợ giao dịch hiện tại; thực thi phi giao dịch nếu không có. |
số 8 | TransactionDefinition.TIMEOUT_DEFAULT Sử dụng thời gian chờ mặc định của hệ thống giao dịch cơ bản hoặc không sử dụng nếu thời gian chờ không được hỗ trợ. |
Các TransactionStatus giao diện cung cấp một cách đơn giản đối với mã giao dịch để thực hiện giao dịch kiểm soát và truy vấn tình trạng giao dịch.
public interface TransactionStatus extends SavepointManager {
boolean isNewTransaction();
boolean hasSavepoint();
void setRollbackOnly();
boolean isRollbackOnly();
boolean isCompleted();
}
Sr.No. | Phương pháp & Mô tả |
---|---|
1 | boolean hasSavepoint() Phương thức này trả về liệu giao dịch này nội bộ có mang một điểm lưu hay không, tức là đã được tạo dưới dạng giao dịch lồng nhau dựa trên một điểm lưu hay chưa. |
2 | boolean isCompleted() Phương thức này trả về liệu giao dịch này đã hoàn tất hay chưa, tức là liệu giao dịch đã được cam kết hay chưa. |
3 | boolean isNewTransaction() Phương thức này trả về true trong trường hợp giao dịch hiện tại là mới. |
4 | boolean isRollbackOnly() Phương thức này trả về liệu giao dịch có được đánh dấu là chỉ khôi phục hay không. |
5 | void setRollbackOnly() Phương pháp này đặt giao dịch là chỉ khôi phục. |
Khung công tác Spring Web MVC cung cấp kiến trúc Model-View-Controller (MVC) và các thành phần sẵn sàng có thể được sử dụng để phát triển các ứng dụng web linh hoạt và kết hợp lỏng lẻo. Mô hình MVC dẫn đến việc tách biệt các khía cạnh khác nhau của ứng dụng (logic đầu vào, logic nghiệp vụ và logic giao diện người dùng), đồng thời cung cấp sự kết hợp lỏng lẻo giữa các phần tử này.
Các Model đóng gói dữ liệu ứng dụng và nói chung chúng sẽ bao gồm POJO.
Các View chịu trách nhiệm hiển thị dữ liệu mô hình và nói chung, nó tạo ra đầu ra HTML mà trình duyệt của khách hàng có thể diễn giải.
Các Controller chịu trách nhiệm xử lý các yêu cầu của người dùng và xây dựng một mô hình thích hợp và chuyển nó đến chế độ xem để kết xuất.
The DispatcherServlet
Khung mô hình-view-controller (MVC) của Spring Web được thiết kế xung quanh một DispatcherServlet để xử lý tất cả các yêu cầu và phản hồi HTTP. Quy trình xử lý yêu cầu của Spring Web MVC DispatcherServlet được minh họa trong sơ đồ sau:
Sau đây là chuỗi các sự kiện tương ứng với một yêu cầu HTTP đến DispatcherServlet :
Sau khi nhận được một yêu cầu HTTP, DispatcherServlet sẽ tư vấn cho HandlerMapping để gọi Bộ điều khiển thích hợp .
Bộ điều khiển nhận yêu cầu và gọi các phương thức dịch vụ thích hợp dựa trên phương thức GET hoặc POST đã sử dụng. Phương thức dịch vụ sẽ thiết lập dữ liệu mô hình dựa trên logic nghiệp vụ đã xác định và trả về tên chế độ xem cho DispatcherServlet .
Các DispatcherServlet sẽ mất sự giúp đỡ từ ViewResolver để đón các quan điểm được xác định cho yêu cầu.
Sau khi hoàn tất chế độ xem, DispatcherServlet chuyển dữ liệu mô hình sang chế độ xem cuối cùng được hiển thị trên trình duyệt.
Tất cả các thành phần được đề cập ở trên, tức là HandlerMapping, Controller và ViewResolver là một phần của WebApplicationContext w, là một phần mở rộng của ApplicationContext đơn giản với một số tính năng bổ sung cần thiết cho các ứng dụng web.
Cấu hình yêu cầu
Bạn cần ánh xạ các yêu cầu mà bạn muốn DispatcherServlet xử lý, bằng cách sử dụng ánh xạ URL trongweb.xmltập tin. Sau đây là một ví dụ để hiển thị khai báo và ánh xạ choHelloWeb Ví dụ về DispatcherServlet -
<web-app id = "WebApp_ID" version = "2.4"
xmlns = "http://java.sun.com/xml/ns/j2ee"
xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation = "http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<display-name>Spring MVC Application</display-name>
<servlet>
<servlet-name>HelloWeb</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>HelloWeb</servlet-name>
<url-pattern>*.jsp</url-pattern>
</servlet-mapping>
</web-app>
Các web.xmltệp sẽ được lưu trong thư mục WebContent / WEB-INF của ứng dụng web của bạn. Khi khởi tạoHelloWeb DispatcherServlet, khung công tác sẽ cố gắng tải ngữ cảnh ứng dụng từ một tệp có tên [servlet-name]-servlet.xmlnằm trong Thư mục WebContent / WEB-INFdirectory của ứng dụng. Trong trường hợp này, tệp của chúng tôi sẽHelloWebservlet.xml.
Tiếp theo, thẻ <servlet-mapping> cho biết URL nào sẽ được xử lý bởi DispatcherServlet nào. Tại đây tất cả các yêu cầu HTTP kết thúc bằng.jsp sẽ được xử lý bởi HelloWeb DispatcherServlet.
Nếu bạn không muốn sử dụng tên tệp mặc định là [servlet-name] -servlet.xml và vị trí mặc định là WebContent / WEB-INF , bạn có thể tùy chỉnh tên và vị trí tệp này bằng cách thêm trình nghe servlet ContextLoaderListener trong tệp web.xml của mình như sau -
<web-app...>
<!-------- DispatcherServlet definition goes here----->
....
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/HelloWeb-servlet.xml</param-value>
</context-param>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
</web-app>
Bây giờ, hãy để chúng tôi kiểm tra cấu hình cần thiết cho HelloWeb-servlet.xmltệp, được đặt trong thư mục WebContent / WEB-INF của ứng dụng web của bạn -
<beans xmlns = "http://www.springframework.org/schema/beans"
xmlns:context = "http://www.springframework.org/schema/context"
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
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<context:component-scan base-package = "com.tutorialspoint" />
<bean class = "org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name = "prefix" value = "/WEB-INF/jsp/" />
<property name = "suffix" value = ".jsp" />
</bean>
</beans>
Sau đây là những điểm quan trọng về HelloWeb-servlet.xml tập tin -
Tệp [servlet-name] -servlet.xml sẽ được sử dụng để tạo các bean được định nghĩa, ghi đè các định nghĩa của bất kỳ bean nào được xác định có cùng tên trong phạm vi toàn cục.
Thẻ <context: component-scan ...> sẽ được sử dụng để kích hoạt khả năng quét chú thích Spring MVC, cho phép sử dụng các chú thích như @Controller và @RequestMapping, v.v.
Các InternalResourceViewResolver sẽ có những quy định để giải quyết các tên xem. Theo quy tắc đã xác định ở trên, một chế độ xem logic có tênhellođược ủy quyền triển khai chế độ xem tại /WEB-INF/jsp/hello.jsp .
Phần sau đây sẽ chỉ cho bạn cách tạo các thành phần thực của bạn, tức là Bộ điều khiển, Mô hình và Chế độ xem.
Xác định Bộ điều khiển
DispatcherServlet ủy quyền yêu cầu cho bộ điều khiển để thực thi chức năng cụ thể cho nó. Các@Controllerchú thích chỉ ra rằng một lớp cụ thể đóng vai trò của bộ điều khiển. Các@RequestMapping chú thích được sử dụng để ánh xạ một URL tới toàn bộ một lớp hoặc một phương thức xử lý cụ thể.
@Controller
@RequestMapping("/hello")
public class HelloController {
@RequestMapping(method = RequestMethod.GET)
public String printHello(ModelMap model) {
model.addAttribute("message", "Hello Spring MVC Framework!");
return "hello";
}
}
Các @Controllerchú thích định nghĩa lớp như một bộ điều khiển Spring MVC. Đây, cách sử dụng đầu tiên của@RequestMapping chỉ ra rằng tất cả các phương pháp xử lý trên bộ điều khiển này liên quan đến /hellocon đường. Chú thích tiếp theo@RequestMapping(method = RequestMethod.GET)được sử dụng để khai báo phương thức theprintHello () làm phương thức dịch vụ mặc định của bộ điều khiển để xử lý yêu cầu HTTP GET. Bạn có thể xác định một phương thức khác để xử lý bất kỳ yêu cầu POST nào tại cùng một URL.
Bạn có thể viết bộ điều khiển ở trên ở một biểu mẫu khác, nơi bạn có thể thêm các thuộc tính bổ sung trong @RequestMapping như sau:
@Controller
public class HelloController {
@RequestMapping(value = "/hello", method = RequestMethod.GET)
public String printHello(ModelMap model) {
model.addAttribute("message", "Hello Spring MVC Framework!");
return "hello";
}
}
Các value thuộc tính chỉ ra URL mà phương thức xử lý được ánh xạ tới và methodthuộc tính xác định phương thức dịch vụ để xử lý yêu cầu HTTP GET. Những điểm quan trọng sau đây cần được lưu ý về bộ điều khiển được xác định ở trên:
Bạn sẽ xác định logic nghiệp vụ bắt buộc bên trong một phương thức dịch vụ. Bạn có thể gọi một phương thức khác bên trong phương thức này theo yêu cầu.
Dựa trên logic nghiệp vụ được xác định, bạn sẽ tạo một mô hình trong phương pháp này. Bạn có thể sử dụng các thuộc tính mô hình khác nhau của setter và các thuộc tính này sẽ được chế độ xem truy cập để trình bày kết quả cuối cùng. Ví dụ này tạo một mô hình với thuộc tính của nó là "message".
Một phương thức dịch vụ đã xác định có thể trả về một Chuỗi, chứa tên của viewđược sử dụng để kết xuất mô hình. Ví dụ này trả về "hello" dưới dạng tên chế độ xem logic.
Tạo chế độ xem JSP
Spring MVC hỗ trợ nhiều kiểu xem cho các công nghệ trình chiếu khác nhau. Chúng bao gồm - JSP, HTML, PDF, trang tính Excel, XML, mẫu Velocity, XSLT, JSON, nguồn cấp dữ liệu Atom và RSS, JasperReports, v.v. Nhưng thông thường nhất, chúng tôi sử dụng các mẫu JSP được viết bằng JSTL.
Hãy để chúng tôi viết một đơn giản hello xem trong /WEB-INF/hello/hello.jsp -
<html>
<head>
<title>Hello Spring MVC</title>
</head>
<body>
<h2>${message}</h2>
</body>
</html>
Đây ${message}là thuộc tính mà chúng tôi đã thiết lập bên trong Bộ điều khiển. Bạn có thể có nhiều thuộc tính được hiển thị bên trong chế độ xem của mình.
Ví dụ về khung MVC của Spring Web
Dựa trên các khái niệm trên, hãy để chúng tôi kiểm tra một số ví dụ quan trọng sẽ giúp bạn trong việc xây dựng Ứng dụng web mùa xuân của mình -
Sr.No. | Ví dụ & Mô tả |
---|---|
1 | Ví dụ về Spring MVC Hello World Ví dụ này sẽ giải thích cách viết một ứng dụng Spring Web Hello World đơn giản. |
2 | Ví dụ về xử lý biểu mẫu Spring MVC Ví dụ này sẽ giải thích cách viết một ứng dụng Spring Web bằng cách sử dụng các biểu mẫu HTML để gửi dữ liệu đến bộ điều khiển và hiển thị kết quả đã xử lý. |
3 | Ví dụ về chuyển hướng trang mùa xuân Tìm hiểu cách sử dụng chức năng chuyển hướng trang trong Spring MVC Framework. |
4 | Ví dụ về trang tĩnh mùa xuân Tìm hiểu cách truy cập các trang tĩnh cùng với các trang động trong Spring MVC Framework. |
5 | Ví dụ về xử lý ngoại lệ mùa xuân Tìm hiểu cách xử lý các ngoại lệ trong Spring MVC Framework. |
Đây là một chức năng Log4J rất dễ sử dụng bên trong các ứng dụng Spring. Ví dụ sau sẽ hướng dẫn bạn qua các bước đơn giản để giải thích sự tích hợp đơn giản giữa Log4J và Spring.
Chúng tôi cho rằng bạn đã có log4Jđược cài đặt trên máy của bạn. Nếu bạn chưa có thì bạn có thể tải xuống từhttps://logging.apache.org/và chỉ cần giải nén tệp đã nén trong bất kỳ thư mục nào. Chúng tôi sẽ chỉ sử dụnglog4j-x.y.z.jar trong dự án của chúng tôi.
Tiếp theo, hãy để chúng tôi có một IDE Eclipse đang hoạt động và thực hiện các bước sau để phát triển một Ứng dụng Web dựa trên Biểu mẫu Động bằng cách sử dụng Spring Web Framework -
Các bước | Sự miêu tả |
---|---|
1 | Tạo một dự án với tên SpringExample và tạo một gói com.tutorialspoint trongsrc thư mục trong dự án đã tạo. |
2 | Thêm các thư viện Spring bắt buộc bằng cách sử dụng tùy chọn Thêm JAR bên ngoài như được giải thích trong chương Ví dụ về Spring Hello World . |
3 | Thêm thư viện log4j log4j-xyzjar cũng như trong dự án của bạn bằng cách sử dụng Thêm JAR bên ngoài . |
4 | Tạo các lớp Java HelloWorld và MainApp trong gói com.tutorialspoint . |
5 | Tạo tệp cấu hình Đậu Beans.xml trongsrc thư mục. |
6 | Tạo tệp cấu hình log4J log4j.properties trongsrc thư mục. |
7 | Bước cuối cùng là tạo nội dung của tất cả các tệp Java và tệp Cấu hình Bean và chạy ứng dụng như được giải thích bên dưới. |
Đây là nội dung của HelloWorld.java tập tin
package com.tutorialspoint;
public class HelloWorld {
private String message;
public void setMessage(String message){
this.message = message;
}
public void getMessage() {
System.out.println("Your Message : " + message);
}
}
Sau đây là nội dung của tệp thứ hai MainApp.java
package com.tutorialspoint;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.apache.log4j.Logger;
public class MainApp {
static Logger log = Logger.getLogger(MainApp.class.getName());
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");
log.info("Going to create HelloWord Obj");
HelloWorld obj = (HelloWorld) context.getBean("helloWorld");
obj.getMessage();
log.info("Exiting the program");
}
}
Bạn có thể tạo debug và errorthông báo theo cách tương tự như chúng tôi đã tạo thông báo thông tin. Bây giờ chúng ta hãy xem nội dung củaBeans.xml tập tin
<?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">
<bean id = "helloWorld" class = "com.tutorialspoint.HelloWorld">
<property name = "message" value = "Hello World!"/>
</bean>
</beans>
Sau đây là nội dung của log4j.properties xác định các quy tắc tiêu chuẩn cần thiết cho Log4J để tạo thông báo nhật ký
# Define the root logger with appender file
log4j.rootLogger = DEBUG, FILE
# Define the file appender
log4j.appender.FILE=org.apache.log4j.FileAppender
# Set the name of the file
log4j.appender.FILE.File=C:\\log.out
# Set the immediate flush to true (default)
log4j.appender.FILE.ImmediateFlush=true
# Set the threshold to debug mode
log4j.appender.FILE.Threshold=debug
# Set the append to false, overwrite
log4j.appender.FILE.Append=false
# Define the layout for file appender
log4j.appender.FILE.layout=org.apache.log4j.PatternLayout
log4j.appender.FILE.layout.conversionPattern=%m%n
Khi bạn đã hoàn tất việc tạo các tệp cấu hình nguồn và bean, hãy để chúng tôi chạy ứng dụng. Nếu mọi thứ đều ổn với ứng dụng của bạn, điều này sẽ in ra thông báo sau trong bảng điều khiển Eclipse:
Your Message : Hello World!
Nếu bạn kiểm tra ổ C: \\, thì bạn sẽ tìm thấy tệp nhật ký của mình log.out với các thông báo nhật ký khác nhau, như sau:
<!-- initialization log messages -->
Going to create HelloWord Obj
Returning cached instance of singleton bean 'helloWorld'
Exiting the program
API ghi nhật ký Jakarta Commons (JCL)
Ngoài ra bạn có thể sử dụng Jakarta Commons Logging (JCL)API để tạo nhật ký trong ứng dụng Spring của bạn. JCL có thể được tải xuống từhttps://jakarta.apache.org/commons/logging/. Tệp duy nhất về mặt kỹ thuật mà chúng tôi cần từ gói này là tệp commons-logging-xyzjar , tệp này cần được đặt trong classpath của bạn theo cách tương tự như bạn đã đặt log4j-xyzjar trong ví dụ trên.
Để sử dụng chức năng ghi nhật ký, bạn cần một đối tượng org.apache.commons.logging.Log và sau đó, bạn có thể gọi một trong các phương thức sau theo yêu cầu của bạn:
- gây tử vong (Thông báo đối tượng)
- lỗi (Thông báo đối tượng)
- cảnh báo (Thông báo đối tượng)
- thông tin (Thông báo đối tượng)
- gỡ lỗi (Thông báo đối tượng)
- dấu vết (Thông điệp đối tượng)
Sau đây là sự thay thế của MainApp.java, sử dụng API JCL
package com.tutorialspoint;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.apache.commons.logging. Log;
import org.apache.commons.logging. LogFactory;
public class MainApp {
static Log log = LogFactory.getLog(MainApp.class.getName());
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");
log.info("Going to create HelloWord Obj");
HelloWorld obj = (HelloWorld) context.getBean("helloWorld");
obj.getMessage();
log.info("Exiting the program");
}
}
Bạn phải đảm bảo rằng bạn đã bao gồm tệp commons-logging-xyzjar trong dự án của mình, trước khi biên dịch và chạy chương trình.
Bây giờ giữ nguyên cấu hình và nội dung còn lại trong ví dụ trên, nếu bạn biên dịch và chạy ứng dụng của mình, bạn sẽ nhận được kết quả tương tự như những gì bạn nhận được khi sử dụng API Log4J.