Spring 核心注解深度解析教程


(涵盖 @Component/@Repository/@Service/@Controller/@Autowired/@Qualifier/@Resource/@Value


一、组件扫描与分层注解
1. @Component 基础组件标识
@Component // 通用组件标识
public class BasicComponent {
    // 会被Spring自动扫描并注册为Bean
}

特性

  • 所有组件注解的基类
  • 默认Bean名称为类名首字母小写(如 basicComponent
  • 需配合 @ComponentScan 使用
2. 分层特化注解
注解 应用场景 等效XML 特殊功能
@Repository 数据访问层(DAO) 自动转换JDBC异常为Spring异常
@Service 业务逻辑层(Service) 无特殊功能,语义化分层
@Controller 控制层(MVC Controller) 支持请求映射注解(如@RequestMapping

代码示例

@Repository // DAO层
public class UserDaoImpl implements UserDao {
    // 自动JDBC异常转换
}

@Service // Service层
public class UserServiceImpl implements UserService {
    // 业务逻辑代码
}

@Controller // MVC控制器层
public class UserController {
    @RequestMapping("/user")
    public String getUser() { ... }
}

二、依赖注入注解
1. @Autowired 自动装配

注入方式

  • 字段注入(不推荐)
@Service
public class UserService {
    @Autowired // 直接注入字段
    private UserDao userDao;
}
  • 构造器注入(推荐)
@Service
public class UserService {
    private final UserDao userDao;

    @Autowired // 构造器注入(Spring 4.3+ 可省略)
    public UserService(UserDao userDao) {
        this.userDao = userDao;
    }
}
  • Setter注入
@Service
public class UserService {
    private UserDao userDao;

    @Autowired
    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }
}

装配规则

  1. 按类型匹配(默认)
  2. 找到多个同类型Bean时,按 变量名匹配Bean名称
  3. 可通过 @Qualifier 指定具体Bean
2. @Qualifier 精确匹配
@Service
public class PaymentService {
    @Autowired
    @Qualifier("wechatPay") // 指定Bean名称
    private PaymentGateway paymentGateway;
}

@Component("wechatPay")
public class WechatPay implements PaymentGateway { ... }

@Component("alipay")
public class Alipay implements PaymentGateway { ... }
3. @Resource JSR-250 标准注入
@Service
public class OrderService {
    @Resource(name = "mysqlOrderDao") // 按名称注入
    private OrderDao orderDao;

    @Resource // 按类型注入(等效@Autowired)
    private PaymentService paymentService;
}

@Autowired 对比

特性 @Autowired @Resource
标准 Spring 专属 JSR-250 标准
默认行为 按类型注入 按名称注入
名称指定 需配合 @Qualifier 直接使用 name 属性

三、属性注入 @Value
1. 基本用法
@Component
public class DatabaseConfig {
    @Value("${jdbc.url}") // 注入属性值
    private String url;

    @Value("${jdbc.timeout:3000}") // 带默认值
    private int timeout;

    @Value("#{systemProperties['java.version']}") // SpEL表达式
    private String javaVersion;
}
2. 配置文件示例

application.properties

jdbc.url=jdbc:mysql://localhost:3306/mydb
jdbc.username=admin
3. 动态配置加载
@Configuration
@PropertySource("classpath:application.properties")
public class AppConfig {
    // 配合@Value使用
}

四、注解综合实战
场景:电商订单系统分层实现

1. 数据访问层

@Repository
public class OrderDaoImpl implements OrderDao {
    @Autowired // 注入数据源
    private DataSource dataSource;
    
    public Order findById(Long id) { ... }
}

2. 业务逻辑层

@Service
public class OrderServiceImpl implements OrderService {
    private final OrderDao orderDao;
    private final PaymentService paymentService;

    @Autowired // 构造器注入
    public OrderServiceImpl(OrderDao orderDao, 
                           @Qualifier("alipay") PaymentService paymentService) {
        this.orderDao = orderDao;
        this.paymentService = paymentService;
    }
}

3. 控制层

@Controller
public class OrderController {
    @Resource // 按名称注入
    private OrderService orderService;

    @Value("${order.maxLimit:100}") 
    private int maxLimit;

    @GetMapping("/order/{id}")
    public String getOrder(@PathVariable Long id) { ... }
}

五、常见问题排查
1. 注入失败的N种可能
  • NoSuchBeanDefinitionException
    • 原因:组件未被扫描到
    • 解决:检查 @ComponentScan 包路径
  • NoUniqueBeanDefinitionException
    • 原因:存在多个同类型Bean
    • 解决:使用 @Qualifier 指定Bean名称
2. 注解不生效的隐藏原因
  • 代理问题:在非Spring管理类中(如普通POJO)使用注解无效
  • 加载顺序@Value 在静态字段/方法中无法注入
  • 属性文件未加载:忘记添加 @PropertySource

六、最佳实践指南
  1. 分层规范
    • 严格遵循 @Controller@Service@Repository 分层结构
    • 禁止在DAO层使用 @Service
  2. 注入方式选择
    • 优先使用 构造器注入(强制依赖)
    • 可选依赖使用 Setter注入
  3. 命名规范
@Repository("userDaoImpl") // 明确指定Bean名称
public class UserDaoImpl { ... }
  1. 混合使用策略
@Autowired // 主要依赖
private OrderService orderService;

@Resource(name = "wechatPay") // 需要明确指定时
private PaymentGateway paymentGateway;

通过系统掌握这些注解,可减少 80% 的XML配置代码量,提升开发效率 50% 以上。实际开发中建议结合IDEA的Spring插件实时验证注解有效性。

你可能感兴趣的:(Java基础,spring,python,java)