Blogger Information
Blog 11
fans 0
comment 0
visits 7708
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
二、Spring程序开发
P粉934491362
Original
447 people have browsed it

一、本次学习的软件版本介绍

  1. JDK 1.8+
  2. Maven 3.5+
  3. IDEA2018+
  4. SpringFramework 5.1.4

二、环境搭建

Spring的jar包

  1. 我们可以通过maven的中心仓库来获取对应版本的依赖(上网找-搜spring-看到springcontext)
  2. <dependency>
  3. <groupId>org.springframework</groupId>
  4. <artifactId>spring-context</artifactId>
  5. <version>5.1.4.RELEASE</version>
  6. </dependency>

Spring的配置文件

  1. 1. 配置文件的放置位置: 任意位置 没有硬性要求
  2. 2. 配置文件的命名:没有硬性要求,不过官方建议:applicationContext.xml
  3. 思考:你不告诉spring你的配置文件在哪,它怎么去拉配置呢?
  4. 所以我们后面要配置对应【配置文件】的路径
  5. 备注:我们可以通过下图所示创建对应的配置文件

三、Spring的核心API

ApplicationContext

  1. 作用:Spring提供的的这个ApplicationContext这个工厂,最重要的是为了对象的创建
  2. 好处: 解耦合

ApplicationContext接口类型

  1. >为什么是接口?
  2. 因为接口的目的是为了屏蔽实现的差异(谁实现我,谁就必须实现我所声明的方法)
  3. >那么Spring的接口实现类有哪些呢?
  4. WEB环境:ClassPathXmlApplicationContext (比如main junit等方法)
  5. WEB环境: XmlWebApplicationContext
  6. >如何证明上面说的是正确的呢?
  7. 首先为了保证有WEB环境的实现类,我们先导入下面这个依赖
  8. <dependency>
  9. <groupId>org.springframework</groupId>
  10. <artifactId>spring-webmvc</artifactId>
  11. <version>5.1.4.RELEASE</version>
  12. </dependency>
  13. 第二步:我们使用 CTRL+H 去查看该类的继承关系,那么我们就找到了如下图

Application的实现类都是重量级资源

  1. 》毕竟属于创建对象的重要方法,所以其一定占用了大量的内存
  2. 》不会频繁地创建对象:一个应用只会创建一个工厂对象
  3. 》在多线程并发访问的时候一定是线程安全的

开发你的第一个Spring程序吧!
其实和第一节的通过工厂方式获取对象的方式一样,我们通过在配置文件取得唯一的类的全限定名来获取对象,下面为开发步骤

  1. 1》创建类:需要什么类,就配置什么类
  2. 2》配置applicationContext.xml文件
  3. <bean id="user" class="cn.paul.spring.demo.hellospring.entity.User"/>
  4. 这里的id一定是唯一的,class是类的权限定名,这就像我们开头所学习的配置文件的k-v对一样
  5. 3》通过工厂,获得对象
  6. ApplicationContext
  7. |- ClassPathXmlApplicationContext Junitmain等非web的环境下使用)
  8. |- XmlWebApplicationContext(在web环境下使用)
  9. 4demo展示
  10. public class TestSpring {
  11. @Test
  12. void test01(){
  13. //获取Spring工厂(传入对应的文件路径)
  14. ApplicationContext ctx = new ClassPathXmlApplicationContext("/applicationContext.xml");
  15. //通过Spring工厂创建对象
  16. User user = ctx.getBean("user", User.class);
  17. System.out.println("user:"+user);
  18. }
  19. }
  20. 备注:对于非WEB的环境,你需要告知Spring你的配置文件在哪里!!

第一个程序后,你应该要对下面这些细节有了解哦

  1. 第一点,通过上面的getBean方法传入的是配置文件的id和对应的类名称,那么很明显
  2. 通过这种方式,能很好地去让Spring确定你需要创建哪个Bean(在Spring中也叫component)
  3. 第二点,我们还有一种getBean(User.class),通过这种方式来创建对象,比较好的一点就是
  4. 开发者可以稍微懒一下,但是这是有限制的,如果你在配置文件中有声明到两个bean,而这
  5. 两个bean所对应的Class名称都一样,都为这个同一个类的全限定名,那么在运行的时候就会
  6. NoUniqueBeanDefinitionException 这个异常
  7. //通过这种方式获得对象,就不需要强制类型转换
  8. Person person = ctx.getBean("Person",Person.class);
  9. //当前Spring的配置文件中,只能有一个<bean class是Person类型
  10. Person person = ctx.getBean(Person.class);
  11. //获取的是Spring工厂配置文件中所有的bean标签的id值(看英文的复数便知)
  12. String[] beanDefinitionNames = ctx.getBeanDefinitionNames();
  13. //根据class的类型获得Spring配置文件中对应的id值
  14. String[] beanNamesForType = ctx.getBeanNamesFortype(Person.class);
  15. //下面两个方法都能用于判断是否存在指定id 的bean
  16. ctx.containsBeanDefinition("指定的id");
  17. ctx.containsBean("指定的id")

