Kỹ thuật Autowiring sử dụng annotation trong Spring Framework

Bài viết được sự cho phép của smartjob.vn
Có 3 cách để autowiring trong Spring là:
– Sử dụng annotation
– Sử dụng code Java
– Cấu hình trong file XML.
Trong bài viết này giới thiệu đến các bạn kỹ thuật autowiring dùng annotation. Đây là cách autowiring nhanh, dễ thực hiện nhất, do chỉ cần đặt annotation @Autowired trước phương thức set (dùng cho việc khởi tạo Object) (*) và đặt annotation @Service trước class chứa phương thức (*).
Ví dụ dưới đây minh họa một giao dịch ngân hàng: chuyển tiền giữa 2 tài khoản.
Chuẩn bị công cụ:
– JDK 8 update 92 [1]
– IntelliJ IDEA 2016.1.2 [2]
– Maven 3.3.9 [3]
– Apache Tomcat 8.0.35 [4]
– Trình duyệt web (Google Chrome, Mozilla Firefox, v.v..)
Khởi tạo project:
Chọn project Maven từ archetype:
Khai báo 3 tham số GAV khởi tạo project (GAV: Group – ArtifactId – Version)
GroupId: vn.smartjob.demo
ArtifactId: demoSpring
Version: 1.0.0-SNAPSHOT (bạn nên dùng hậu tố -SNAPSHOT).
Đặt tên project và chọn thư mục lưu project:
Bạn sửa lại file pom.xml như sau:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>vn.smartjob.demo</groupId> <artifactId>demoSpring</artifactId> <packaging>war</packaging> <version>1.0.0-SNAPSHOT</version> <name>demoSpring Maven Webapp</name> <url>http://smartJob.vn</url> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>4.2.6.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>4.2.6.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>4.2.6.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>4.2.6.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> <version>4.2.6.RELEASE</version> </dependency> </dependencies> <build> <finalName>demoSpring</finalName> </build> </project>
Các dependency quan trọng đã được highlight trong mã nguồn bên trên (dòng 22, 27, 32, 37, 42). Thư viện đã được import tự động
Do project được tạo ra từ Maven archetype, do đó cần chỉnh sửa thêm. Bạn tạo thư mục java để chứa mã nguồn.
Bạn cần thao tác này để IntelliJ IDEA nhận diện thư mục java là thư mục chứa source code.
Bạn sẽ tạo package (chứa các class Java) vào thư mục java vừa tạo ở trên.
Tạo thực thể tài khoản là Account:
package vn.smartJob.demoSpring.annotationBasedAutowiring; import java.util.Date; /** * Account domain. * * @author SmartJob */ public class Account { private long id; private String ownerName; private double balance; private Date accessTime; private boolean locked; public Account() { } public Account(long id, String ownerName, double balance, Date accessTime, boolean locked) { this.id = id; this.ownerName = ownerName; this.balance = balance; this.accessTime = accessTime; this.locked = locked; } public long getId() { return id; } public void setId(long id) { this.id = id; } public String getOwnerName() { return ownerName; } public void setOwnerName(String ownerName) { this.ownerName = ownerName; } public double getBalance() { return balance; } public void setBalance(double balance) { this.balance = balance; } public Date getAccessTime() { return accessTime; } public void setAccessTime(Date accessTime) { this.accessTime = accessTime; } public boolean isLocked() { return locked; } public void setLocked(boolean locked) { this.locked = locked; } }
Interface AccountDAO dùng làm khuôn dạng cho các phương thức truy vấn dữ liệu:
package vn.smartJob.demoSpring.annotationBasedAutowiring; import java.util.List; /** * Interface dùng để làm khuôn cho các phương thức (method) truy vấn dữ liệu. * * @author SmartJob */ public interface AccountDAO { public void insert(Account account); public void update(Account account); public void update(List<Account> accounts); public void delete(long accountId); public Account find(long accountId); public List<Account> find(List<Long> accountIds); public List<Account> find(String ownerName); public List<Account> find(boolean locked); }
Triển khai class DAO thực tế:
package vn.smartJob.demoSpring.annotationBasedAutowiring; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Repository; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; @Repository @Qualifier("accountDao") public class AccountDAOInMemoryImpl implements AccountDAO { private Map<Long, Account> accountsMap = new HashMap<>(); { Account account1 = new Account(); account1.setId(1L); account1.setOwnerName("Hoang The Anh"); account1.setBalance(8000000.0); Account account2 = new Account(); account2.setId(2L); account2.setOwnerName("Nguyen Duc Hai"); account2.setBalance(4000000.0); accountsMap.put(account1.getId(), account1); accountsMap.put(account2.getId(), account2); } @Override public void insert(Account account) { accountsMap.put(account.getId(), account); } @Override public void update(Account account) { accountsMap.put(account.getId(), account); } @Override public void update(List<Account> accounts) { for (Account account : accounts) { update(account); } } @Override public void delete(long accountId) { accountsMap.remove(accountId); } @Override public Account find(long accountId) { return accountsMap.get(accountId); } @Override public List<Account> find(List<Long> accountIds) { List<Account> accounts = new ArrayList<>(); for (Long id : accountIds) { accounts.add(accountsMap.get(id)); } return accounts; } @Override public List<Account> find(String ownerName) { List<Account> accounts = new ArrayList<>(); for (Account account : accountsMap.values()) { if (ownerName.equals(account.getOwnerName())) { accounts.add(account); } } return accounts; } @Override public List<Account> find(boolean locked) { List<Account> accounts = new ArrayList<>(); for (Account account : accountsMap.values()) { if (locked == account.isLocked()) { accounts.add(account); } } return accounts; } }
Chúng ta có 2 tài khoản ngân hàng: Hoàng Thế Anh có 8 triệu đồng trong tài khoản (id = 1). Nguyễn Đức Hải có 4 triệu đồng trong tài khoản (id = 2). Để đảm bảo ví dụ minh họa không quá phực tạp, chúng ta không truy vấn vào cơ sở dữ liệu thực, mà sử dụng cơ sở dữ liệu mô phỏng, dạng HashMap. Các phương thức không liên quan đến CRUD (Creat- Read – Update – Delete) nguyên tử (mức nhỏ nhất của một truy vấn), sẽ xử lý bởi AccountService và AccountServiceImpl .
package vn.smartJob.demoSpring.annotationBasedAutowiring; /** * Interface service. * * @author SmartJob */ public interface AccountService { public void transferMoney(long sourceAccountId, long targetAccountId, double amount); public void depositMoney(long accountId, double amount) throws Exception; public Account getAccount(long accountId); }
package vn.smartJob.demoSpring.annotationBasedAutowiring; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Service; /** * Truy vấn dữ liệu. * * @author SmartJob */ @Service public class AccountServiceImpl implements AccountService { private AccountDAO accountDAO; @Autowired @Qualifier("accountDao") public void setAccountDao(AccountDAO accountDAO) { this.accountDAO = accountDAO; } /** * Giao dịch Chuyển tiền. * * @param sourceAccountId Tài khoản người gửi * @param targetAccountId Tài khoản người nhận * @param amount Số tiền chuyển khoản */ @Override public void transferMoney(long sourceAccountId, long targetAccountId, double amount) { Account sourceAccount = accountDAO.find(sourceAccountId); Account targetAccount = accountDAO.find(targetAccountId); sourceAccount.setBalance(sourceAccount.getBalance() - amount); targetAccount.setBalance(targetAccount.getBalance() + amount); accountDAO.update(sourceAccount); accountDAO.update(targetAccount); } @Override public void depositMoney(long accountId, double amount) throws Exception { Account account = accountDAO.find(accountId); account.setBalance(account.getBalance() + amount); accountDAO.update(account); } @Override public Account getAccount(long accountId) { return accountDAO.find(accountId); } }
File xml khai báo:
Tạo file beans.xml trong thư mục resources:
<?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.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd"> <context:component-scan base-package="vn.smartJob.demoSpring.annotationBasedAutowiring"/> </beans>
Ứng dụng chính:
package vn.smartJob.demoSpring.annotationBasedAutowiring; import org.springframework.context.support.ClassPathXmlApplicationContext; /** * Ứng dụng chuyển tiền. * * @author SmartJob */ public class App { public static void main(String[] args) { ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans.xml"); AccountService accountService = applicationContext.getBean("accountServiceImpl", AccountService.class); System.out.println("Trước khi chuyển tiền"); System.out.println("Số dư trong tài khoản Hoàng Thế Anh:" + accountService.getAccount(1).getBalance()); System.out.println("Số dư trong tài khoản Nguyễn Đức Hải:" + accountService.getAccount(2).getBalance()); // Hoàng Thế Anh chuyển cho Nguyễn Đức Hải 4 triệu 200 nghìn đồng. accountService.transferMoney(1, 2, 4200000.0); System.out.println("---------------------------------------------------"); System.out.println("Sau khi chuyển tiền"); System.out.println("Số dư trong tài khoản Hoàng Thế Anh:" + accountService.getAccount(1).getBalance()); System.out.println("Số dư trong tài khoản Nguyễn Đức Hải:" + accountService.getAccount(2).getBalance()); } } // Kết quả: //Trước khi chuyển tiền //Số dư trong tài khoản Hoàng Thế Anh:8000000.0 //Số dư trong tài khoản Nguyễn Đức Hải:4000000.0 //--------------------------------------------------- //Sau khi chuyển tiền //Số dư trong tài khoản Hoàng Thế Anh:3800000.0 //Số dư trong tài khoản Nguyễn Đức Hải:8200000.0
Dòng code 13 và 21 rất quan trọng, nó được highlight để bạn chú ý.
Download source code: annotation-based-autowiring . Bạn cũng có thể clone/fork từ Github: https://github.com/SmartJobVN/annotation-based-autowiring
Bài viết gốc được đăng tải tại smartjob.vn
Có thể bạn quan tâm:
- Kết nối ứng dụng Spring Framework với Cơ sở dữ liệu SQL
- Cho phép tùy chọn Giao diện trong Spring Web MVC framework
- Kiểm tra tính hợp lệ của dữ liệu đầu vào form Spring Web MVC bởi Hibernate Validator
Xem thêm Jobs IT for Developer hấp dẫn trên Station D
Bạn có thể quan tâm
- Tôi không phải là lập trình viên thực sự?(Công Nghệ)
- Vừa đủ để đi (go)(Công Nghệ)
- Principle thiết kế của các sản phẩm nổi tiếng(Công Nghệ)