phase 5 part 4: java-spring awareness, k8s basics with validated manifests, run_examples supports single-file Java
This commit is contained in:
1 parent
075872e31e
commit
f695bbd7cc
18 files changed
+1192
-23
No files matched your search
@@ -0,0 +1,87 @@
|
||||
// Java 基础对照示例(不依赖 Spring,只用 JDK):record、接口 + 构造器注入、Optional、Stream、异常、并发
|
||||
// 运行(JDK 21+):java OrderDemo.java —— 单文件源码直接运行,不需要先 javac
|
||||
import java.math.BigDecimal;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class OrderDemo {
|
||||
// record:不可变数据类,自动生成构造器、getter、equals/hashCode/toString(类似 Go struct / Python dataclass(frozen))
|
||||
record Order(String id, String tenant, String status, BigDecimal amount) {}
|
||||
|
||||
// 接口 + 实现:Spring 中会用 @Repository 标注,由容器创建并注入
|
||||
interface OrderRepository {
|
||||
Optional<Order> findById(String id);
|
||||
List<Order> findByTenant(String tenant);
|
||||
}
|
||||
|
||||
static class InMemoryOrderRepository implements OrderRepository {
|
||||
private final Map<String, Order> data = new ConcurrentHashMap<>();
|
||||
InMemoryOrderRepository(List<Order> seed) { seed.forEach(o -> data.put(o.id(), o)); }
|
||||
public Optional<Order> findById(String id) { return Optional.ofNullable(data.get(id)); }
|
||||
public List<Order> findByTenant(String tenant) {
|
||||
return data.values().stream().filter(o -> o.tenant().equals(tenant)).toList();
|
||||
}
|
||||
}
|
||||
|
||||
static class NotFoundException extends RuntimeException {
|
||||
NotFoundException(String msg) { super(msg); }
|
||||
}
|
||||
|
||||
// 构造器注入:Spring 推荐的方式(@Service),依赖是 final 的,测试时可以直接传入假实现
|
||||
static class OrderService {
|
||||
private final OrderRepository repo;
|
||||
OrderService(OrderRepository repo) { this.repo = repo; }
|
||||
|
||||
Order get(String tenant, String id) {
|
||||
return repo.findById(id)
|
||||
.filter(o -> o.tenant().equals(tenant)) // 租户隔离:别的租户的订单当作不存在
|
||||
.orElseThrow(() -> new NotFoundException("订单不存在: " + id));
|
||||
}
|
||||
|
||||
Map<String, BigDecimal> sumByStatus(String tenant) { // Stream 分组汇总;金额用 BigDecimal,不用 double
|
||||
return repo.findByTenant(tenant).stream()
|
||||
.collect(Collectors.groupingBy(Order::status,
|
||||
Collectors.reducing(BigDecimal.ZERO, Order::amount, BigDecimal::add)));
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
var repo = new InMemoryOrderRepository(List.of(
|
||||
new Order("A001", "t1", "paid", new BigDecimal("19.90")),
|
||||
new Order("A002", "t1", "paid", new BigDecimal("0.10")),
|
||||
new Order("A003", "t1", "refunded", new BigDecimal("5.00")),
|
||||
new Order("B001", "t2", "paid", new BigDecimal("99.00"))));
|
||||
var service = new OrderService(repo);
|
||||
|
||||
check(service.get("t1", "A001").amount().equals(new BigDecimal("19.90")), "查询订单");
|
||||
try {
|
||||
service.get("t1", "B001");
|
||||
check(false, "跨租户应当查不到");
|
||||
} catch (NotFoundException e) {
|
||||
System.out.println("跨租户查询被拒绝: " + e.getMessage());
|
||||
}
|
||||
var sums = service.sumByStatus("t1");
|
||||
check(sums.get("paid").equals(new BigDecimal("20.00")), "BigDecimal 精确求和");
|
||||
System.out.println("t1 按状态汇总: " + new java.util.TreeMap<>(sums));
|
||||
System.out.println("用 double 计算金额的问题: 0.1 + 0.2 = " + (0.1 + 0.2));
|
||||
|
||||
// 并发:虚拟线程(JDK 21 正式特性)+ 原子计数,类比 Go 的 goroutine
|
||||
var counter = new AtomicInteger();
|
||||
try (ExecutorService pool = Executors.newVirtualThreadPerTaskExecutor()) {
|
||||
for (int i = 0; i < 1000; i++) pool.submit(counter::incrementAndGet);
|
||||
} // try-with-resources:等待全部任务完成
|
||||
check(counter.get() == 1000, "虚拟线程并发计数");
|
||||
System.out.println("1000 个虚拟线程计数结果: " + counter.get());
|
||||
System.out.println("全部检查通过");
|
||||
}
|
||||
|
||||
static void check(boolean ok, String name) {
|
||||
if (!ok) throw new AssertionError("检查失败: " + name);
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user