Hướng dẫn lập trình Spring cho người mới bắt đầu
Công ty Vĩnh Cửu tuyển dụng lập trình viên Java

1- Giới thiệu

Tài liệu này viết dựa trên:
  • Spring Framework 4.x

  • Eclipse 4.6 NEON (ok for Eclipse 4.5 MARS)

Document History:
  • 15-05-2014: Based on Eclipse 4.4 LUNA + Spring 4.0.4 + Download Spring Library
  • 15-07-2015: Based on Eclipse 4.5 MARS + Spring 4.0.4 + Using Maven.
  • 17-09-2016: Based on Eclipse 4.6 NEON + Spring 4.0.4 + Using Maven + Annotation Config.
Trong tài liệu này tôi sử dụng Maven để khai báo các thư viện Spring sẽ sử dụng, thay vì download Spring và khai báo thư viện theo cách thông thường.

Maven là một công cụ giúp bạn quản lý các thư viện một cách tự động và hiệu quả, và nó đã trở thành thông dụng mà bất cứ một lập trình viên Java nào đều phải biết. Nếu bạn chưa biết về Maven bạn có thể bỏ ra 10 phút để học về cách sử dụng tại đây:
Trong trường hợp bạn muốn download Spring và khai báo thư viện theo cách truyền thống bạn có thể xem phụ lục ở phía cuối tài liệu.

2- Spring Framework

Hình minh họa dưới đây mô tả cấu trúc của Spring Framework.
  1. IoC Container: Đây là phần quan trọng nhất và cũng là phần cơ bản, nền tảng của Spring. Nó giữ vai trò về cấu hình và quản lý lifecycle của các java object. Bài hôm nay chúng ta sẽ tìm hiểu về phần này.
  2. DAO, ORM, AOP, WEB: Các module này là tool hoặc là framework có sẵn được tích hợp vào Spring.

3- Tạo Maven project

  • File/New/Other...
Nhập vào:
  • Group Id: org.o7planning
  • Artifact Id: HelloSpringAnnotation
  • package: org.o7planning.spring
Project của bạn đã được tạo ra:
Đảm bảo rằng Project của bạn được build trên Java 7 hoặc mới hơn. Nhấn phải chuột vào project chọn Properties.

4- Khai báo các thư viện Spring cơ bản

Đây là ví dụ HelloWorld Spring, vì vậy chúng ta chỉ sử dụng thư viện Spring cơ bản (Core). Mở file pom.xml khai báo các thư viện sẽ sử dụng:
pom.xml
<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/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>org.o7planning</groupId>
  <artifactId>HelloSpringAnnotation</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>jar</packaging>

  <name>HelloSpringAnnotation</name>
  <url>http://maven.apache.org</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>

    <dependencies>

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>3.8.1</version>
            <scope>test</scope>
        </dependency>

        <!-- Spring Core -->
        <!-- http://mvnrepository.com/artifact/org.springframework/spring-core -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>4.1.4.RELEASE</version>
        </dependency>

        <!-- Spring Context -->
        <!-- http://mvnrepository.com/artifact/org.springframework/spring-context -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>4.1.4.RELEASE</version>
        </dependency>

    </dependencies>
 
</project>

5- Code Project

Dưới đây là hình minh họa cấu trúc của project:
Language.java
package org.o7planning.spring.lang;

// A Language
// Một ngôn ngữ
public interface Language {

    // Get a greeting
    // Một lời chào
    public String getGreeting();

    // Get a bye
    // Một lời tạm biệt
    public String getBye();

}
English.java
package org.o7planning.spring.lang.impl;

import org.o7planning.spring.lang.Language;

// Tiếng anh
public class English  implements Language {

  @Override
  public String getGreeting() {
      return "Hello";
  }

  @Override
  public String getBye() {
      return "Bye bye";
  }
 

}
Vietnamese.java
package org.o7planning.spring.lang.impl;

import org.o7planning.spring.lang.Language;

// Tiếng Việt
public class Vietnamese implements Language {

  @Override
  public String getGreeting() {
      return "Xin Chao";
  }

  @Override
  public String getBye() {
      return "Tam Biet";
  }

}
@Service là một annotation, nó được sử dụng để chú thích trên một class để nói với Spring rằng class đó là một Spring BEAN.

@Autowired được chú thích trên một trường (field) để nói với Spring rằng hãy tiêm (inject) giá trị vào cho trường đó. Chú ý: Từ tiêm ở đây có ý giống với gán giá trị cho trường đó.
 
GreetingService.java
package org.o7planning.spring.bean;

import org.o7planning.spring.lang.Language;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class GreetingService {

   @Autowired
   private Language language;

   public GreetingService() {

   }

   public void sayGreeting() {
       
       String greeting = language.getGreeting();

       System.out.println("Greeting: " + greeting);
   }

}
@Repository là một annotation, nó được sử dụng để chú thích trên một class để nói với Spring rằng class này là một Spring BEAN.
 
