IOC容器讲解以及Spring依赖注入最佳实践全解析
IOC容器:
因为web开发讲解三层架构,所以@Controller注解是在控制层,@Service注解是在业务层,@Repository是对数据访问层。
在实际开发当中,有些类是不归属与这三层架构,例如工具类,像这种想要交给IOC容器的类,但是不属于三层架构里的就可以用@Component注解
DI详解:
基于字段的注入(属性注入)
直接在类的字段上使用@Autowired
注解,Spring容器会自动装配匹配的Bean。这种方式简洁但缺乏灵活性,且无法注入final
字段。
@Service
public class UserService { @Autowired private UserRepository userRepository;
}
基于构造方法的注入(构造方法注入)
在类的构造方法上使用@Autowired
注解(Spring 4.3+可省略),推荐用于强制依赖或final
字段。这种方式明确依赖关系,且便于单元测试。
@Service
public class UserService { private final UserRepository userRepository; @Autowired public UserService(UserRepository userRepository) { this.userRepository = userRepository; }
}
基于Setter方法的注入(Setter注入)
在Setter方法上使用@Autowired
注解,适合可选依赖或需要动态变更依赖的场景。灵活性高但可能掩盖设计问题。
@Service
public class UserService { private UserRepository userRepository; @Autowired public void setUserRepository(UserRepository userRepository) { this.userRepository = userRepository; }
}
解决 @Autowired
注入相同类型 Bean 冲突的方法
当使用 @Autowired
自动注入时,若存在多个相同类型的 Bean,我们可以使用以下是几种常见的方案解决:
使用 @Qualifier
注解指定 Bean 名称
通过 @Qualifier
注解明确指定需要注入的 Bean 名称,确保唯一性。
@Autowired
@Qualifier("beanName")
private MyService myService;
使用 @Primary
标记主 Bean
在多个同类型 Bean 中,标记其中一个为 @Primary
,Spring 会优先选择它。
@Bean
@Primary
public MyService primaryService() {return new MyServiceImpl();
}
通过 Bean 名称自动匹配
@Autowired
默认按类型匹配,但若字段名称与 Bean 名称一致,Spring 会尝试按名称匹配。
@Autowired
private MyService specificService; // 匹配名为 specificService 的 Bean
使用构造函数注入 + @Qualifier
构造函数注入结合 @Qualifier
更显式地指定 Bean。
private final MyService myService;public MyClass(@Qualifier("beanName") MyService myService) {this.myService = myService;
}
使用 @Resource
替代 @Autowired
@Resource
默认按名称匹配,可避免类型冲突。
@Resource(name = "beanName")
private MyService myService;