Spring基础专题——第一章(第一个Spring程序)
前言:去年到现在一直没有很好的时间完成这个spring基础+源码的博客目标,去年一年比较懒吧,所以今年我希望我的知识可以分享给正在奋斗中的互联网开发人员,以及未来想往架构师上走的道友们我们一起进步,从一个互联网职场小白到一个沪漂湿人,一路让我知道分享是一件多么重要的事情,总之不对的地方,多多指出,我们一起徜徉代码的海洋!
我这里做每个章节去说的前提,不是一定很标准的套用一些官方名词,目的是为了让大家可以理解更加清楚,如果形容的不恰当,可以留言出来,万分感激
1、软件版本
- jdk1.8+
- maven3.5+
- IDEA2019.2
- Spring Framework 5.1.4(spring官网:http://spring.io)
2、环境搭建
pom.xml中设定spring的jar依赖
#设置pom 依赖 <!-- https://mvnrepository.com/artifact/org.springframework/springcontext --> <dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.1.4.RELEASE</version> </dependency>
此处新手会有疑问,我们为什么要导入这个context呢?
看下官网spring的核心组件有哪些(Core Container中有四个,Beans,Core,Context,SpEL)
我们为什么先选择用Context,因为对于Context来说,你可以理解为Spring既然是一种解决方案,一定是为了解耦而出现,所以它是作用在整个应用上下文,也就是官方文档中强烈建议我们xml设置为applicationContext.xml,我这边不严格对照官网的方式来,我们按照我们最熟悉spring的基础来走,所以我们先引用了Spring的Context包;
3、Spring的配置文件
- 配置文件放置位置:任意位置,没有硬性要求
- 配置文件命名:也没有硬性要求,但是官网强烈建议applicationContext.xml
4、Spring核心API
- ApplicationContext
- 作用:Spring提供的ApplicationContext这个工厂,用于对象的创建
- 好处:解耦合
- 接口类型:屏蔽实现的差异
非web环境:ClassPathApplicationContext(main unit)
web环境:XmlWebApplicationContext(这个需要引入spring-web的才会有,因为这个实现是在web应用中)
找到ApplicationContext.java这个类,然后使用Ctrl+H就可以看到这个接口有那些实现类
注意:ApplicationContext这个工厂对象占用大量的内存,所以
- 不会频繁的创建对象:一个应用只会创建一个工厂对象
- 既然对象只有一个,那么一定会有涉及到共享资源多线程并发访问,那么也一定是线程安全的(后面解释)
5、程序开发
- 创建类型,配置文件在resources下建立applicationContext.xml
- 配置文件添加(前提是要创建一个Person类)
<bean id="person" class="com.doctchen.spring5.entity.Person"></bean>
- 测试类
/*** 测试ApplicationContext工厂怎么创建对象的*/@Testpublic void test1(){ApplicationContext ctx = new ClassPathXmlApplicationContext("/applicationContext.xml");Person person = (Person) ctx.getBean("person");System.out.println("person = " + person);}
6、细节分析
- 名词解释
- Spring工厂创建的对象,叫做bean或者组件Component(实际上严格来说,不能称为对象,对象不等于bean,后面分析源码我再详解,这里先做为对象)
- Spring工厂相关的方法
- getBean家庭
- getBeanDefinitionNames
- getBeanNamesForType
- containsBeanDefinition
- containsBean
- getBean(String, Class)
Person person = (Person) ctx.getBean("person"); System.out.println("person = " + person);//通过这种⽅式获得对象,就不需要强制类型转换 Person person = ctx.getBean("person", Person.class); System.out.println("person = " + person);
- getBean(Class)
//当前Spring的配置⽂件中 只能有⼀个<bean class是Person类型 Person person = ctx.getBean(Person.class); System.out.println("person = " + person);
<bean id="person" class="com.doctchen.spring5.entity.Person"> </bean><!-- 对于getBean(Class),只能有一个class,id也唯一,这里多写一个Person1后,这个api会报错 --> <bean id="person1" class="com.doctchen.spring5.entity.Person"> </bean>
//getBean(Class)报错 org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'com.doctchen.spring5.entity.Person' available: expected single matching bean but found 2: person,person1at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveNamedBean(DefaultListableBeanFactory.java:1137)at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveBean(DefaultListableBeanFactory.java:407)at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:341)at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:335)at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1101)
很明显报错解释,要找一个确定的Person Bean,但是发现有两个Bean,所以Spring懵逼了!!!
- getBeanDefinitionNames
//获取的是Spring⼯⼚配置⽂件中所有bean标签的id值person person1 people String[] beanDefinitionNames = ctx.getBeanDefinitionNames(); for (String beanDefinitionName : beanDefinitionNames) {System.out.println("beanDefinitionName = " +beanDefinitionName); }
<bean id="person" class="com.doctchen.spring5.entity.Person"> </bean><bean id="person1" class="com.doctchen.spring5.entity.Person"> </bean><bean id="people" class="com.doctchen.spring5.entity.People"> </bean>
- getBeanNamesForType
//根据类型获得Spring配置⽂件中对应的id值 String[] beanNamesForType = ctx.getBeanNamesForType(Person.class); for (String id : beanNamesForType) {System.out.println("id = " + id); }
<bean id="person" class="com.doctchen.spring5.entity.Person"> </bean><bean id="person1" class="com.doctchen.spring5.entity.Person"> </bean>
- containsBeanDefinition
//⽤于判断是否存在指定id值的bean,不能判断name的值 if (ctx.containsBeanDefinition("person")) {System.out.println("true = " + true); } else {System.out.println("false = " + false); }
<!-- 判断是否存在指定id为person的bean,但是无法判断是否存在指定name为p的bean --> <bean id="person" name="p" class="com.doctchen.spring5.entity.Person"> </bean>
- containsBean
<!-- 判断是否存在指定id为person的bean,也可以判断是否存在指定name为p的bean --> <bean id="person" name="p" class="com.doctchen.spring5.entity.Person"> </bean>
这两个有细微的差别,就是id都可以判断,后者连name的值也可以判断,对于name和id的区别,我后面再说!
- 配置文件中的细节注意
- 只配置class属性
<bean class="com.doctchen.spring5.entity.Person">
当我们不写id的时候,spring会不会给我们一个id值?答案是肯定的,我们只需要用上面的api--getBeanDefinitionNames
//打印结果 beanDefinitionName = com.doctchen.spring5.entity.Person#0 String[] beanDefinitionNames = ctx.getBeanDefinitionNames(); for (String beanDefinitionName : beanDefinitionNames) { System.out.println("beanDefinitionName = " +beanDefinitionName); }
所以这个名字是有的,如果没有命名的id对应的class有多个,并且我们id没有写,那么spring会默认以此类推1、2、...
<!--beanDefinitionName = com.doctchen.spring5.entity.Person#0beanDefinitionName = com.doctchen.spring5.entity.Person#1 --><bean class="com.doctchen.spring5.entity.Person"> </bean><bean class="com.doctchen.spring5.entity.Person"> </bean>
这个应用场景在:如果这个bean只需要使用一次,那么就可以省略id的值,如果这个bean被使用多次,或者被其他的bean引用则需要设置id的值
- name属性
- 作用在Spring配置文件中,为bean的对象定义别名(小名)
相同:ctx.getBean("id|name")--->object
配置上:<bean id="" class=""/> == <bean name="" class=""/>- 区别是
1. 别名可以定义多个,但是id只有一个
2. xml的id属性,命名要求,必须以字母,数字,下划线,连字符开头,不能以特殊字符开头,比如/person
3. 对于name属性命名,没有要求但是spring发展到了现在,xml中的bean id,已经没有了限制,读者可以自行去试试
7、Spring工厂底层实现原理(简易版)
Spring是可以调用私有的构造方法来创建对象的
8、思考
- 未来开发过程中,是不是所有的对象都要交给Spring工厂来创建?我们下一章见分晓!!!
有不对的地方,或者需要补充的,直接评论,我把这个文章更加完善下去!!!
Spring基础专题——第一章(第一个Spring程序)相关推荐
- 第一章第一个c#程序上机_我从第一个#100DaysOfCode中学到的东西
第一章第一个c#程序上机 On May 17th, I completed my first round of #100DaysOfCode. In case you haven't heard, # ...
- Dubbo基础专题——第一章(带你认识Dubbo)
前言:刚完成的Spring基础专题本想更新源码的,但是发现分布式非常火,而我喜欢玩这个,所以今年我希望把我的知识可以分享给正在奋斗中的互联网开发人员,以及未来想往架构师上走的道友们我们一起进步,从一个 ...
- Spring基础专题——第九章(基础注解编程——上)
目标,去年一年比较懒吧,所以今年我希望我的知识可以分享给正在奋斗中的互联网开发人员,以及未来想往架构师上走的道友们我们一起进步,从一个互联网职场小白到一个沪漂湿人,一路让我知道分享是一件多么重要的事情 ...
- Spring基础专题——第二章(注入Injection)
前言:去年到现在一直没有很好的时间完成这个spring基础+源码的博客目标,去年一年比较懒吧,所以今年我希望我的知识可以分享给正在奋斗中的互联网开发人员,以及未来想往架构师上走的道友们我们一起进步,从 ...
- Dubbo基础专题——第二章(Dubbo工程简单实践)
前言:刚完成的Spring基础专题本想更新源码的,但是发现分布式非常火,而我喜欢玩这个,所以今年我希望把我的知识可以分享给正在奋斗中的互联网开发人员,以及未来想往架构师上走的道友们我们一起进步,从一个 ...
- 微型计算机基础 教案,第一章微型计算机基础知识新080902电子教案(153页)-原创力文档...
第一章 微型计算机基础知识;第一章? 微型计算机基础知识;§1.1 计算机中数的表示方法;1.1.1 进位计数制及各计数制间的转换;二进制数的特点; 十进制--符合人们的习惯二进制--便于物理实现十六 ...
- 电大计算机基础光盘电脑安装,电大《计算机应用技术基础》第一章 计算机的硬件安装...
<电大<计算机应用技术基础>第一章 计算机的硬件安装>由会员分享,可在线阅读,更多相关<电大<计算机应用技术基础>第一章 计算机的硬件安装(28页珍藏版)&g ...
- excel工具栏隐藏了怎么办_Office2016基础教程第一章:认识Excel #excel #职场 #办公技巧...
今日详讲Excel基础 教程 第一章:认识Excel 1. 版本兼容性 2. Excel2016的独特之处 3. 安装Excel2016 4. 启动Excel2016 5. 退出Excel2016 6 ...
- 计算机基础应用win7,计算机应用基础WIN7第一章.ppt
计算机应用基础WIN7第一章.ppt (20页) 本资源提供全文预览,点击全文预览即可全文预览,如果喜欢文档就下载吧,查找使用更方便哦! 9.9 积分 计算机应用基础 Windows7+Office2 ...
最新文章
- UVA1103 古代象形符号 Ancient Messages解题报告(DFS,字符串)难度⭐⭐⭐⭐
- PostgreSQL在何处处理 sql查询之三十九
- mysql @@version_MySQL数据库安装Version5.5
- python数据分析笔记中panda(2)
- Daily scrum 12.19
- matlab2c使用c++实现matlab函数系列教程-cat函数
- 8.docker search
- c#: Newtonsoft.Json 高级用法二(jsonpath)
- python读取二进制文件_python中读写二进制文件
- 用计算机如何扫描文件,打印机扫描文件到电脑方法教程
- 《嵌入式系统原理与应用》 |(一)嵌入式系统概述 知识梳理
- 如何成长为硬件工程师
- 【MarkDown】基础语法
- linux路由器还原,openwrt路由器恢复出厂设置的方法
- 数据增强方法:图片镜像、图片缩放、图片旋转、加噪点
- 红豆薏米的祛湿效果到底好不好?
- 1231321321
- 拉钩参数加密过程:data
- 根据字符的首字母进行分类
- 月度计划:2022年5月
热门文章
- GitHub标星10,000+,Apache项目ShardingSphere的开源之路
- 为什么说Transformer就是图神经网络?
- AttoNets,一种新型的更快、更高效边缘计算神经网络
- 无需成对示例、无监督训练,CycleGAN生成图像简直不要太简单
- 华为推CPU Turbo,荣耀Note10突破3000档
- AI工程师的哆啦A梦超能力不是吹出来的!
- AI 一分钟 | 微软推出全新人工智能平台;多名用户反映亚马逊 Echo 智能音箱突然发笑
- 面试:TCP协议经典十五连问!
- 为什么不推荐使用BeanUtils属性转换工具
- 轻松两步,我在 SpringBoot 服务上实现了接口限流