@Component
1. 介绍
在项目开发过程中,我们自己编写的类如果想注入到Spring中,由Spring来管理Bean的生命周期,就可以使用@Component注解将其注入到IOC容器中。
@Component注解还有三个衍生注解,那就是@Repository、@Service和@Controller注解,并且衍生出的注解通常会在使用MVC架构开发项目时,标注到MVC架构的分层类上。
比如:@Repository通常会被标注到表示dao层的类上,@Service注解通常会被标注到表示Service层的类上,而@Controller注解通常会被标注到表示Controller层的类上。
2. 场景
在Spring开发项目的过程中,如果需要将自己创建的类注入到IOC容器中,就可以使用@Component注解,也可以使用@Repository、@Service和@Controller注解。
其中,@Component注解一般会被标注到非三层(非MVC架构)类上,而@Repository、@Service和@Controller注解通常会被标注到三层架构的类上。并且@Repository通常会被标注到表示dao层的类上,@Service注解通常会被标注到表示Service层的类上,而@Controller注解通常会被标注到表示Controller层的类上。
3. 源码
3.1 @Component源码
/**
* @author Mark Fisher
* @since 2.5
* @see Repository
* @see Service
* @see Controller
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Indexed
public @interface Component {
// 用于指定注入容器时Bean的id。如果没有指定Bean的id,默认值为当前类的名称
String value() default "";
}
3.2 @Repository源码
/**
* @author Rod Johnson
* @author Juergen Hoeller
* @since 2.0
* @see Component
* @see Service
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Repository {
@AliasFor(annotation = Component.class)
String value() default "";
}
3.3 @Service源码
/**
* @author Juergen Hoeller
* @since 2.5
* @see Component
* @see Repository
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Service {
@AliasFor(annotation = Component.class)
String value() default "";
}
3.4 @Controller源码
/**
* @author Arjen Poutsma
* @author Juergen Hoeller
* @since 2.5
* @see Component
* @see org.springframework.web.bind.annotation.RequestMapping
* @see org.springframework.context.annotation.ClassPathBeanDefinitionScanner
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Controller {
@AliasFor(annotation = Component.class)
String value() default "";
}
4. 补充
4.1 DAO && Service && Controller
DAO层 (Data Access Object)
- 定义:DAO层是专门用来处理数据访问的对象层。它的主要任务是从数据库获取数据、向数据库保存数据等操作。
- 职责:
- 封装了底层的数据存取逻辑。
- 提供了一种抽象方式来访问数据库中的数据,而不需要暴露具体的实现细节给上层服务。
- 通常会包含CRUD(创建(Create)、读取(Retrieve)、更新(Update)、删除(Delete))操作。
- 优点:提高了程序的可移植性和可测试性,通过更换不同的DAO实现即可支持多种数据库类型。
Service层
- 定义:服务层位于业务逻辑的核心,负责处理应用程序的主要业务逻辑。
- 职责:
- 实现业务规则。
- 可能涉及调用多个DAO层方法完成复杂的事务处理。
- 对于一些跨领域的需求,如日志记录、安全控制等,也可能在这里实现。
- 特点:保持业务逻辑与用户界面以及数据访问机制之间的隔离,使得逻辑更加清晰且易于修改。
Controller层
- 定义:控制器层作为前端请求的第一接触点,负责接收用户的输入,并根据这些输入决定调用哪个模型或服务来进行相应的处理。
- 职责:
- 处理HTTP请求并返回适当的响应。
- 调用适当的服务层方法执行业务逻辑。
- 根据业务逻辑的结果准备数据模型,并选择正确的视图模板进行渲染。
- 作用:充当客户端与服务器端其他部分之间的桥梁,确保只有合法的请求被转发到下一层处理。
在典型的分层结构中,一个请求可能首先到达Controller层,然后该层可能会调用Service层的方法来处理具体的业务逻辑。Service层可能会直接与DAO层交互,以便从数据库获取所需的数据或者保存更改。这样的设计使得各层之间相互独立,有利于软件开发过程中的模块化管理和后期维护。
4.2 Mybatis-Plus中的Mapper
在MyBatis-Plus框架中,Mapper
接口实际上扮演了类似于传统意义上的DAO(Data Access Object)层的角色。MyBatis-Plus是对MyBatis的一个增强工具包,在简化开发、提高效率的同时保持了MyBatis原有的强大功能。以下是关于MyBatis-Plus中的Mapper
与传统的DAO层之间关系的一些关键点:
- 定义和角色:
- 在MyBatis-Plus里,
Mapper
是直接面向数据库操作的接口。通过继承BaseMapper
接口或使用注解的方式,可以快速地创建一个能够进行基本CRUD操作的数据访问对象。
- 传统的DAO层同样是为了封装数据持久化逻辑而存在的,它通常包括了针对特定实体类的一系列数据库操作方法。
- 实现方式:
- MyBatis-Plus的
Mapper
利用了MyBatis提供的动态SQL支持,并结合了一些内置的优化措施来简化代码编写。开发者可以通过简单的配置或者继承BaseMapper
来获得强大的数据访问能力。
- 传统的DAO层可能需要手动编写更多的SQL语句以及处理结果集转换等细节工作,虽然更加灵活但也相对繁琐一些。
- 功能对比:
- MyBatis-Plus的
Mapper
提供了很多开箱即用的功能,比如分页查询、条件构造器等,这些都可以极大地减少开发者的工作量。
- DAO层则往往需要开发者自行实现所有所需的操作,这给定制化带来了更高的自由度,但同时也意味着更多的时间成本。
- 整合进应用架构:
- 使用MyBatis-Plus时,
Mapper
可以直接被Service层调用来执行具体的数据库操作。这种情况下,Mapper
就承担起了原本DAO层的责任。
- 如果你的项目已经存在明确划分出的DAO层,那么也可以选择让DAO层内部使用MyBatis-Plus的
Mapper
来进行数据访问,这样既保留了原有架构的优点,又享受到了MyBatis-Plus带来的便利。
总结来说,MyBatis-Plus中的Mapper
可以视为一种更为现代、高效的DAO实现形式。对于大多数应用场景而言,直接使用Mapper
作为数据访问层已经足够满足需求;但在某些特殊场景下,你仍然可以选择在Mapper
之上构建额外的DAO层以提供更复杂的业务逻辑封装。无论如何,合理利用MyBatis-Plus所提供的特性都能够帮助简化开发过程并提升工作效率。