这篇文章主要介绍了怎么搭建第一个Spring项目,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。
Spring Framework 八大模块
模块化的思想是 Spring 中非常重要的思想。
Spring 框架是一个分层架构,每个模块既可以单独使用,又可与其他模块联合使用。
每个「绿框」,对应一个模块,总共8个模块; 「黑色包」,表示要实现这个模块的 jar 包。
Core Container
,我们刚才已经在文档里看到过了,就是 IoC 容器,是核心,可以看到它依赖于这4个 jar 包:
-
Beans
-
Core
-
Context
-
SpEL
, spring express language
那这里我们就知道了,如果想要用 IoC 这个功能,需要把这 4个 jar 包导进去。 其中,Core 模块是 Spring 的核心,Spring 的所有功能都依赖于这个 jar 包,Core 主要是实现 IoC 功能,那么说白了 Spring 的所有功能都是借助于 IoC 实现的。
其他的模块和本文关系不大,不在这里展开了。
那当我们想搭建 Spring 项目时,当然可以把所有 jar 包都导进去,但是你的电脑能受得了吗。。但是包越大,项目越大,问题就越多,所以尽量按需选择,不用囤货。。
Btw, 这张图在网上有很多,但是在我却没有在最新版的 reference doc 上找到。。 不过,既然那些老的教程里有,说明老版本的 doc 里有,那去老版本的介绍 里找找看????
在本文第一张图 Spring Framework
– Documentation
中我们选 4.3.26
的 Reference Doc.
,然后搜索“Framework Modules
”,就有啦~ 具体链接可以看文末参考资料。
还有一个方法,待会我们讲到 jar 包中的内容时再说。
知道要导入哪些 jar 包了,那就找吧????。
一、手动加载 jar 包的方式
1. 下载
下载地址:
如果你要问我怎么找的,那就还是从刚才 4.3.26
版本的 Reference Doc
中进去,然后刚开头就有一个 Distribution Zip Files
,
好奇心带着我打开了它,发现…
发现了仓库地址!
打开后发现是各个版本的 jar 包啊~
我们搜 5.2.3 版的,它在最下面:
然后就可以愉快的使用了~
-
Dist.zip
是 jar 包 -
Docs.zip
是文档
其他的暂时先不用管~
下载好了之后,就好好看看 Spring 送我们的这份大礼包吧。
此处回答上文的遗留问题:哪里找 Spring Framework 框架图。
答案是:下载的 docs.zip → spring-framework-reference → images → spring-overview
我们需要导入 Intellij 的 jar 包在哪里呢? Dist.zip → libs
这里可以看到,每个黑色框对应3个 jar 包,我们要导入 Intellij 的是 RELEASE.jar
.
2. 不用 IoC 构建项目
我们 new project
,不用 maven 构架,就新建一个普通的 Java 项目,比如我就叫它 Spring_HelloWorld
,然后还是用我常用的 class Rectangle
的例子。
然后在 External Libraries 中导入我们刚才在模块图里看到的那4个模块所对应的 jar 包,结构如下:
这样你以为就大功告成了吗?Too young too simple 啊~
来运行一下:
出现了老盆友:no class def found error
, 就是找不到这个类。
我们谷歌 Maven common logging
并下载它的 jar 包,再加到项目里就可以了。
我上图里是已经加过了的,所以你会看到一个 commons-logging-1.2
.
再运行一下就可以了。这里的两个文件上文都有截图。
目前为止我们是手动用 set()
方法设置对象的,那怎么用 Spring IoC 呢?
3. Spring IoC 配置文件详解
还需要有一个配置文件,可是这个文件需要配置啥,该怎么配置呢?
官网里都给我们写好了:
第一段是一些命名空间及其规范的介绍,
第二段就是给 bean
的属性赋值了。
这里注意下 bean
里面的配置要改一下,改成我们这个项目对应的。 这里的 id
, class
是什么意思呢?官网上也有解释,我这里简单概括下:
-
bean
标签:告诉 Spring 要创建的对象 -
id
: 对象的唯一标识,就像每个人的身份证一样,不可重复 -
class
:bean
的完全限定名,即从 package name 到 class name -
property
:给属性赋值,name
的名称取决于set()
方法后面的参数;
其实也可以用 constructor 来赋值,name 的名称取决于参数列表; 更多给复杂数据类型赋值的使用可以在官网查到。
当然,在工作中更常用的是注解。但是往往也会有 xml 文件配合着一起使用的,所以还是要懂的。
我的 service 文件配置如下:
4. 最后一步,我们再来看它是怎么用的:
这里面并没有直接的 new 这个 service,但是 Spring 容器帮我们创建了这个对象。
那么 Spring 是如何帮我们创建对象的呢?
ApplicationContext
是 IoC 容器
的入口,其实也就是 Spring 程序
的入口, 刚才已经说过了它的两个具体的实现子类,在这里用了从 class path 中读取数据的方式;
然后第二行,就是获取具体的 bean 了。这个其实有很多方式,在使用的时候就能看到:
点进去发现,是在 BeanFactory.class 里定义的:
这其中比较常用的是通过
-
Id → 需要 cast
-
Bean 的类型 → 只能在 Singleton 的时候使用,否则不知道用哪个呀
-
Id + 类型 → 下图代码示例
来获取对象,最后两种 String, Class objects 这种可变参数的方式用的很少。
照猫画虎,我的 test 文件改动如下:
成功运行~~????????
Follow up 1. 对象在容器中默认是单例的
实践是检验的唯一标准:
再用 getBean()
得到一个对象,测试是否还是同一个。
即:
public class MyTest { public void test myTest() { ApplicationContext context = new ClassPathXmlApplicationContext("service.xml"); Rectangle rect = context.getBean("rectangle", Rectangle.class); Rectangle rect2 = context.getBean("rectangle", Rectangle.class); System.out.println(rect == rect2); } } }
返回 True or False?
答:True
因为默认是单例的,如果要改,需要在配置文件里改 <bean … scope = “prototype”>
.
至于这些标签的用法,这里不再延伸了~
Follow up 2. 容器中的对象是什么时候创建的?
实践是检验的唯一标准:
定义一个无参的 constructor,里面打印一句话,然后只 new ClassPathXmlApplicationContext
,如下图:
发现也是可以打印的,所以其实是每次启动容器的时候,就已经创建好容器中的所有对象了。(当然,这在 scope = "prototype"
的时候不适用,只是 singleton 的时候。)
多说一句,其实最好应该一直保留一个无参的 constructor,因为这里 bean 对象的创建是通过反射,
-
clazz.newInstance()
默认是调用无参的 constructor
不过,现在已经被弃用掉了,换用了这个:
-
clazz.getDeclaredConstructor().newInstance()
二、使用 Maven 构建项目
我们再回到最开始的构建项目,相信大家都体会到了手动导入 jar 包的繁琐之处,其实我们还可以用 Maven 来管理项目中的 jar 包,在公司中也是比较常用的一种方式,免除了手动下载 jar 包的过程。
1. 新建项目
使用 Maven 的话就简化很多了,首先我们创建一个 Maven 项目,不同于刚才的过程在于:
New Project 的时候要选择从 Maven 构建,而不是一个简单的 Java 项目。
建好之后,我们会发现比起刚才的 Java 项目,多了很多东西:
和之前的空项目不太一样,这里有 main
, test
,其中 resources
是放配置文件的地方,也就是我们刚才的 service.xml
应该放在这里,如果没有放对位置是代码找不到哦~
2. 添加对应的 pom 依赖,就不用手动导 jar 包了
-
仓库地址
https://mvnrepository.com/
-
搜
spring
-
选择
Spring context
→5.2.3 release
,把里面的配置 copy 到pom.xml
中
最终在左边 external libraries 会自动出现所需的包,一键导入,不要太方便~
3. 写代码~~????????
小结
我们最后再来体会一下用 Spring 创建对象的过程:
通过 ApplicationContext
这个 IoC 容器的入口,用它的两个具体的实现子类,从 class path 或者 file path 中读取数据,用 getBean()
获取具体的 bean instance。
那使用 Spring 到底省略了我们什么工作?
答:new 的过程
。把 new 的过程交给第三方来创建、管理,这就是「解藕」。
Spring 也是用的 set()
方法,它只不过提供了一套更加完善的实现机制而已。
而说到底,底层的原理并没有很复杂,只是为了提高扩展性、兼容性,Spring 提供了丰富的支持,所以才觉得源码比较难。
因为框架是要给各种各样的用户来使用的,它们考虑的更多的是扩展性。如果让我们来实现,或许三五行就能搞定,但是我们实现的不完善、不完整、不严谨,总之不高大上,所以它写三五十行,把框架设计的尽可能的完善,提供了丰富的支持,满足不同用户的需求,才能占领更大的市场啊。
感谢你能够认真阅读完这篇文章,希望小编分享的“怎么搭建第一个Spring项目”这篇文章对大家有帮助,同时也希望大家多多支持亿速云,关注亿速云行业资讯频道,更多相关知识等着你来学习!
原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/208305.html