这是我参与8月更文挑战的第10天,活动详情查看:8月更文挑战
精彩干货索引
Hello,你好呀,我是灰小猿,一个超会写bug的程序猿!
《SSM编程日记》系列文章正在持续更新中,欢迎小伙伴们一起关注学习!
之前在文章中和大家讲解了有关Spring开发的基础入门,其中有讲到了在IOC中对bean对象的实例化和从IOC中如何获取相关对象的一系列操作!但是真正在进行开发的时候,**如果类比较多,那么再一个一个的添加并实例化中是不是就太麻烦了呢?想想就头秃...**今天就来教你如何高效的提升java开发效率!!!
优秀的程序员们怎么会没有想到这一点呢?所以针对于更加简洁开发的注解就出现了...
一、使用注解标识组件
为了不再在IOC中一个个的声明类对象,首先根据每一个类的功能的不同,Spring中先规定了基于组件的注解,大致可以分为以下四种:
①普通组件:@Component
标识一个受Spring IOC容器管理的组件,我们也可以理解为是除了数据库层、业务逻辑层、控制层组件以外的其他组件使用的注解。
②持久化层组件:@Respository
标识一个受Spring IOC容器管理的持久化层组件,一般就是用来标注数据库层
③业务逻辑层组件:@Service
标识一个受Spring IOC容器管理的业务逻辑层组件,
④表述层控制器组件:@Controller
标识一个受Spring IOC容器管理的表述层控制器组件。
同时这几个注解后面也可以添加一些参数,比如比较常用的一个是注解的括号中加value属性,来表示这个组件在容器中的ID,如果不设置value值时,默认的ID是类名的全称(第一个字母小写)。
**如下实例,**我们为一个Dao层组件添加一个@Respository注解
/**
* 数据库层注解
* */
@Repository
public class BookDao {
public void saveBook() {
System.out.println("bookDao中的图书已保存...");
}
}
通过这四个注解我们首先就可以将所有的组件逐一分类。置于为什么要使用注解进行分类,说到底其实就是为了方便方便快速的知道哪一个类是做了什么类型的功能,同时方便之后通过这四个注解将组件加入到IOC容器中。
所以你也可以把这四个注解理解为是Spring分发给不同功能组件的一个“身份证”,只有拥有这四种“身份证”,那么这个组件就可以被加入到IOC容器中。
**在这里有一点需要注意:****事实上Spring并没有能力识别一个组件到底是不是它所标记的类型,**即使将@Respository注解用在一个表述层控制器组件上面也不会产生任何错误,所以@Respository、@Service、@Controller这几个注解仅仅是为了让开发人员自己明确当前的组件扮演的角色。方便将组件加入到容器中去。
二、组件扫描
1、普通扫描
现在倒是对所有的组件进行了详细的分类,但是这样就等于将所有的组件已经加入到IOC容器中了嘛?如果真的是这样的话,那么我们就真正的实现了低代码时代了...
**所以现在我们就是应该如何将拥有注解标识的组件加入到IOC容器中呢?**在这里Spring在IOC中提供了一个包扫描的功能,通过这个名字我们就可以知道,Spring可以自动的扫描整个项目中被标记了这四个注解的组件,并且将其加入到IOC容器中。
进行包扫描的具体操作是这样的:
**进行包扫描依赖于Context名称空间,所以需要在IOC中加入该名称空间,加入名称空间的方法有两种,**一种是在IOC的头文件中加入如下代码:
xmlns:context="http://www.springframework.org/schema/context"
但是因为这种不好记所以不推荐,
还有一种就是直接在界面点击下方的Namespaces,在其中找到并勾选Context,
在容器中进行包扫描的代码是:
<context:component-scan base-package="com.spring"></context:component-scan>
**其中base-package属性指定一个需要扫描的基类包,Spring容器将会扫描这个基类包及其子包中的所有类。当需要扫描多个包时可以使用逗号分隔。**如上面的代码就是扫描com.spring包下面的所有类。
2、包含与排除特定组件
但是这样进行扫描的范围有时候未免还是有一些大,那么能不能再缩小进行包扫描的范围呢?当然是可以的。
**如果仅希望扫描特定的类而非基包下的所有类,可使用resource-pattern属性过滤特定的类,**如:
<context:component-scan base-package="com.atguigu.component" resource-pattern="autowire/*.class"/>
(1)扫描包含特定组件
**如果我们仅仅是想要扫描包含特定特征的组件,**那么我们可以如下方法:
context:include-filter子节点表示要包含的目标类
但是需要注意的是:由于context:component-scan默认是将所有的类全部都添加进去,所以在此基础上再添加是没有用的,需要在context:component-scan中加入属性参数use-default-filters,use-default-filters="true" 表示默认将所有的类都添加进去,false表示将所有的类都不添加进去,
如下代码表示仅仅扫描包含include-filter中所指特征的组件,其中的type用来表示使用何种类型的扫描表达式,expression后面跟表达式。
<context:component-scan base-package="com.spring" use-default-filters="false">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Repository"/>
</context:component-scan>
(2)扫描排除特定组件
尽然有扫描包含特定组件,那么就有扫描排除特定组件,
context:exclude-filter子节点表示要排除在外的目标类。
以下代码表示扫描除以下特征外的其他组件。
<context:component-scan base-package="com.spring">
<context:exclude-filter type="assignable" expression="com.spring.service.BookService"/>
</context:component-scan>
同时component-scan下可以拥有若干个include-filter和exclude-filter子节点,来表示可以包含多个哪种特征的组件或排除具有哪种特征的组件。
关于上面说到的type中填写的过滤表达式类型及作用如下表:
类别
示例
说明
annotation
com.atguigu.XxxAnnotation
过滤所有标注了XxxAnnotation的类。这个规则根据目标组件是否标注了指定类型的注解进行过滤。
assignable
com.atguigu.BaseXxx
过滤所有BaseXxx类的子类。这个规则根据目标组件是否是指定类型的子类的方式进行过滤。
aspectj
com.atguigu.*Service+
所有类名是以Service结束的,或这样的类的子类。这个规则根据AspectJ表达式进行过滤。
regex
com\.atguigu\.anno\.*
所有com.atguigu.anno包下的类。这个规则根据正则表达式匹配到的类名进行过滤。
custom
com.atguigu.XxxTypeFilter
使用XxxTypeFilter类通过编码的方式自定义过滤规则。该类必须实现org.springframework.core.type.filter.TypeFilter接口
最常用的上面两个,以下三个几乎不用:
type="aspectj" aspectj表达式
type="custom" 定义一个TypeFile,自己写一个类定义使用哪一个
type="regex" 利用正则表达式
****注意有bug:有些小伙伴们在进行注解开发的时候注解和扫描都写的很完美,可就是不起作用,原因可能是缺少相应特有的一个jar包,在这里需要导入额外的一个aop包
spring-aop-4.0.0.RELEASE.jar
到这里,将组件添加到容器中的操作就算是完成了,
在我们将组件添加成功之后呢,我们可以在组件图标的右上角看到一个小S的图标,这个时候就表示这个组件已经成功的加入到了容器中,
3、实现注解的三步骤
总结一下实现注解的三步骤:
- 添加context依赖
context:component-scan - 为类添加相应的注解
- 导入aop包
spring-aop-4.0.0.RELEASE.jar
- 导入aop包
五、写在最后
以上就是Spring注解开发的上一部分知识点了,是不是觉得使用注解开发比原生代码简洁多了,注解也是SSM框架乃至之后开发会经常用到的东西,
所以小伙伴们一定要认真学习,有问题可以直接私信我或留言评论。点赞收藏,肝起来!!!
我是灰小猿,我们下期见!