1. Spring 框架
1.1 Spring 框架概述
- Spring 框架:一个开源的 Java 应用程序框架,提供了全面的基础设施支持,主要用于开发企业级应用程序。
- 核心功能:依赖注入(DI)、面向切面编程(AOP)、数据访问框架(JDBC、JPA)、MVC Web 应用程序开发。
1.2 依赖注入(DI)
-
概念:通过依赖注入,Spring 能够在运行时自动装配类的依赖对象,从而简化对象的创建和管理。
-
示例:
import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Main { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml"); HelloWorld helloWorld = (HelloWorld) context.getBean("helloWorld"); helloWorld.sayHello(); } } public class HelloWorld { private String message; public void setMessage(String message) { this.message = message; } public void sayHello() { System.out.println("Message: " + message); } }
<!-- beans.xml --> <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.xsd"> <bean id="helloWorld" class="com.example.HelloWorld"> <property name="message" value="Hello, Spring!"/> </bean> </beans>
1.3 面向切面编程(AOP)
-
概念:通过 AOP,可以将横切关注点(如日志记录、事务管理)从业务逻辑中分离出来。
-
示例:
import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; @Aspect public class LoggingAspect { @Before("execution(* com.example.HelloWorld.sayHello(..))") public void logBefore() { System.out.println("Logging before method execution"); } } public class Main { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml"); HelloWorld helloWorld = (HelloWorld) context.getBean("helloWorld"); helloWorld.sayHello(); } }
<!-- beans.xml --> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <bean id="helloWorld" class="com.example.HelloWorld"> <property name="message" value="Hello, Spring!"/> </bean> <bean id="loggingAspect" class="com.example.LoggingAspect"/> <aop:config> <aop:aspect ref="loggingAspect"> <aop:pointcut id="sayHelloPointcut" expression="execution(* com.example.HelloWorld.sayHello(..))"/> <aop:before method="logBefore" pointcut-ref="sayHelloPointcut"/> </aop:aspect> </aop:config> </beans>
2. Spring Boot
2.1 Spring Boot 概述
- Spring Boot:一个简化 Spring 应用程序开发的框架,提供了一种快速创建独立、生产级 Spring 应用的方式,开箱即用。
2.2 创建 Spring Boot 项目
-
示例:
import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } } @RestController public class HelloController { @GetMapping("/hello") public String hello() { return "Hello, Spring Boot!"; } }
<!-- 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>com.example</groupId> <artifactId>spring-boot-demo</artifactId> <version>1.0.0</version> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.5.4</version> </parent> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
3. RESTful Web 服务
3.1 RESTful API 概述
- REST(Representational State Transfer):一种架构风格,常用于构建基于 HTTP 的 Web 服务。
- RESTful API:符合 REST 架构风格的 API。
3.2 创建 RESTful Web 服务
- 示例:
import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.web.bind.annotation.*; import java.util.HashMap; import java.util.Map; @SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } } @RestController @RequestMapping("/api") public class UserController { private Map<Integer, String> users = new HashMap<>(); @GetMapping("/users") public Map<Integer, String> getUsers() { return users; } @PostMapping("/users") public String addUser(@RequestParam int id, @RequestParam String name) { users.put(id, name); return "User added successfully"; } @PutMapping("/users/{id}") public String updateUser(@PathVariable int id, @RequestParam String name) { users.put(id, name); return "User updated successfully"; } @DeleteMapping("/users/{id}") public String deleteUser(@PathVariable int id) { users.remove(id); return "User deleted successfully"; } }
4. 测试驱动开发 (TDD)
4.1 TDD 的概念
- 测试驱动开发(TDD):一种软件开发方法,通过编写测试用例来驱动代码的设计和开发。
- 红-绿-重构:TDD 的三个步骤:编写失败的测试(红),编写通过测试的代码(绿),重构代码(重构)。
4.2 使用 JUnit 进行单元测试
- 示例:
import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertEquals; public class CalculatorTest { @Test public void testAdd() { Calculator calculator = new Calculator(); int result = calculator.add(2, 3); assertEquals(5, result); } } public class Calculator { public int add(int a, int b) { return a + b; } }
4.3 使用 Spring Boot 测试
- 示例:
import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.web.client.TestRestTemplate; import org.springframework.http.ResponseEntity; import static org.junit.jupiter.api.Assertions.assertEquals; @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) public class HelloControllerTest { @Autowired private TestRestTemplate restTemplate; @Test public void testHello() { ResponseEntity<String> response = restTemplate.getForEntity("/hello", String.class); assertEquals("Hello, Spring Boot!", response.getBody()); } }
5. 数据访问
5.1 使用 Spring Data JPA
- 概念:Spring Data JPA 提供了一种便捷的方法来访问数据库,简化了数据访问层的实现。
- 示例:
import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; import org.springframework.web.bind.annotation.*; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import java.util.List; @SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } } @Entity public class User { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String name; // Getters and Setters public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } } @Repository public interface UserRepository extends JpaRepository<User, Long> {} @RestController @RequestMapping("/api/users") public class UserController { private final UserRepository userRepository; public UserController(UserRepository userRepository) { this.userRepository = userRepository; } @GetMapping public List<User> getAllUsers() { return userRepository.findAll(); } @PostMapping public User addUser(@RequestBody User user) { return userRepository.save(user); } @PutMapping("/{id}") public User updateUser(@PathVariable Long id, @RequestBody User user) { user.setId(id); return userRepository.save(user); } @DeleteMapping("/{id}") public void deleteUser(@PathVariable Long id) { userRepository.deleteById(id); } }
5.2 使用 Spring Data MongoDB
- 概念:Spring Data MongoDB 提供了一种便捷的方法来访问 MongoDB 数据库。
- 示例:
import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.data.mongodb.repository.MongoRepository; import org.springframework.stereotype.Repository; import org.springframework.web.bind.annotation.*; import java.util.List; @SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } } public class User { private String id; private String name; // Getters and Setters public String getId() { return id; } public void setId(String id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } } @Repository public interface UserRepository extends MongoRepository<User, String> {} @RestController @RequestMapping("/api/users") public class UserController { private final UserRepository userRepository; public UserController(UserRepository userRepository) { this.userRepository = userRepository; } @GetMapping public List<User> getAllUsers() { return userRepository.findAll(); } @PostMapping public User addUser(@RequestBody User user) { return userRepository.save(user); } @PutMapping("/{id}") public User updateUser(@PathVariable String id, @RequestBody User user) { user.setId(id); return userRepository.save(user); } @DeleteMapping("/{id}") public void deleteUser(@PathVariable String id) { userRepository.deleteById(id); } }
6. 消息队列
6.1 使用 RabbitMQ
- 概念:RabbitMQ 是一个开源的消息代理,用于实现消息队列、发布/订阅等消息传递模式。
- 示例:
import org.springframework.amqp.core.Queue; import org.springframework.amqp.rabbit.annotation.RabbitListener; import org.springframework.amqp.rabbit.core.RabbitTemplate; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.Bean; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } @Bean public Queue helloQueue() { return new Queue("hello"); } } @RestController public class ProducerController { private final RabbitTemplate rabbitTemplate; public ProducerController(RabbitTemplate rabbitTemplate) { this.rabbitTemplate = rabbitTemplate; } @GetMapping("/send") public String send() { rabbitTemplate.convertAndSend("hello", "Hello, RabbitMQ!"); return "Message sent!"; } } public class Receiver { @RabbitListener(queues = "hello") public void receive(String message) { System.out.println("Received: " + message); } }
7. 容器化和部署
7.1 使用 Docker 容器化 Spring Boot 应用
-
Dockerfile:
# Use an official OpenJDK runtime as a parent image FROM openjdk:11-jre-slim # Set the working directory WORKDIR /app # Copy the current directory contents into the container at /app COPY target/spring-boot-demo-0.0.1-SNAPSHOT.jar /app/spring-boot-demo.jar # Make port 8080 available to the world outside this container EXPOSE 8080 # Run the jar file ENTRYPOINT ["java", "-jar", "spring-boot-demo.jar"]
-
构建和运行 Docker 容器:
# 构建 Docker 镜像 docker build -t spring-boot-demo . # 运行 Docker 容器 docker run -p 8080:8080 spring-boot-demo
7.2 部署到 Kubernetes
-
Kubernetes 部署文件:
apiVersion: apps/v1 kind: Deployment metadata: name: spring-boot-demo spec: replicas: 2 selector: matchLabels: app: spring-boot-demo template: metadata: labels: app: spring-boot-demo spec: containers: - name: spring-boot-demo image: spring-boot-demo:latest ports: - containerPort: 8080 --- apiVersion: v1 kind: Service metadata: name: spring-boot-demo spec: type: LoadBalancer ports: - port: 80 targetPort: 8080 selector: app: spring-boot-demo
-
部署到 Kubernetes:
kubectl apply -f deployment.yaml
小结
- 本课学习了 Spring 框架和 Spring Boot 的基础知识,包括依赖注入、AOP 和快速开发应用。
- 介绍了如何创建 RESTful Web 服务,并进行测试驱动开发。
- 探讨了使用 Spring Data JPA 和 MongoDB 进行数据访问。
- 学习了如何使用 RabbitMQ 进行消息队列操作。
- 探讨了如何使用 Docker 容器化 Spring Boot 应用,并部署到 Kubernetes。
通过这些技术的学习,可以更好地开发、测试和部署现代 Java 应用程序。