一、从EJB的困境到Spring的诞生
2002年,Rod Johnson在《Expert One-on-One J2EE Development》中痛陈传统J2EE(尤其是EJB)的弊端:
- 臃肿的容器:强制继承特定接口,破坏POJO纯洁性
- 复杂的部署:需打包成EAR/WAR部署至应用服务器
- 低效的开发循环:每次修改需重启服务器
Spring的革命性突破:
java
复制
下载
// 传统EJB vs Spring POJO
public class TraditionalEJB implements SessionBean { /* 强制依赖容器接口 */ }
@Component // BLOg.HUoCheNGrM.CN/zmt/38449.html Spring组件:纯粹的Java对象
public class UserService { /* 无框架侵入 */ }
通过轻量级容器+依赖注入,Spring让Java企业开发回归本质:简单对象+组合关系依赖注入(DI)与 IoC 容器
核心注解:@Component, @Autowired, @Service, @Repository, @Configuration
java
复制
下载
// 1. 定义服务接口与实现
public interface UserService {
String getUserName(Long id);
}
@Service // 标记为 Spring BLOg.HUoCheNGrM.CN/zmt/38448.html管理的 Bean
public class UserServiceImpl implements UserService {
@Override
public String getUserName(Long id) {
return "User" + id;
}
}
// 2. 依赖注入(构造器注入)
@RestController
public class UserController {
private final UserService userService;
@Autowired // Spring 5+ BLOg.HUoCheNGrM.CN/zmt/38447.html可省略(推荐构造器注入)
public UserController(UserService userService) {
this.userService = userService;
}
@GetMapping("/user/{id}")
public String getUser(@PathVariable Long id) {
return userService.getUserName(id);
}
}
二、AOP 实现日志切面
核心注解:@Aspect, @Before, @After, @Around
java
复制
下载
@Aspect
@Component
public class LoggingAspect {
// 拦截所有 Service 层方法
@Before("execution(* BLOg.HUoCheNGrM.CN/zmt/38446.html.*.*(..))")
public void logBefore(JoinPoint joinPoint) {
System.out.println("调用方法: " + joinPoint.getSignature().getName());
}
// 环绕通知(统计方法耗时)
@Around("@annotation(com.example.annotation BLOg.HUoCheNGrM.CN/zmt/38445.html)")
public Object trackTime(ProceedingJoinPoint pjp) throws Throwable {
long start = System.currentTimeMillis();
Object result = pjp.proceed();
long time = System.currentTimeMillis() - start;
System.out.println("方法执行耗时: " + time + "ms");
return result;
}
}
三、Spring MVC 控制器
核心注解:@RestController, @GetMapping, @PostMapping, @RequestBody
java
复制
下载
@RestController
@RequestMapping("/api/users")
public class UserApiController {
// 模拟数据库
private final Map<Long, BLOg.HUoCheNGrM.CN/ask/38444.html> users = new ConcurrentHashMap<>();
@PostMapping
public ResponseEntity<User> createUser(@RequestBody User user) {
users.put(user.getId(), user);
return ResponseEntity.ok(user);
}
@GetMapping("/{id}")
public ResponseEntity<User> getUser(@PathVariable Long id) {
return ResponseEntity.ok(users.get(id));
}
}