配置文件中需要注意的细节

  1. a)我们先来思考一个问题,如果我们只是配置了一个只含有class标签的beanSpring会帮
  2. 我们创建吗?如下
  3. <bean class="cn.paul.spring.demo.hellospring.entity.User"/>
  4. 答案是:可以的,但是必须保证如果你想实际地使用上该对象,那么这个bean要保证唯一
  5. 第二问题:既然上面对bean的定义是可以,那么Spring是否有给它定义“id值”呢?
  6. 我们可以通过 ctx.getBeanDefinitionNames()来获取对应的id值以做出判断
  7. 我们会发现其实Spring其实会给这个只声明了class名称的bean对应的id值的,
  8. 其命名规则为:类的全限定名+ # + 下标
  9. 如:cn.paul.spring.demo.hellospring.entity.User#0
  10. 我们留意一下最后一个下标,为什么下标是数组0呢?莫非还有123.....?
  11. 其实我推测可能是这样的,我们可以在配置文件配置多个只带class名称的bean
  12. Spring也会给他们对应的默认id值(后面下标改变即可)
  13. b) 只定义class名称的bean的应用场景
  14. 1> 如果这个bean只需要使用一次,那么就可以省略id
  15. 2> 如果这个bean会使用多次,或者被其他bean引用则需要设置id
  16. c) name的属性
  17. 除了在bean标签内定义idclass属性外,还可以定义name属性
  18. 作用:用于在Spring的配置文件中,为bean对象设置别名(小名)
  19. 按照我们的生活经验,我们知道本名只能有一个(就像这里的id属性),但是我们可以有
  20. 很多个别名小名(就像这里的name属性,但是注意是指只针对一个bean对象)
  21. 问题:它和id属性有什么区别呢?
  22. 先说相同点:
  23. 1.ctx.getBean("id|name") --> Object (通过idname,都可以创建对象)
  24. 但是注意:可以定义多个name,之间用逗号分割即可,但是不能在不同的bean使用同一个别名
  25. 2. <bean id="" class="" />
  26. 等效
  27. <bean name="" class="" />
  28. 3. 为什么要有name这个属性呢?
  29. 这是因为在早期SpringStruts1整合的时候,对于bean的命名必须是以/开头的
  30. 但是早期的xml是不允许id以/开头的,所以导致说可用name来匹配这种特殊的命名
  31. 最后随着技术的发展,现在xml也允许id以/开头了,所以说name这个属性多多少少
  32. 带有一点历史的痕迹
  33. 4. 关于ctx工厂提供的方法
  34. ctx.containsBeanDefinition"字符串名称")只能判断是否存在指定idbean
  35. 不能判断name
  36. ctx.containsBean"字符串名称")既可以判断是否存在指定id值的bean,也可以
  37. 判断name值(所以以后尽量用这个吧,比较好记)

Spring工厂对上述的底层实现原理(简易版)

  1. 1.Spring框架通过ClassPathXmlApplicationContext工厂读取配置文件
  2. applicationContext.xml
  3. 2.获取到配置文件标签的相关信息,比如id的值=account,class的值=cn.paul.entity.User
  4. 3.通过反射去创建对象
  5. Class<?> clazz = Class.forName("class的值");
  6. User user = clazz.newInstance();
  7. 4.注意一个问题,通过反射可以创建以任何修饰符修饰的构造方法的类的对象(回顾爆破)
  8. 同时要知道反射的底层其实是调用了该类的构造方法,并且首先调用的是无参构造
  9. Class<?> clazz = Class.forName("class的值");
  10. User user = clazz.newInstance();
  11. 等效于
  12. User user = new User();

思考:在spring的开发中,是不是所有的对象,都会交由Spring工厂来创建呢

  1. 理论上来说,因为使用Spring工厂能解耦合的原因,确实是可以通过工厂来创建的
  2. 但是有特例,比如操作数据库的持久层DAO,或者叫entity是不会交给Spring创建的
  3. 而是交给持久层框架比如mybatis进行创建,毕竟entity生来是操作数据库的,和数据库做映射关系
Statement of this Website
The copyright of this blog article belongs to the blogger. Please specify the address when reprinting! If there is any infringement or violation of the law, please contact admin@php.cn Report processing!
All comments Speak rationally on civilized internet, please comply with News Comment Service Agreement
0 comments