基于Spring更简单的读取和存储对象

在spring的创建和使用这篇博客中有讲到关于Spring存储和读取Bean对象的操作,但是细心的朋友有没有发现那些操作没有想象中的简单呢?所以呀,我今天要给朋友分享的是更简单的存储和读取Bean对象的方法,快来看看吧~

 

在Spring中想要更简单的存储和读取对象的核心就是使用注解,这就是我接下来要给朋友讲的啦

讲注解之前,先要在配置文件中添加扫描路径.

目录

1、存储Bean对象

1.1 配置扫描路径

1.2 添加注解存储Bean对象

1.2.1 @Controller(控制器存储)

1.3 各类注解的含义

1.4 方法注解

1.4.1 方法注解需要配合类注解使用

1.4.2 重命名Bean

2. 获取Bean对象

2.1 属性注入

2.2 setter注入

2.3 构造方法注入

2.4 @Resource


1、存储Bean对象

想要将对象成功的存储到Spring中,我们需要先配置一下存储对象的扫描包路径,只有被配置了的包下的所有类,添加注解后才能被正确的识别并保存到Spring中.

1.1 配置扫描路径

在 spring-config.xml (此文件为resources目录下自己创建的一个xml文件)中添加如下配置:

 这一步很重要,因为即使添加了注解,但如果不是在配置的扫描包下的类对象,仍然是不能被存储到Spring中的.例如上图,只要是在com.zl包下的加了注解的类的对象都可以被存储到Spring中.

1.2 添加注解存储Bean对象

若想将Bean对象成功存储到Spring中,有两种类型的注解可以实现:

  • 类注解:@Controller,@Service,@Repository,@Component,@Configuration.
  • 方法注解:@Bean

1.2.1 @Controller(控制器存储)

使用@Controller存储bean的代码如下所示:

读取并使用Bean:

运行APP类,得到一下结果:

 以上是五大类注解中@Controller的使用方法,其他四大注解的使用方法与之相同.在这里就不一一演示了.但是现在可能朋友你就要问了,为什么使用方法一样,用一个就好了呀,但是要有这么多类注解呢,接下来我们来看.

1.3 各类注解的含义

为什么要有这么多种类注解,这就和自己的身份证号的前两位一样,比如北京市的身份证号前两位就是11,河北省的前两位是13,湖北省的前两位42等,每个省的身份证号的其两位都不同,这样做的最大的作用就是可以直观的标识这个身份证所处的归属地.

同样这也是为什么需要这么多类注解一样,就是为了方便程序员看到类注解之后,就能直接了解当前类的用途,以下是这些类注解所要传达给程序员的信息:

@Controller:控制类,业务逻辑层,主要验证前端发过来的参数

@Servie:服务类,服务层,数据的处理和接口的调用

@Repository:仓库类,持久层,主要是对数据库的操作,也叫作Dao类

@Configuration:配置类,一些主要负责配置信息的类

@Component:组件类,一些外部实现的工具类

程序的工程分层,调用流程如下:

 注:@Component是其他四类类注解的"父类".

1.4 方法注解

类注解是添加在某个类上的,而方法注解是添加到某个方法上的,以下是代码实现:

然后我们在主函数上调用一下bean对象中的user方法,代码如下:

运行一下代码,发现报错,为什么呢?我们来看一下报错信息:

 通过报错信息我们可以发现,user找不到,为什么呢,是因为UserController这个类对象没有添加类注解,所以就没有存储到Spring中,所以自然就不能调用这个对象的方法了,所以,我们还要在类上添加一个类注解. 

1.4.1 方法注解需要配合类注解使用

在Spring框架的设计中,方法注解@Bean需要结合类注解才能将对象正常的存储到Spring容器中,如下图代码所示:

我们再来运行一下,得到以下结果:

这样就达到了我们的预期结果.

 通过以上例子我们得出一个小小的结论:类注解需要与方法注解搭配使用.

1.4.2 重命名Bean

可以通过name属性给Bean对象进行重命名操作,如下代码所示:

然后我们使用user1就可以获取到User对象了,如以下代码所示:

另外,这个重命名的name其实是一个数组,一个bean可以有多个名字,代码如下:

以上写法的话,不论我们是用 user1 还是 user2 都可以获取到User对象了,但是一旦重命名后,就不能写原来的user了.

补充:重命名时,name={}是可以省略的,就像这样:

@Bean("user1")
@Bean({"user1","user2"})

以上两种重命名的格式都是对的

2. 获取Bean对象

获取Bean对象也叫装配,是把对象取出来放到某个类中,也叫作对象注入.

对象注入的实现方法有以下3种:

  • 属性注入
  • 构造方法注入
  • Setter注入

下面我将仔细讲解一下这三种注入方式,按照实际开发中的模式,将 Service 类注入到 Controller 类中

2.1 属性注入

属性注入是用 @Autowired 实现的,将 Service 类注入到 Controller 类中.

Service 类的实现代码如下:

 

Controller 类的实现代码如下:

 获取Controller中的getUser方法:

 运行结果如下:

 

 属性注入的核心实现为:

