当前位置: 首页 > 后端技术 > Java

2.Spring程序开发

时间:2023-04-01 17:46:50 Java

一、本次学习的软件版本介绍JDK1.8+Maven3.5+IDEA2018+SpringFramework5.1.4二、构建Springjar包的环境我们可以通过maven的中央仓库获取对应版本的依赖(网上搜索-搜索spring-seeTospringcontext)org.springframeworkspring-context5.1.4.RELEASESpring配置文件1.配置文件2.配置文件的命名:没有硬性要求,官方建议:applicationContext.xml思路:不告诉spring你的配置文件在哪里,它怎么拉取配置?所以我们需要配置【配置文件】对应的路径备注:我们可以创建对应的配置文件如下图3.Spring核心APIApplicationContext的作用:Spring提供的ApplicationContext工厂最重要的是对象创建好处:解耦ApplicationContext接口类型>为什么是接口?因为接口的目的是为了屏蔽实现的差异(谁实现我就必须实现我声明的方法)>那么Spring的接口实现类有哪些呢?非WEB环境:ClassPathXmlApplicationContext(比如mainjunit等方法)WEB环境:XmlWebApplicationContext>如何证明上面是正确的?首先,为了保证WEB环境下有实现类,我们先导入如下依赖org.springframeworkspring-webmvc5.1.4.发布第二步:我们用CTRL+H查看这个类的继承关系,然后发现Application的实现类都是重量级资源如下图。毕竟是创建对象的重要方法,所以它肯定会占用大量内存《不要频繁创建对象:一个应用程序只会创建一个工厂对象》多线程并发访问时,一定是thread-安全地开发你的第一个Spring程序!其实和第一节中通过工厂获取对象的方法是一样的。我们通过获取配置文件中唯一类的完全限定名来获取对象。以下是开发步骤1《创建类:需要什么类就配置什么类2》配置applicationContext.xml文件这里的id必须是唯一的,class是类权限的名字,就像我们最开始学的配置文件的k-v对一样3"通过工厂,得到对象ApplicationContext|-ClassPathXmlApplicationContext(用于Junit或main等非web环境)|-XmlWebApplicationContext(用于web环境)4》演示展示publicclassTestSpring{@Testvoidtest01(){//获取Spring工厂(通过在对应的文件路径下)ApplicationContextctx=newClassPathXmlApplicationContext("/applicationContext.xml");//通过Spring工厂创建一个对象Useruser=ctx.getBean("user",User.class);System.out.println("user:"+user);}}注意:对于非WEB环境,需要告诉Spring你的配置文件在哪里!!在第一个程序之后,您应该需要以下内容了解这些细节。第一点是配置文件的id和对应的类名是通过上面的getBean方法传入的。很明显,这种方式可以让Spring判断你需要创建哪个Bean(在Spring中也被称为component)第二点,我们还有一个getBean(User.class)来通过这种方式创建对象。更好的一点是开发人员可以偷懒一点,但这是有限度的。如果你在配置文件中声明了两个bean,并且这两个bean对应的Class名是相同的,都是同一个类的完全限定名,那么在运行时会报NoUniqueBeanDefinitionException//通过获取对象在这种方式不需要强制类型转换Personperson=ctx.getBean("Person",Person.class);//在当前的Spring配置文件中,只能有一个答案是:可以,但是你必须保证如果你要真正使用对象,那么这个bean必须是唯一的。第二个问题:既然上面bean的定义是OK的,那么Spring是否为它定义了“id值”呢?我们可以通过ctx.getBeanDefinitionNames()获取对应的id值来进行判断。我们会发现Spring其实会给只声明了类名的bean对应的id值。命名规则为:类的完全限定名+#+下标如:cn.paul.spring.demo.hellospring.entity.User#0我们要注意最后一个下标,为什么下标数组是0?难道有1、2、3……?事实上,我推测可能是这样的。我们可以在配置文件中配置多个只有类名的bean。spring也会给他们相应的默认id值(后面下标变化就是这样)b)只定义类名的bean的应用场景1>如果bean只需要使用一次,那么id值可以省略2>如果bean会被多次使用,或者被其他bean引用,则需要设置id值c)除了在bean标签中定义id和class属性外,name属性还可以定义作用name属性的作用:用于在Spring配置文件中为bean对象设置一个别名(小名)。根据我们的生活经验,我们知道真实姓名只能有一个(比如这里的id属性),但是我们可以有多个别名(比如这里的name属性,但是注意它只针对一个bean对象)问题:What是它和id属性的区别先说相同点吧:1.ctx.getBean("id|name")-->Object(可以通过id或者name创建对象)但是注意:可以定义多个name,用逗号隔开,但是不同的bean不能使用同一个别名2.等同于3.为什么会有名称属性?这是因为早期Spring集成Struts1的时候,bean的名字必须以/开头,但是早期的xml不允许id以/开头,所以说可以用名字来匹配这个特殊的名字。最后,随着技术的发展,现在xml也允许id以/开头,所以命名为属性或多或少都有历史的痕迹4、ctx工厂提供的方法ctx.containsBeanDefinition("stringname")只能判断是否有指定id的bean,不能判断name值,但是ctx.containsBean("stringname")不仅可以判断是否有指定id值的bean,还可以判断name值(所以以后尽量用这个,比较好记)Spring工厂的底层实现原理以上(简易版)1.Spring框架通过ClassPathXmlApplicationContext工厂读取配置文件applicationContext.xml2.获取配置文件tag的相关信息,比如id=account的值,class=cn的值.paul.entity.User3.通过反射创建对象Classclazz=Class。forName("类值");用户user=clazz.newInstance();4.注意一个问题,通过反射,可以创建一个构造函数被任意修饰符修饰的类的对象(复习爆破),知道反射底层其实是调用了这个类的构造方法,并且无参数构造Classclazz=Class.forName("classvalue");用户user=clazz.newInstance();相当于Useruser=newUser();思考:在spring的开发中,会不会所有的对象都由Spring工厂来创建?理论上来说,因为可以使用Spring工厂来解耦,所以确实可以通过工厂来创建。还有一些特殊情况,比如操作数据库的持久层DAO,或者实体不是Spring创建的,而是由mybatis等持久层框架创建的。毕竟实体是为操作数据库而生的,和数据库有映射关系