277 lines
15 KiB
HTML
277 lines
15 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="zh-CN">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
<title>Spring Boot 学习中心</title>
|
||
<style>
|
||
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||
body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; background: #f5f5f5; }
|
||
.container { max-width: 1400px; margin: 0 auto; padding: 20px; }
|
||
|
||
.header { background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; padding: 40px 20px; text-align: center; margin-bottom: 30px; border-radius: 10px; }
|
||
.header h1 { font-size: 2.5em; margin-bottom: 10px; }
|
||
.header p { opacity: 0.9; font-size: 1.1em; }
|
||
|
||
.nav { display: flex; gap: 10px; margin-bottom: 30px; flex-wrap: wrap; justify-content: center; }
|
||
.nav a { padding: 12px 24px; background: white; border-radius: 25px; text-decoration: none; color: #333; font-weight: 500; transition: all 0.3s; border: 2px solid #e0e0e0; }
|
||
.nav a:hover, .nav a.active { background: #667eea; color: white; border-color: #667eea; }
|
||
|
||
.grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 20px; }
|
||
|
||
.card { background: white; border-radius: 15px; padding: 25px; box-shadow: 0 5px 20px rgba(0,0,0,0.08); transition: transform 0.3s; }
|
||
.card:hover { transform: translateY(-5px); }
|
||
.card h3 { color: #333; margin-bottom: 15px; font-size: 1.3em; }
|
||
.card p { color: #666; line-height: 1.6; margin-bottom: 15px; }
|
||
.card .btn { display: inline-block; padding: 10px 20px; background: #667eea; color: white; text-decoration: none; border-radius: 20px; font-size: 0.9em; }
|
||
.card .btn:hover { background: #5a6fd6; }
|
||
|
||
.feature-list { list-style: none; }
|
||
.feature-list li { padding: 8px 0; border-bottom: 1px solid #eee; }
|
||
.feature-list li:last-child { border-bottom: none; }
|
||
.feature-list .icon { margin-right: 8px; }
|
||
|
||
.api-test { background: #1e1e1e; border-radius: 10px; padding: 20px; margin-top: 20px; }
|
||
.api-test h4 { color: #4ec9b0; margin-bottom: 15px; }
|
||
.api-test pre { color: #d4d4d4; overflow-x: auto; font-size: 0.85em; }
|
||
.api-test .method { color: #569cd6; }
|
||
.api-test .url { color: #4ec9b0; }
|
||
|
||
.status { display: flex; gap: 20px; flex-wrap: wrap; margin-bottom: 30px; }
|
||
.status-item { background: white; padding: 20px 30px; border-radius: 10px; text-align: center; }
|
||
.status-item .value { font-size: 2em; font-weight: bold; color: #667eea; }
|
||
.status-item .label { color: #666; margin-top: 5px; }
|
||
.lab { background:#fff7e6; border:1px solid #ffe58f; border-radius:10px; padding:16px; margin-bottom:20px; }
|
||
.lab h4 { margin-bottom:8px; color:#ad6800; }
|
||
.lab ul { margin-left:18px; color:#444; line-height:1.7; }
|
||
|
||
footer { text-align: center; padding: 30px; color: #666; margin-top: 40px; }
|
||
</style>
|
||
</head>
|
||
<body>
|
||
<div class="container">
|
||
<div class="header">
|
||
<h1>🍃 Spring Boot 学习中心</h1>
|
||
<p>交互式学习 Spring 核心功能 | IoC · AOP · MyBatis · 事务</p>
|
||
</div>
|
||
|
||
<div class="status">
|
||
<div class="status-item">
|
||
<div class="value" id="beanCount">-</div>
|
||
<div class="label">已加载 Bean</div>
|
||
</div>
|
||
<div class="status-item">
|
||
<div class="value" id="userCount">-</div>
|
||
<div class="label">用户数量</div>
|
||
</div>
|
||
<div class="status-item">
|
||
<div class="value" id="productCount">-</div>
|
||
<div class="label">产品数量</div>
|
||
</div>
|
||
<div class="status-item">
|
||
<div class="value" id="orderCount">-</div>
|
||
<div class="label">订单数量</div>
|
||
</div>
|
||
<div class="status-item">
|
||
<div class="value" id="activeProfile">-</div>
|
||
<div class="label">当前 Profile</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="lab">
|
||
<h4>🧪 实验任务卡(事务模块)</h4>
|
||
<p style="margin-bottom:8px;color:#8c8c8c;">鉴权学习建议:learn=none(先学核心),advanced=jwt/satoken(再学安全链路)</p>
|
||
<ul>
|
||
<li>目标:理解事务回滚与 REQUIRES_NEW 差异</li>
|
||
<li>步骤1:到 transaction.html 创建普通订单(rollback=false)</li>
|
||
<li>步骤2:再创建模拟失败订单(rollback=true)</li>
|
||
<li>预期:主事务回滚,但独立事务可保留日志/部分数据(取决于实现)</li>
|
||
<li>观察点:查看控制台事务日志(TransactionInterceptor TRACE)</li>
|
||
</ul>
|
||
</div>
|
||
|
||
<div class="nav">
|
||
<a href="index.html" class="active">🏠 首页</a>
|
||
<a href="ioc.html">📦 IoC 容器</a>
|
||
<a href="aop.html">🔪 AOP 切面</a>
|
||
<a href="mybatis.html">💾 MyBatis</a>
|
||
<a href="transaction.html">🔄 事务管理</a>
|
||
<a href="users.html">👥 用户管理</a>
|
||
<a href="advanced.html">🚀 高级功能</a>
|
||
<a href="reflection.html">🪞 反射实验室</a>
|
||
<a href="auth-lab.html">🔐 鉴权实验室</a>
|
||
<a href="verify-lab.html">🩺 修复验证实验室</a>
|
||
<a href="api.html">🔌 API 测试</a>
|
||
</div>
|
||
|
||
<div class="grid">
|
||
<div class="card">
|
||
<h3>📦 IoC 容器</h3>
|
||
<p>理解 Spring 的核心:控制反转和依赖注入。学习 Bean 的生命周期、作用域和各种注入方式。</p>
|
||
<ul class="feature-list">
|
||
<li><span class="icon">✅</span>Bean 生命周期演示</li>
|
||
<li><span class="icon">✅</span>依赖注入方式对比</li>
|
||
<li><span class="icon">✅</span>Bean 作用域详解</li>
|
||
<li><span class="icon">✅</span>性能统计面板</li>
|
||
</ul>
|
||
<a href="ioc.html" class="btn">开始学习 →</a>
|
||
</div>
|
||
|
||
<div class="card">
|
||
<h3>🔪 AOP 切面编程</h3>
|
||
<p>掌握面向切面编程,实现日志、性能监控、事务等横切关注点的模块化管理。</p>
|
||
<ul class="feature-list">
|
||
<li><span class="icon">✅</span>5 种通知类型演示</li>
|
||
<li><span class="icon">✅</span>切入点表达式语法</li>
|
||
<li><span class="icon">✅</span>实时日志展示</li>
|
||
<li><span class="icon">✅</span>性能监控切面</li>
|
||
</ul>
|
||
<a href="aop.html" class="btn">开始学习 →</a>
|
||
</div>
|
||
|
||
<div class="card">
|
||
<h3>💾 MyBatis 集成</h3>
|
||
<p>学习 MyBatis 与 Spring Boot 的整合,对比 JPA,掌握动态 SQL 和缓存机制。</p>
|
||
<ul class="feature-list">
|
||
<li><span class="icon">✅</span>MyBatis vs JPA 对比</li>
|
||
<li><span class="icon">✅</span>动态 SQL 语法</li>
|
||
<li><span class="icon">✅</span>一级/二级缓存演示</li>
|
||
<li><span class="icon">✅</span>批量操作示例</li>
|
||
</ul>
|
||
<a href="mybatis.html" class="btn">开始学习 →</a>
|
||
</div>
|
||
|
||
<div class="card">
|
||
<h3>🔄 事务管理</h3>
|
||
<p>深入理解 Spring 声明式事务,掌握传播行为和隔离级别的实际应用。</p>
|
||
<ul class="feature-list">
|
||
<li><span class="icon">✅</span>事务传播行为</li>
|
||
<li><span class="icon">✅</span>事务隔离级别</li>
|
||
<li><span class="icon">✅</span>回滚机制演示</li>
|
||
<li><span class="icon">✅</span>订单创建场景</li>
|
||
</ul>
|
||
<a href="transaction.html" class="btn">开始学习 →</a>
|
||
</div>
|
||
|
||
<div class="card">
|
||
<h3>👥 用户管理 CRUD</h3>
|
||
<p>完整的 RESTful API 示例,演示增删改查操作和参数验证。</p>
|
||
<ul class="feature-list">
|
||
<li><span class="icon">✅</span>RESTful 设计规范</li>
|
||
<li><span class="icon">✅</span>参数验证</li>
|
||
<li><span class="icon">✅</span>异常处理</li>
|
||
<li><span class="icon">✅</span>交互式测试</li>
|
||
</ul>
|
||
<a href="users.html" class="btn">开始学习 →</a>
|
||
</div>
|
||
|
||
<div class="card">
|
||
<h3>🚀 高级功能</h3>
|
||
<p>Redis 缓存、分布式锁、多数据库、认证方案对比,从小白到高手的进阶之路。</p>
|
||
<ul class="feature-list">
|
||
<li><span class="icon">✅</span>Redis 数据类型操作</li>
|
||
<li><span class="icon">✅</span>缓存穿透/击穿/雪崩</li>
|
||
<li><span class="icon">✅</span>分布式锁实现</li>
|
||
<li><span class="icon">✅</span>JWT vs Sa-Token</li>
|
||
<li><span class="icon">✅</span>多数据库切换</li>
|
||
</ul>
|
||
<a href="advanced.html" class="btn">进阶学习 →</a>
|
||
</div>
|
||
|
||
<div class="card">
|
||
<h3>🪞 反射实验室</h3>
|
||
<p>动态查看类结构、通过构造器创建对象、修改私有字段、调用私有方法,理解 Spring 等框架底层为什么依赖反射。</p>
|
||
<ul class="feature-list">
|
||
<li><span class="icon">✅</span>类/字段/方法元信息</li>
|
||
<li><span class="icon">✅</span>反射构造对象</li>
|
||
<li><span class="icon">✅</span>私有字段修改</li>
|
||
<li><span class="icon">✅</span>公开/私有/静态方法调用</li>
|
||
</ul>
|
||
<a href="reflection.html" class="btn">开始实验 →</a>
|
||
</div>
|
||
|
||
<div class="card">
|
||
<h3>🔐 鉴权实验室</h3>
|
||
<p>一步步体验登录、带 Token 请求、鉴权放行/拦截,对比 learn / advanced 模式差异。</p>
|
||
<ul class="feature-list">
|
||
<li><span class="icon">✅</span>登录拿 Token</li>
|
||
<li><span class="icon">✅</span>自动携带 Authorization</li>
|
||
<li><span class="icon">✅</span>当前模式读取</li>
|
||
<li><span class="icon">✅</span>交互式错误观察</li>
|
||
</ul>
|
||
<a href="auth-lab.html" class="btn">开始实验 →</a>
|
||
</div>
|
||
|
||
<div class="card">
|
||
<h3>🩺 修复验证实验室</h3>
|
||
<p>自己点检查,不靠口头确认。直接验证 profile、H2、用户服务、MyBatis 和鉴权模式。</p>
|
||
<ul class="feature-list">
|
||
<li><span class="icon">✅</span>一键总览检查</li>
|
||
<li><span class="icon">✅</span>数据库链路验证</li>
|
||
<li><span class="icon">✅</span>用户服务验证</li>
|
||
<li><span class="icon">✅</span>MyBatis 查询验证</li>
|
||
</ul>
|
||
<a href="verify-lab.html" class="btn">开始验证 →</a>
|
||
</div>
|
||
|
||
<div class="card">
|
||
<h3>🔌 API 测试面板</h3>
|
||
<p>在线测试所有 API 接口,查看请求响应,理解 RESTful API 工作原理。</p>
|
||
<ul class="feature-list">
|
||
<li><span class="icon">✅</span>用户 API</li>
|
||
<li><span class="icon">✅</span>产品 API</li>
|
||
<li><span class="icon">✅</span>订单 API</li>
|
||
<li><span class="icon">✅</span>学习 API</li>
|
||
</ul>
|
||
<a href="api.html" class="btn">开始测试 →</a>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="api-test">
|
||
<h4>🚀 快速开始 - API 示例</h4>
|
||
<pre>
|
||
<span class="method">GET</span> <span class="url">/api/users</span> # 获取所有用户
|
||
<span class="method">GET</span> <span class="url">/api/users/{id}</span> # 获取单个用户
|
||
<span class="method">POST</span> <span class="url">/api/users</span> # 创建用户
|
||
<span class="method">PUT</span> <span class="url">/api/users/{id}</span> # 更新用户
|
||
<span class="method">DEL</span> <span class="url">/api/users/{id}</span> # 删除用户
|
||
|
||
<span class="method">GET</span> <span class="url">/api/learning/ioc/beans</span> # 查看所有 Bean
|
||
<span class="method">GET</span> <span class="url">/api/learning/aop/concepts</span> # AOP 概念
|
||
<span class="method">GET</span> <span class="url">/api/learning/mybatis/cache</span> # 缓存机制
|
||
<span class="method">GET</span> <span class="url">/api/learning/transaction/propagation</span> # 传播行为
|
||
</pre>
|
||
</div>
|
||
|
||
<footer>
|
||
<p>🍃 Spring Boot 学习脚手架 | <a href="/h2-console" target="_blank">H2 控制台</a> (learn 模式 JDBC: jdbc:h2:mem:springboot_scaffold_learn, 用户: sa)</p>
|
||
</footer>
|
||
</div>
|
||
|
||
<script>
|
||
// 加载状态数据
|
||
async function loadStatus() {
|
||
try {
|
||
const [beans, users, products, orders, profile] = await Promise.all([
|
||
fetch('/api/learning/ioc/beans').then(r => r.json()),
|
||
fetch('/api/users/count').then(r => r.json()),
|
||
fetch('/api/products').then(r => r.json()),
|
||
fetch('/api/orders').then(r => r.json()),
|
||
fetch('/api/profile').then(r => r.json())
|
||
]);
|
||
|
||
document.getElementById('beanCount').textContent = beans.total || '-';
|
||
document.getElementById('userCount').textContent = users.count || 0;
|
||
document.getElementById('productCount').textContent = products.length || 0;
|
||
document.getElementById('orderCount').textContent = orders.length || 0;
|
||
document.getElementById('activeProfile').textContent = profile.profile || '-';
|
||
} catch (e) {
|
||
console.error('加载状态失败:', e);
|
||
}
|
||
}
|
||
|
||
loadStatus();
|
||
setInterval(loadStatus, 30000);
|
||
</script>
|
||
</body>
|
||
</html> |