属性注入的优缺点分析:

优点: 写法精简,可读性高

缺点: 首先官方就不推荐使用, 专业版 IDAE 会报警告提示.

  • 功能方面: 无法注入一个被 final 修饰的对象;容易引起空指针异常​​​​​​     
  • 通用性方面: 只适用于 IoC 容器
  • 设计原则方面: 更加容易违背单一设计原则

无法注入一个被 final 修饰的对象​​​​​​ :

这与java中的语法有关,因为对于被final修饰的对象,只有两种方式对其进行赋值,

  • 在声明时直接赋值
  • 通过构造方法赋值

容易引起空指针异常:

 只适用于 IoC 容器:

属性注入的方式只适用于 IoC 容器,  在非 IoC 框架中使用不了, 可移植性不高, 所以属性注入的通用性不是很好.

 更加容易违背单一设计原则:

因为属性注入的写法相对来说较为简单,就容易引起这种注入方式的滥用,所以更容易违背单一性原则.但是并不是说一定会违背,只是有这个可能.

2.2 setter注入

setter注入的核心实现为:

Setter注入优缺点分析:

优点:Setter 注入完全符合单一设计原则, 一个 Setter 方法只针对一个对象.

缺点:

  • 不能注入final修饰的对象
  • 注入的对象有被修改的风险

不能注入final修饰的对象:

原因和属性注入一样,final修饰的对象要么直接赋值,要么在构造方法中赋值.

注入的对象有被修改的风险:

因为 Setter 注入提供了 setXXX() 方法, 就意味着 setXXX() 可以被调用,  既然能被调用, 则 Setter 注入的对象随时都有被修改的风险.

2.3 构造方法注入

构造方法注入的核心实现为:

注意:如果只有一个构造方法,则@Autowired可以省略.如果有多个构造方法,则必须在需要注入的构造方法上加入@Autowired表明哪一个是需要被注入的.另外只能注入一个构造方法,因为在普通程序中,我们创建new一个对象时,会根据参数调用其中一个构造方法.

构造方法优缺点分析:

优点:首先它是当前Spring的推荐写法

  1. 可以注入不可变对象
  2. 注入的对象不会被修改
  3. 依赖对象在使用前一定会被完全初始化
  4. 通用性更好

缺点:写法较为复杂,如果注入对象很多,则代码看起来更臃肿.

可以注入不可变对象:

上面有讲到,被final修饰的属性可以通过构造方法赋值,故在构造方法注入时,可以给final对象赋值

注入的对象不会被修改:

构造方法注入, 在程序执行的时候, 它只会执行一次, 所以不会像 Setter 注入那样被调用多次, 也就不存在被修改的情况.

依赖对象在使用前一定会被完全初始化:

因为我们要注入的对象是在构造方法中实现的,构造方法的执行比类的创建要早, 所以我们要使用的注入的对象, 一定是被完全初始化的.

通用性更好:

构造方法是 JDK 支持的,  往往越底层的框架, 它的可移植性就越好, 所以换做其他任何框架都是适用的.

2.4 @Resource

在进⾏类注⼊时,除了可以使⽤ @Autowired 关键字之外,我们还可以使⽤ @Resource 进⾏注⼊,如 下代码所示:

 @Autowired 和 @Resource 的区别:

  • 来源不同:@Autowired 来⾃于 Spring,⽽ @Resource 来⾃于 JDK 的注解;
  • 使用时设置的参数不同:相⽐于 @Autowired 来说,@Resource ⽀持更多的参数设置,例如 name 设置,根据名称获取 Bean.
  • @Autowired 可⽤于 Setter 注⼊、构造函数注⼊和属性注⼊,⽽ @Resource 只能⽤于 Setter 注 ⼊和属性注⼊,不能⽤于构造函数注⼊。

同一类型对应多个Bean时,如何注入自己想要的Bean?

比如当出现以下多个Bean,返回同一对象类型时程序会报错,如下代码所示:

 

在另一个类中获取User对象,如下:

 

 

执行以上程序:

报错原因:非唯一的Bean对象。

那怎么解决呢?有以下两种方法:

对于同一类型多个Bean报错处理:

  • 使⽤ @Resource(name="user1") 定义。
  • 使⽤ @Qualifier 注解定义名称

1)、使⽤ @Resource(name="user1") 定义:

 2)、使⽤ @Qualifier(需要搭配@Autowired)

 两者的运行结果都是:

这样问题就解决了~


 好啦,到这里就结束啦,回顾一下,五大类注解分别是什么以及他们之间各自起到的标识作用是什么,怎样存储对象、从Spring中获取对象的方式有哪几种,分别怎么获取,这几种方式的优缺点又是什么呢?相信认真看完这篇博客的朋友你应该知道了吧,要是回答不上来,那就再看一下吧

 

还有,有什么不理解的地方或建议或错误都欢迎指出哦,评论区私信都可~~~

 

 

 

  • 8
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 7
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

哆啦A梦的110

你的鼓励是我创作最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值