开篇
mmp,今天上班又迟到了一个小时。一下雨这鬼路上就堵车,简直了。。好了,不吐槽了,昨天挖的坑,今天是时候填上了。内容可能有点多,肾功能不强大者勿看0.0。
常见的几种注入方式
1. Set 方式注入
set 方式注入是除了注解以外最常用的一种方式,我们昨天所说的就是通过 set 方式注入属性值的,具体实现如下:
在 applicationContext.xml中配置:
- 1
- 2
- 3
- 4
- 5
- 1
- 2
- 3
- 4
- 5
在实体类中提供 set 方法
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
测试结果:
注意:
- 必须要提供 set 方法,get 方法可以不提供。
- 通过配置 Spring 就可以实现帮我们创建对象的实例,这说明了什么?说明 Spring 底层是通过反射来帮我们创建对象的实例的,如果不提供 set 方法,Spring 将无法通过反射来获取到 setXXX() 方法来帮我们注入值。
- 提供 toString 方法仅仅只是为了打印结果,并没有其他意图。
2. 通过构造器注入值
在 User 对象中添加如下构造函数:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
在applicationContext.xml 文件中做如下配置:
- 1
- 2
- 3
- 4
- 5
- 1
- 2
- 3
- 4
- 5
测试结果:
结果是正常的,不过通过构造函数注入时,除了可以通过
- 1
- 1
这种方式外,还可以通过索引来注入,比如把配置文件更改成如下的方式:
- 1
- 2
- 3
- 4
- 5
- 1
- 2
- 3
- 4
- 5
结果同上面是一样的。(提示:索引从 0 开始)
注意
这里全部都是用的 value ,还记得昨天的文章中有一个 ref 么?为什么要用 value 而不用 ref 请自行去上一篇文章中弄清楚。
假设 User 对象中有另外一个 对象 “Car”, 这个时候我们应该如何注入?如何注入我们试试就知道了。
新建一个 Car 对象
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
在 User 对象里面添加
- 1
- 2
- 3
- 4
- 5
- 6
- 1
- 2
- 3
- 4
- 5
- 6
在配置文件 applicationContext.xml 中做如下配置:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
结果
我想,到这里,ref 和 value 的用法你应该了解了。如果还不知道什么区别的话,那你这样记吧。
value 是传值的,ref 是传引用的。
这句话可能不太严谨,但是对初学者来说,还是比较好记住的。
3. 其他的注入方式
注入的方式还有
SpEL 表达式注入
通过 P 标签注入
通过注解注入(重要)
其中 SpEL 表达式 和 p 标签在开发中基本不会用到,这里就不做讲解了。而注解注入,这个是比较重要的知识点,留在后面去说。注解注入也是我们以后开发中最主流的注入方式。
p 标签的注入方式(了解)
- 1
- 2
- 3
- 1
- 2
- 3
注意:通过 p 标签注入,一定要提供 set 方法,否则无法注入。
SpEL 的代码我就不写了,有需要的可以去看一些文档。自己要学会举一反三。
注入几种特殊类型
1. 注入数组类型
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
SpType.Java
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 1
- 2
- 3
- 4
- 5
- 6
- 7
2. 注入 List
这个套路和注入数组一毛一样,这里就只给出配置文件和截图了。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
3. 注入Map
这个和上面的两者稍有区别。也不废话了,直接上配置文件。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
运行截图:
4. 注入 Set
套路和 List 已经数组一样,只不过要注意,Set 没有重复的值。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
截图:
5. 注入属性文件
- 1
- 2
- 3
- 4
- 5
- 6
- 1
- 2
- 3
- 4
- 5
- 6
具体测试我就不测试了,挺简单的,有兴趣自己动手,丰衣足食。
Spring 重要的开发方式之注解开发
啥是注解我也就不解释了,不知道的话,推荐你们去重新温习一下 Java 的基础知识。
1. 注解入门
使用注解开发,能够极大的方便我们的开发,所以这也是我们实际开发中必须掌握的一门技术。要使用注解进行开发,我们需要引入 spring框架的另外一个包
spring-aop-4.0.2.jar
此时修改我们的 UserServiceImpl.java,在类的上面添加如下注解
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
如果要使该注解生效,我们需要告诉 Spring 容器我们使用了注解。所以我们还需要在配置文件中加上一句话:(开启注解扫描)
- 1
- 2
- 1
- 2
运行结果:
运行结果和我们在配置文件中配置并无其他区别。通过注解,我们不需要再配置文件中在配置数不清的 bean,大大节省了我们的开发时间,也提升了我们的开发效率。
2. 注解功能讲解
@Component 注解是什么意思呢?
Component 是组件的意思,作用在类上的。在我们的 MVC 开发模式中,WEB 层,Service 层以及 Control 层都可以使用该注解。但是为了满足单一职责原则,从该注解又衍生出三个注解:
@Controller 作用在类上,WEB 层使用
@Service 作用在类上,Service 层使用
@Repository 作用在类上,Dao 层使用
这三个注解本身就是为了使各个模块的功能更加清晰,虽然你使用 @Component 也没错,但是谁也不能保证 Spring 的团队后面不会对该注解进行改动,所以为了避免以后出现不必要的麻烦,还是使用功能分工明确的那三个注解。
So?我们的上面的例子也可以使用 @Service 注解来代替:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
实现的效果完全一样。
3. 使用注解注入属性
上面只是讲了解决了配置文件中 bean 标签的简化配置
- 1
- 1
那如果我们要注入引用类型和基本数据类型呢?难道没有吗?错,Spring 当然给我们也提供了注解的方式。看下面的几个注解:
@AutoWired
@Qualifier
@Value
首先从最下面的注解说起
3.1 如果是要注入普通的数据类型,那么非 Value 注解莫属。
修改 UserServiceImpl.java
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
注意:
Spring 所提供的注解属性值全部都是 value
在注解只有一个属性的前提下,”value = ” 可省略不写
上面的 @Value(value=”二花”) 和 @Value(“二花”) 是等价的
同理 @Service(“userService”) 同样也和 @Service(value=”userService”) 等价
使用注解后,set 方法可以省略。
3.2 注入引用类型
如果是注入引用类型的话,就要看 @AutoWired 和 @Qualifer 这两个注解了。
@AutoWired //按类型装配
@Qualifer //强制使用名称注入
先说 @AutoWired 注解
更改 UserDaoImpl.java,要把 UserDaoImpl 也交给 Spring 去管理,必须要加上注解 @Repository 注解。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 1
- 2
- 3
- 4
- 5
- 6
- 7
再改 UserServiceImpl.java
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
先不谈 AutoWired 的功能,我们先看结果。
测试结果:
嗯,老铁,没毛病。AutoWired 是自动装配的,它默认是按照类型装配的,如果我们把
- 1
- 2
- 3
- 4
- 5
- 6
- 1
- 2
- 3
- 4
- 5
- 6
结果和上面一样,这是为什么呢?是因为使用了 AutoWired 注解后,他并不是根据 id 去找,而是根据类型去找的,所以不管你更改成什么名字,ud,xxx 等等,都是可以注入成功的。但是这样是会有一个弊端的,如果一个接口有多个实现类,那么此时使用 AutoWired 进行自动装配肯定会出错。那么如何解决上面的问题呢?
当然有解决办法,我们不乱写名字不就可以了么?那么我们的另外一个注解 @Qualifer,这个注解的意思就是强制使用名称去注入
更改 UserDaoImpl.java 和 UserServiceImpl.java 中的代码
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
测试结果:
这样就达到了我们的目的。一个是按类型,一个强制按名称,这两个注解同时使用,只能得出正确的结果。
3.3 Java 提供的 Resource 注解
如果一个接口有多个实现类,那么我们就跟上面一样,需要同时写两个注解,那么这好像一点也不程序员,不满足我们程序员的风格,能不能再简单一点呢?当然可以,Java 中有一个注解是得到了 Spring 的支持了的,他就是 Resource 注解,这个注解的功能就相当于上面的 AutoWired 注解和 Qualifer 注解同时使用。
这样更改 UserServiceImpl.java
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
图片展示的结果已经说明了一切,一切尽在不言中。
bingo!此处应该有掌声。。。(鸦雀无声),好吧,此时无声胜有声也行。(自抱自泣.jpg)
3.4 其他注解
-
Bean的作用范围注解
1. 注解为@Scope(value=”prototype”),作用在类上。值如下:
2. singleton – 单例,默认值
3. prototype – 多例 -
Bean的生命周期的配置(了解)
注解如下:
1. @PostConstruct – 相当于init-method
2. @PreDestroy – 相当于destroy-method
OK,完美收工。
结尾
一点注解和注入方式就讲了这么多,好啦,下面的东西留到下篇文章吧,毕竟需要消化一下。能力有限,只能写出这样的文章,如果有错误的地方,还烦请给我指出,以免误导他人,同时欢迎留言交流。