MyRepository.java
package org.o7planning.spring.bean;

import java.util.Date;

import org.springframework.stereotype.Repository;

@Repository
public class MyRepository {

    public String getAppName() {
        return "Hello Spring App";
    }

    public Date getSystemDateTime() {
        return new Date();
    }
    
    
}
@Component là một annotation, nó được chú thích trên một class để nói với Spring rằng class này là một Spring BEAN.

@Autowired được chú thích trên một trường (field) để nói với Spring rằng hãy tiêm (inject) giá trị vào cho trường đó. Chú ý: Từ tiêm ở đây có ý giống với gán giá trị cho trường đó.
MyComponent
package org.o7planning.spring.bean;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class MyComponent {
   
    @Autowired
    private MyRepository repository;

    public void showAppInfo() {
        System.out.println("Now is: "+ repository.getSystemDateTime());
        System.out.println("App Name: "+ repository.getAppName());
    }

}
Không có sự khác biệt về cách sử dụng của @Service, @Component@Repository, bạn sử dụng để chú thích trên các class của bạn nên phù hợp với ý nghĩa và ngữ cảnh trong ứng dụng.

6- Spring @Configuration & IoC

@Configuration là một annotation, nó được chú thích trên một class, class này sẽ định nghĩa các Spring BEAN.

@ComponentScan - Nói cho Spring các package để tìm kiếm các Spring BEAN khác, Spring sẽ quét (scan) các package đó để tìm kiếm.
AppConfiguration.java
package org.o7planning.spring.config;

import org.o7planning.spring.lang.Language;
import org.o7planning.spring.lang.impl.Vietnamese;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration
@ComponentScan({"org.o7planning.spring.bean"})
public class AppConfiguration {

    @Bean(name ="language")
    public Language getLanguage() {

        return new Vietnamese();
    }
     
}
Các Spring BEAN được tạo ra sẽ được quản lý trong Spring IoC Container (Bộ chứa Spring IoC).

7- Spring ApplicationContext

MainProgram.java
package org.o7planning.spring;

import org.o7planning.spring.bean.GreetingService;
import org.o7planning.spring.bean.MyComponent;
import org.o7planning.spring.config.AppConfiguration;
import org.o7planning.spring.lang.Language;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class MainProgram {

   public static void main(String[] args) {
 
     
       // Tạo ra một đối tượng ApplicationContext bằng cách đọc cấu hỉnh
       // trong class AppConfiguration
       ApplicationContext context = new AnnotationConfigApplicationContext(AppConfiguration.class);

       System.out.println("----------");
       Language language = (Language) context.getBean("language");
     
       System.out.println("Bean Language: "+ language);
       System.out.println("Call language.sayBye(): "+ language.getBye());
     
       System.out.println("----------");
     
       GreetingService service = (GreetingService) context.getBean("greetingService");
 

       service.sayGreeting();
 
       System.out.println("----------");
     
       MyComponent myComponent = (MyComponent) context.getBean("myComponent");
     
       myComponent.showAppInfo();
     
   }
 
}
Chạy class MainProgram
Kết quả:

8- Nguyên tắc hoạt động của Spring

Bạn tạo một đối tượng ApplicationContext bằng cách đọc các cấu hình trong class AppConfiguration, giống như đoạn code dưới đây.
ApplicationContext context = new AnnotationConfigApplicationContext(AppConfiguration.class);
Spring sẽ tạo các Spring BEAN, theo các định nghĩa trong class AppConfiguration, (Chú ý: Class AppConfiguration phải được chú thích bởi @Configuration).
Tiếp theo Spring sẽ tìm kiếm trong package "org.o7planning.spring.bean" để tạo các Spring BEAN khác, (Tạo các đối tượng từ các class được chú thích bởi @Service, @Component hoặc @Repository).
Lúc này các Spring BEAN đã được tạo ra, và được chứa trong Spring IoC. Các trường của các Spring BEAN có chú thích bởi @Autowired sẽ được tiêm các giá trị vào, giống hình minh họa dưới đây:
Trở về với câu hỏi "IoC là gì?".
Theo cách truyền thống một đối tượng được tạo ra từ một class, các trường (field) của nó sẽ được gán giá trị từ chính bên trong class đó. Spring đã làm ngược lại với cách truyền thống, các đối tượng được tạo ra và một vài trường của nó được tiêm giá trị từ bên ngoài vào bởi một đối tượng được gọi là IoC.

IoC viết tắt của "Inversion of Control" - Có nghĩa là "Đảo ngược của sự điều khiển".

IoC Container là bộ chứa tất cả các Spring BEAN được sử dụng trong ứng dụng.

9- Lập trình ứng dụng Web sử dụng Spring MVC

Tiếp theo bạn có thể tìm hiểu lập trình ứng dụng web với Spring MVC:

10- Phụ lục: Download thư viện Spring

Bạn có thể download Spring tại địa chỉ:
Giải nén file zip vừa download được vào một thư mục ổ cứng: