🚀 核心启动注解
@SpringBootApplication
SpringBoot应用的主注解,组合了多个核心注解
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
等价于:@Configuration + @EnableAutoConfiguration + @ComponentScan
@Configuration
标识配置类,替代传统的XML配置文件
@Configuration
public class AppConfig {
@Bean
public DataSource dataSource() {
return new HikariDataSource();
}
}
@EnableAutoConfiguration
启用SpringBoot的自动配置机制
@EnableAutoConfiguration
@ComponentScan
public class Application {
// 自动配置数据源、JPA等
}
@ComponentScan
指定组件扫描的包路径
@ComponentScan(basePackages = {
"com.example.controller",
"com.example.service"
})
public class Application {
}
package com.example.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
🌐 Web开发注解
@RestController
RESTful API控制器,自动将返回值序列化为JSON
@RestController
@RequestMapping("/api/users")
public class UserController {
@GetMapping("/{id}")
public User getUser(@PathVariable Long id) {
return userService.findById(id);
}
}
@Controller
传统MVC控制器,通常返回视图名称
@Controller
public class HomeController {
@GetMapping("/")
public String home(Model model) {
model.addAttribute("message", "Hello");
return "index"; // 返回视图名
}
}
@RequestMapping
映射HTTP请求到处理方法
@RequestMapping(
value = "/users",
method = RequestMethod.GET,
produces = "application/json"
)
public List<User> getUsers() {
return userService.findAll();
}
@GetMapping / @PostMapping
HTTP方法特定的映射注解
@GetMapping("/users/{id}")
public User getUser(@PathVariable Long id) {}
@PostMapping("/users")
public User createUser(@RequestBody User user) {}
@PutMapping("/users/{id}")
public User updateUser(@PathVariable Long id,
@RequestBody User user) {}
@DeleteMapping("/users/{id}")
public void deleteUser(@PathVariable Long id) {}
@PathVariable
绑定URL路径中的变量
@GetMapping("/users/{id}/orders/{orderId}")
public Order getUserOrder(
@PathVariable Long id,
@PathVariable Long orderId
) {
return orderService.findByUserAndId(id, orderId);
}
@RequestParam
绑定请求参数
@GetMapping("/users")
public List<User> getUsers(
@RequestParam(defaultValue = "0") int page,
@RequestParam(defaultValue = "10") int size,
@RequestParam(required = false) String name
) {
return userService.findUsers(page, size, name);
}
@RequestBody
绑定请求体中的JSON数据
@PostMapping("/users")
public User createUser(@RequestBody User user) {
return userService.save(user);
}
@PostMapping("/users/batch")
public List<User> createUsers(
@RequestBody List<User> users
) {
return userService.saveAll(users);
}
@ResponseBody
将返回值直接写入HTTP响应体
@Controller
public class ApiController {
@GetMapping("/api/data")
@ResponseBody
public Map<String, Object> getData() {
Map<String, Object> result = new HashMap<>();
result.put("status", "success");
return result;
}
}
@RestController
@RequestMapping("/api/users")
@CrossOrigin(origins = "*")
public class UserController {
@Autowired
private UserService userService;
@GetMapping
public ResponseEntity<List<User>> getAllUsers(
@RequestParam(defaultValue = "0") int page,
@RequestParam(defaultValue = "10") int size
) {
Page<User> users = userService.findAll(PageRequest.of(page, size));
return ResponseEntity.ok(users.getContent());
}
@GetMapping("/{id}")
public ResponseEntity<User> getUser(@PathVariable Long id) {
User user = userService.findById(id);
return user != null ?
ResponseEntity.ok(user) :
ResponseEntity.notFound().build();
}
@PostMapping
public ResponseEntity<User> createUser(@RequestBody @Valid User user) {
User savedUser = userService.save(user);
return ResponseEntity.status(HttpStatus.CREATED).body(savedUser);
}
@PutMapping("/{id}")
public ResponseEntity<User> updateUser(
@PathVariable Long id,
@RequestBody @Valid User user
) {
User updatedUser = userService.update(id, user);
return ResponseEntity.ok(updatedUser);
}
@DeleteMapping("/{id}")
public ResponseEntity<Void> deleteUser(@PathVariable Long id) {
userService.deleteById(id);
return ResponseEntity.noContent().build();
}
}
⚙️ 配置注解
@Value
注入配置文件中的属性值
@Component
public class AppConfig {
@Value("${app.name}")
private String appName;
@Value("${server.port:8080}")
private int serverPort;
@Value("#{systemProperties['java.home']}")
private String javaHome;
}
@ConfigurationProperties
批量绑定配置属性到Java对象
@ConfigurationProperties(prefix = "app.database")
@Component
public class DatabaseConfig {
private String url;
private String username;
private String password;
private int maxConnections;
// getter和setter方法
}
@Profile
指定Bean在特定环境下才生效
@Configuration
@Profile("development")
public class DevConfig {
@Bean
public DataSource dataSource() {
return new H2DataSource();
}
}
@Configuration
@Profile("production")
public class ProdConfig {
@Bean
public DataSource dataSource() {
return new MySQLDataSource();
}
}
@Conditional
条件化配置,满足条件时才创建Bean
@Configuration
public class ConditionalConfig {
@Bean
@ConditionalOnProperty(
name = "feature.cache.enabled",
havingValue = "true"
)
public CacheManager cacheManager() {
return new RedisCacheManager();
}
@Bean
@ConditionalOnMissingBean
public CacheManager defaultCacheManager() {
return new SimpleCacheManager();
}
}
@ConfigurationProperties(prefix = "app")
@Component
@Validated
public class AppProperties {
@NotBlank
private String name;
@Min(1)
@Max(65535)
private int port = 8080;
private Database database = new Database();
private List<String> allowedOrigins = new ArrayList<>();
public static class Database {
private String url;
private String username;
private String password;
private int maxConnections = 10;
}
}
app:
name: "My Spring Boot App"
port: 8080
database:
url: jdbc:mysql://localhost:3306/mydb
username: root
password: 123456
max-connections: 20
allowed-origins:
- http://localhost:3000
- https://example.com
❗ 常见问题解决
问题1:@Autowired注入失败
原因:Bean未被Spring管理或包扫描路径不正确
解决:检查@Component注解和@ComponentScan配置
问题2:循环依赖
原因:两个Bean相互依赖
解决:使用@Lazy注解或重构代码结构
问题3:@Value注入null
原因:配置文件中没有对应属性或格式错误
解决:检查配置文件和属性名称
💡 调试技巧
- 使用@PostConstruct验证Bean初始化
- 启用debug日志查看Bean创建过程
- 使用ApplicationContext.getBean()手动获取Bean
- 检查@Profile和@Conditional条件
🎯 最佳实践
注解使用原则:
- 优先使用构造器注入
- 合理使用@Profile区分环境
- 使用@ConfigurationProperties替代多个@Value
- 在Service层使用@Transactional
性能优化建议:
- 避免过度使用@Autowired
- 合理设置@Transactional的传播行为
- 使用@Lazy延迟加载非必需Bean
- 正确配置@ComponentScan范围
🏆 核心要点
SpringBoot注解是声明式编程的体现,理解每个注解的作用机制是掌握SpringBoot的关键