关于spring:关于Spring注解开发教程打包全送你

1次阅读

共计 5967 个字符,预计需要花费 15 分钟才能阅读完成。

摘要:spring 是咱们 web 开发中必不可少的一个框架,基于传统的 xml 形式配置 bean 总感觉太过繁琐,从 spring2.5 之后注解的呈现能够大大简化咱们的配置。

本文分享自华为云社区《如何高效晋升 Java 开发效率—Spring 注解开发全套教程!》,作者:灰小猿。

一、应用注解标识组件

为了不再在 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 中填写的过滤表达式类型及作用如下表:

最罕用的下面两个,以下三个简直不必:

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

三、组件主动拆卸

然而这样就完结了嘛?就这么轻松了嘛?之前学习的 bean 的作用域与生命周期这些都没用了嘛?当然不是!!!更重要的是组件还没获取呢!!!

那么接下来就来和大家讲一下应用注解开发的高端操作,让你晓得应用注解是如许的香!!!

咱们平时在应用类的时候,难免会在类中调用其余自定义的类对吧,就比如说,Controller 组件中往往须要用到 Service 组件的实例,Service 组件中往往须要用到 Repository 组件的实例。

那么如果咱们对这些须要实例化的组件一个一个的在类中进行实例化,是不是就显得太麻烦了呢?哎,聪慧机智的程序员们怎么会没有想到这一点呢!所以组件的主动拆卸就呈现了,​

在 spring 中咱们能够通过注解的模式来对组件进行主动的拆卸,那么到底如何对组件进行拆卸的呢?

其实是这样的,在 IOC 中指定要扫描的包时,<context:component-scan> 元素会主动注册一个 bean 的后置处理器:AutowiredAnnotationBeanPostProcessor 的实例。该后置处理器能够主动拆卸标记了 @Autowired、@Resource 或 @Inject 注解的属性。

而下面的 @Autowired、@Resource 或 @Inject 这三个注解,就是咱们在进行组件的主动拆卸时最罕用的注解,

上面我和大家介绍一下这三种注解的具体应用。

1、@autowired 注解

@autowired 注解可能依据类型实现主动拆卸。无论是结构器、一般字段 (即便是非 public)、还是所有具备参数的办法都能够利用 @Autowired 注解

默认状况下,所有应用 @Autowired 注解的属性都须要被设置。当 Spring 找不到匹配的 bean 拆卸属性时,会抛出异样。

(1)@autowired 拆卸原理

接下里我来和大家具体的讲一下 @autowired 注解的拆卸原理:

1、应用主动拆卸时,首先会依据类型去容器中查找相应的组件,这就相似于

getBean("bookService.class"),
2、如果没有找到就抛异样,如果找到一个就赋值

3、如果找到多个,那么也是有肯定的拆卸根据的,并不是轻易找一个进行拆卸。

首先依据属性名作为 ID 进行持续寻找,找到对应属性名的组件就进行拆卸,没有找到就报错, 报错的起因是:应用变量名作为 id 进行匹配时候,没有找到对应的属性名

(2)@Qualifier 指定拆卸 ID

对于这种报错其实还有一种解决:就是应用 @Qualifier(“bookService”) 指定查找 ID,找到就拆卸,找不到报错,指定查找 ID 的代码示例如下:

// 增加注解示意主动装填
@Autowired
@Qualifier("bookdao")
private BookDao bookDao;

(3)required—拆卸报错解决

那么要是每次找不到就报错,这样程序不是就崩了吗?对于这样的状况应该怎么办呢?其实还有一种解决办法,解决找不到报错:应用 required 参数,

@Autowired(required=false) required=false 示意如果切实找不到,就拆卸 null

反正拆卸的根据就是,依照多种规定查找适合的拆卸对象,直到查找胜利,切实不胜利就返回 null。

(4)非凡属性的主动拆卸

下面是应用 @Autowired 注解的基本原理与步骤,咱们直到 spring 的注解开发是非常弱小的,上面咱们再来说几个非凡的属性的拆卸。

@Autowired 注解能够利用在数组类型的属性上,此时 Spring 将会把所有匹配的 bean 进行主动拆卸。

@Autowired 注解也能够利用在汇合属性上,此时 Spring 读取该汇合的类型信息,而后主动拆卸所有与之兼容的 bean。

@Autowired 注解用在 java.util.Map 上时,若该 Map 的键值为 String,那么 Spring 将主动拆卸与值类型兼容的 bean 作为值,并以 bean 的 id 值作为键。

这样一来,@Autowired 注解的主动拆卸是不是就显得非常的弱小了,当前妈妈再也不必放心我 new 对象了!!!​

2、@Resource 注解

@Resource 注解要求提供一个 bean 名称的属性,若该属性为空,则主动采纳标注处的变量或办法名作为 bean 的名称。

3、@Inject 注解

@Inject 和 @Autowired 注解一样也是按类型注入匹配的 bean,但没有 reqired 属性。

以上就是进行主动拆卸时应用的三个注解,在这里再总结一下,

@autoWried 是 spring 自带的,更弱小一些,可能实现 required=false

@Resource 也是 java 自带的,扩展性更强,所以如果切换成另一个容器框架,@Resource 还是能够用的,而 @Inject 和 @Autowired 注解一样也是按类型注入匹配的 bean,但没有 reqired 属性。其实在日常开发中,咱们最罕用到的、性能最弱小的注解还是 @Autowired 注解。所以记住这一个基本上就能够了。

而后再总结一下应用注解的益处,次要就是节俭了 new 对象时麻烦,间接应用一个 @Autowired 注解,spring 就能够主动的为该属性赋值,一般来说将组件退出到 IOC 的注解和 @Autowired 是联合应用的。

四、注解应用的小细节

其实在应用注解进行开发时还有一些小细节须要留神,我在这里给大家总结一下。

1、整合多个配置文件

当咱们开发时的我的项目过大的时候,在一个配置文件写如配置有时候就不能满足咱们的需要,所以 Spring 容许通过 <import> 将多个配置文件引入到一个文件中,进行配置文件的集成。这样在启动 Spring 容器时,仅须要指定这个合并好的配置文件就能够。import 元素的 resource 属性反对 Spring 的规范的门路资源,

如下示例,咱们有 springmvc.xml 和 spring.xml 两个配置文件,当初咱们想要将 spring.xml 引入到 springmvc.xml 中,办法是:在 springmvc.xml 中写入上面代码:

<import resource="spring.xml"/>

2、门路书写问题

对于 spring 中罕用地址书写,有时候须要应用 classpath,而有时候又须要其余,针对不同的门路书写,有不一样的含意和应用:具体看下表:

3、获取组件时的问题

对于应用注解办法增加到容器中的组件,咱们在 IOC 容器中是看不到的,那么获取它的时候应该如何获取呢?

咱们下面也说了, 在注解中不指定 id 的前提下,spring 是会主动的为每一个组件设置一个第一个字母小写的组件的全称作为 ID,(如 Book 类的 ID 默认是 book)。在容器中获取组件的办法和以往一样,然而如果是单实例的话,个别倡议以类为参数进行获取。如:

Book book = (Book)ioc.getBean(Book.class);

五、写在最初

以上就是 Spring 注解开发的全副知识点了,是不是感觉应用注解开发比原生代码简洁多了,注解也是 SSM 框架乃至之后开发会常常用到的货色,

点击关注,第一工夫理解华为云陈腐技术~

正文完
 0