Week 1-8: Spring Boot 学习计划完整项目

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-04-29 23:45:17 +08:00
commit f95aa18724
201 changed files with 18595 additions and 0 deletions

View File

@@ -0,0 +1,164 @@
package com.learn.ioc;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;
/**
* 第 1 天:手写简易 IoC 容器 —— 理解控制反转的本质
*
* 核心概念:
* IoCInversion of Control把"创建对象"的控制权从程序员手里
* 交给容器。以前是 new 一个对象,现在是容器帮我们创建并注入。
*
* DIDependency Injection依赖注入IoC 最常见的实现方式。
* 当 A 类需要 B 类时,不需要 A 自己 new B而是由容器把 B 注入到 A 中。
*
* 这个类是一个极简 IoC 容器实现,只依赖 JDK用于理解 Spring 的核心思想。
*
* 运行方式IDEA 中右键此类 → Run 'SimpleIocDemo.main()'
*/
public class SimpleIocDemo {
// ==================== 1. 定义两个简单的"业务类" ====================
/** 模拟一个"数据访问层"组件 */
static class UserRepository {
public String findUser() {
return "张三(来自数据库)";
}
}
/** 模拟一个"业务逻辑层"组件 —— 它依赖 UserRepository */
static class UserService {
// UserService 需要 UserRepository但自己不 new
private UserRepository userRepository;
// 通过 setter 方法接收依赖(这就是"注入"
public void setUserRepository(UserRepository userRepository) {
this.userRepository = userRepository;
}
public String getUserInfo() {
return userRepository.findUser();
}
}
// ==================== 2. 极简 IoC 容器 ====================
/**
* 一个玩具级 IoC 容器,实现两个能力:
* 1. 注册 Bean把对象放进容器
* 2. 注入依赖(帮对象建立关联关系)
*/
static class SimpleContainer {
// 存储所有 Bean名字 → 对象
private final Map<String, Object> beans = new HashMap<>();
/** 注册一个 Bean */
public void register(String name, Object bean) {
beans.put(name, bean);
}
/** 获取一个 Bean */
public Object getBean(String name) {
return beans.get(name);
}
/**
* 自动注入:扫描每个 Bean 中带 @Autowired 注解的字段,自动赋值
* (这里用我们自定义的注解来模拟 Spring 的 @Autowired
*/
public void autowire() {
for (Object bean : beans.values()) {
for (Field field : bean.getClass().getDeclaredFields()) {
if (field.isAnnotationPresent(MyAutowired.class)) {
field.setAccessible(true);
try {
// 根据字段类型找到匹配的 Bean
Object dependency = findBeanByType(field.getType());
if (dependency != null) {
field.set(bean, dependency);
}
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}
}
}
}
private Object findBeanByType(Class<?> type) {
for (Object bean : beans.values()) {
if (type.isAssignableFrom(bean.getClass())) {
return bean;
}
}
return null;
}
}
// ==================== 3. 自定义注解(模拟 Spring 的 @Autowired ====================
@java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME)
@interface MyAutowired {
}
// ==================== 4. 使用注解版本测试自动注入 ====================
static class OrderRepository {
public String getOrder() {
return "订单 #12345";
}
}
static class OrderService {
@MyAutowired // 告诉容器:帮我把 OrderRepository 注入进来
private OrderRepository orderRepository;
public String getOrderInfo() {
return orderRepository.getOrder();
}
}
// ==================== 5. 主方法——跑起来看效果 ====================
public static void main(String[] args) {
System.out.println("========== IoC 容器原理演示 ==========\n");
// --- 方式一:手动注入(模拟 XML 配置时代的做法) ---
System.out.println("--- 方式一:手动 setter 注入 ---");
SimpleContainer container1 = new SimpleContainer();
UserRepository userRepo = new UserRepository();
UserService userService = new UserService();
container1.register("userRepository", userRepo);
container1.register("userService", userService);
// 手动注入依赖
userService.setUserRepository(userRepo);
UserService service1 = (UserService) container1.getBean("userService");
System.out.println("调用结果: " + service1.getUserInfo());
// --- 方式二:自动注入(模拟注解时代的做法) ---
System.out.println("\n--- 方式二:注解自动注入 ---");
SimpleContainer container2 = new SimpleContainer();
container2.register("orderRepository", new OrderRepository());
container2.register("orderService", new OrderService());
// 一行代码,自动完成所有依赖注入
container2.autowire();
OrderService service2 = (OrderService) container2.getBean("orderService");
System.out.println("调用结果: " + service2.getOrderInfo());
// --- 对比总结 ---
System.out.println("\n========== 总结 ==========");
System.out.println("没有 IoC 容器时A a = new A(); a.setB(new B()); // 自己控制一切");
System.out.println("有了 IoC 容器后:@Autowired B b; // 容器自动注入,你只管用");
System.out.println("\n这就是 Spring 的核心理念——控制反转!");
}
}