Spring笔记

依赖注入(Dependency Injection, DI)

想象一下你正在做一道菜,比如炒鸡蛋。这道菜的主要材料是鸡蛋和油。在做饭的过程中,你需要这两个材料来完成这道菜。

现在,如果我们把“炒鸡蛋”这个过程看作是一个“客户端”对象,那么“鸡蛋”和“油”就是它的依赖项。在传统的做法中,你可能会在炒鸡蛋的代码中直接写上如何获取鸡蛋和油(比如去冰箱里拿鸡蛋,从橱柜里拿油)。但这样做的话,你的炒鸡蛋过程就和获取鸡蛋、油的具体方式紧密地绑定在一起了。

依赖注入的做法就像是这样:你不再在炒鸡蛋的过程中去管鸡蛋和油是从哪里来的,你只需要告诉别人(比如你的助手或者一个智能厨房设备):“嘿,我需要鸡蛋和油来炒鸡蛋。” 然后,这个“别人”就会帮你准备好鸡蛋和油,并且在你开始炒鸡蛋的时候递给你。

在这个过程中,“别人”就扮演了依赖注入容器的角色,它负责创建和管理依赖项(鸡蛋和油),并在需要的时候将它们注入到客户端对象(炒鸡蛋的过程)中。

一、

在Spring框架中,@Autowired@Qualifier注解经常一起使用,以解决当Spring容器中存在多个相同类型的bean时,如何明确指定注入哪一个bean的问题。

  • @Autowired注解用于自动装配Spring容器中的bean。当Spring看到@Autowired注解时,它会尝试将标记了该注解的字段、setter方法或构造器参数与容器中的bean进行匹配,并自动注入相应的bean。如果没有找到匹配的bean,Spring会抛出异常(除非设置了@Autowired(required = false))。

  • @Qualifier注解用于指定注入bean的名称(或ID)。当存在多个相同类型的bean时,仅使用@Autowired可能不足以确定要注入哪一个bean,因为Spring无法区分它们。这时,可以通过@Qualifier注解来明确指定要注入的bean的名称。

  • @Autowired  
    @Qualifier("BookServiceImpl")  
    private BookService bookService;

这里,bookService字段被标记为自动装配,并且通过使用@Qualifier("BookServiceImpl")指定了要注入的bean的名称是BookServiceImpl。这意味着Spring将查找容器中名为BookServiceImplBookService类型的bean,并将其注入到bookService字段中。

这种方式特别有用,当你有多个实现了同一接口的bean,并且想要根据名称来选择注入哪一个时。例如,如果你有两个BookService的实现类,一个用于处理电子书,另一个用于处理纸质书,你可以通过为它们指定不同的名称(如eBookServiceImplpaperBookServiceImpl),并在需要时通过@Qualifier注解来指定注入哪一个。

二、

在Spring Boot中,将BookServiceImpl变成Bean(即让Spring容器管理BookServiceImpl的实例)通常非常直接,因为Spring Boot的自动配置特性会自动扫描并注册带有@Component@Service@Repository@Controller等注解的类作为Bean。

如果你的BookServiceImpl类实现了某个接口(比如BookService),并且你想要它作为一个Bean被Spring容器管理,你可以简单地在BookServiceImpl类上添加@Service注解(或者@Component,但@Service更具体地表示这是一个服务层组件)。

// 假设你有一个BookService接口  
public interface BookService {  
    // 定义一些方法  
    void addBook(Book book);  
    List<Book> getAllBooks();  
    // ... 其他方法  
}  
  
// BookServiceImpl实现了BookService接口,并且被@Service注解标记为Spring Bean  
@Service("bookServiceImpl") // 注意:这里的"bookServiceImpl"是bean的名称,是可选的  
public class BookServiceImpl implements BookService {  
    // 实现接口中的方法  
    @Override  
    public void addBook(Book book) {  
        // 实现添加书籍的逻辑  
    }  
  
    @Override  
    public List<Book> getAllBooks() {  
        // 实现获取所有书籍的逻辑  
        return new ArrayList<>(); // 示例返回空列表  
    }  
    // ... 其他方法的实现  
}

在这个例子中,@Service注解告诉Spring这个类是一个服务层组件,应该被注册为一个Bean。"bookServiceImpl"是该Bean的名称,但它是可选的。如果你不提供名称,Spring将使用类的简单名称(首字母小写)作为Bean的名称,即在这个例子中默认名称将是bookServiceImpl(注意Spring会自动将首字母小写)。

一旦BookServiceImpl被注册为Bean,你就可以在Spring容器中的其他地方通过自动装配(比如使用@Autowired注解)来注入它了。

@RestController  
public class BookController {  
  
    @Autowired  
    private BookService bookService; // Spring将自动注入名为"bookServiceImpl"的Bean  
  
    // ... 其他代码  
}

在这个BookController中,我们使用了@Autowired注解来自动装配BookService类型的Bean。由于Spring容器中只有一个BookService类型的Bean(即BookServiceImpl),所以Spring会自动将其注入到bookService字段中。如果你提供了Bean的名称(如上面的"bookServiceImpl"),并且需要明确指定注入哪个Bean,你可以使用@Qualifier注解,但在这个例子中它是不必要的。

在Spring框架中,@Mapper@Repository注解虽然都用于标记Spring容器中的Bean,但它们各自有不同的用途和适用场景。然而,在实际应用中,特别是在使用MyBatis作为ORM框架的Spring Boot项目中,这两个注解经常一起出现,但它们的意义和作用有所不同。

@Mapper

@Mapper注解是MyBatis提供的,用于标记MyBatis的Mapper接口。当Spring Boot项目集成了MyBatis时,Spring Boot会自动扫描带有@Mapper注解的接口,并将它们注册为Bean,以便在需要时注入到其他组件中。这样,你就可以在Service层或其他地方通过自动装配来使用这些Mapper接口了。

@Repository

@Repository注解是Spring框架提供的,用于标记在数据访问层(DAO层)的类上。虽然它本身并不提供特别的功能(除了将类标记为Spring管理的Bean之外),但它主要用于向Spring表明该类是一个DAO组件,用于访问数据库。此外,@Repository注解还允许Spring在运行时捕获数据访问异常,并将它们转换为Spring的DataAccessException异常,这是Spring数据访问异常层次结构中的根异常。

一起使用

在Spring Boot项目中,当你使用MyBatis作为ORM框架时,你可能会看到@Mapper@Repository注解一起使用在Mapper接口上。虽然这在实际中并不常见(因为@Mapper已经足够将Mapper接口注册为Bean了),但这样做有一些潜在的好处:

  1. 语义清晰@Repository注解明确指出了这是一个数据访问层的组件,有助于代码的可读性和维护性。
  2. 异常转换:如前所述,@Repository注解允许Spring捕获并转换数据访问异常。

然而,需要注意的是,在Spring Boot项目中,如果你已经配置了MyBatis的自动扫描(比如通过@MapperScan注解),那么通常不需要在Mapper接口上显式地添加@Mapper@Repository注解。Spring Boot会自动识别并注册这些Mapper接口为Bean。

结论

在大多数情况下,对于MyBatis的Mapper接口,你只需要使用@Mapper注解(或者通过配置来自动扫描Mapper接口)。然而,如果你想要更明确地表明这些接口是数据访问层的组件,并且希望利用@Repository注解提供的异常转换功能,那么你可以将这两个注解一起使用。但在实践中,这通常不是必需的。

  • 11
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值