欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Spring框架学习总结(上)

程序员文章站 2022-06-05 19:01:11
@[toc] 1、Spring的概述 在学习SSM框架中,我建议初学者最好先学Spring框架,其次mybatis接着springMVC,先学mybatis当然也是可以的,今天我们就以绝对优雅的姿态闯进Spring世界,系好安全带,准备好了吗,出发了哦!!!咳咳....平时开发接触最多的估计就是IO ......

@

1、spring的概述

在学习ssm框架中,我建议初学者最好先学spring框架,其次mybatis接着springmvc,先学mybatis当然也是可以的,今天我们就以绝对优雅的姿态闯进spring世界,系好安全带,准备好了吗,出发了哦!!!咳咳....平时开发接触最多的估计就是ioc容器,它可以装载bean(所谓的bean也就是我们java中的类,当然也包括servicedao里面),有了这个机制,我们就不用在每次使用这个类的时候为它初始化,很少看到键字new。另外spring的aop,事务管理等等都是我们经常用到的,可见spring的尤为重要的作用spring的核心是控制反转(ioc)和面向切面(aop)

1.1什么是spring

Spring框架学习总结(上)

肯定有熊dei会问se/ee开发的一站式框架所谓的一站式是什么意思,(哼,人类,我早就猜到你会问了)
所谓一站式框架指的是有ee开发的每一层解决方案。

web层 :springmvc

service层 :spring的bean管理,spring声明式事务

dao层 :spring的jdbc模板,spring的orm模块

1.2为什么学习spring

俗话说,人狠话不多(兄嘚看图)
Spring框架学习总结(上)

1.3spring的版本

spring3.x、spring4.x和spring5.x

1.4spring的体系结构

正所谓,人狠话不多(兄嘚看图)
Spring框架学习总结(上)

2、spring的入门(ioc)

2.1什么ioc

一说起ioc我就想起了武哥对ioc的理解的几个例子,可谓通俗易懂,非常适合刚入门spring的兄嘚!有兴趣的可以去了解了解武哥,武哥博客:https://blog.csdn.net/eson_15

ioc(inverse of control):控制反转,也可以称为依赖倒置。
控制反转:将对象的创建权反转给(交给)spring。

所谓依赖,从程序的角度看,就是比如a要调用b的方法,那么a就依赖于b,反正a要用到b,则a依

赖于b。所谓倒置,你必须理解如果不倒置,会怎么着,因为a必须要有b,才可以调用b,如果不倒

置,意思就是a主动获取b的实例:b b = new b(),这就是最简单的获取b实例的方法(当然还有各种

设计模式可以帮助你去获得b的实例,比如工厂、locator等等),然后你就可以调用b对象了。所

以,不倒置,意味着a要主动获取b,才能使用b;到了这里,就应该明白了倒置的意思了。倒置就是

a要调用b的话,a并不需要主动获取b,而是由其它人自动将b送上门来。

2.2通俗理解ioc

形象的举例就是:
通常情况下,假如你有一天在家里口渴了,要喝水,那么你可以到你小区的小卖部去,告诉他们,你需要一瓶水,然后小卖部给你一瓶水!这本来没有太大问题,关键是如果小卖部很远,那么你必须知道:从你家如何到小卖部;小卖部里是否有你需要的水;你还要考虑是否开着车去;等等等等,也许有太多的问题要考虑了。也就是说,为了一瓶水,你还可能需要依赖于车等等这些交通工具或别的工具,问题是不是变得复杂了?那么如何解决这个问题呢?
解决这个问题的方法很简单:小卖部提供送货上门服务,凡是小卖部的会员,你只要告知小卖部你需要什么,小卖部将主动把货物给你送上门来!这样一来,你只需要做两件事情,你就可以活得更加轻松自在:
第一:向小卖部注册为会员。
第二:告诉小卖部你需要什么。

这和spring的做法很类似!spring就是小卖部,你就是a对象,水就是b对象
第一:在spring中声明一个类:a
第二:告诉spring,a需要b

假设a是useraction类,而b是userservice类

<bean id="userservice" class="org.leadfar.service.userservice"/>
<bean id="documentservice" class="org.leadfar.service.documentservice"/>
<bean id="orgservice" class="org.leadfar.service.orgservice"/>
 
<bean id="useraction" class="org.leadfar.web.useraction">
     <property name="userservice" ref="userservice"/>
</bean>

在spring这个商店(工厂)中,有很多对象/服务:userservice,documentservice,orgservice,也有很多会员:useraction等等,声明useraction需要userservice即可,spring将通过你给它提供的通道主动把userservice送上门来,因此useraction的代码示例类似如下所示:

package org.leadfar.web;
public class useraction{
     private userservice userservice;
     public string login(){
          userservice.valifyuser(xxx);
     }
     public void setuserservice(userservice userservice){
          this.userservice = userservice;
     }
}

在这段代码里面,你无需自己创建userservice对象(spring作为背后无形的手,把userservice对象通过你定义的setuserservice()方法把它主动送给了你,这就叫依赖注入!),当然咯,我们也可以使用注解来注入。spring依赖注入的实现技术是:动态代理

2.3下载spring的开发包以及解压说明

官网下载:http://spring.io/
什么?不会下载?what???
好吧,已打包好了qaq:https://pan.baidu.com/s/18wye-5srwccu12ipox56pg
什么?没有网盘?what???
有事请烧香谢谢...

解压之后,文件说明:
docs :spring的开发规范和api
libs :spring的开发的jar和源码
schema :spring的配置文件的约束

2.4创建web项目,引入jar包

Spring框架学习总结(上)

2.5创建普通接口和实现类

创建普通接口,定义一个eat方法

package com.gx.sping;

public interface iuserdao {

    public void eat();
}

创建普通实现类

package com.gx.sping;

public class userdaoimpl implements iuserdao {
  @override
    public void eat() {
        // todo auto-generated method stub
        system.out.println(用户eat了");
    }
}

2.6spring的ioc底层实现原理

创建普通接口和类出现的问题:
如果底层的实现切换了,需要修改源代码,能不能不修改程序源代码对程序进行扩展?
重点来了,要想不改变源码,spring的ioc就能实现!如下图:spring的ioc底层实现
Spring框架学习总结(上)

2.7将实现类交给spring管理

1、在classpath下(也就是src)创建一个xml文件

2、文件名最好统一叫applicationcontext.xml

3、其xml文件的内容头为schema约束

4、约束文件位置在spring的解压路径下lspring-framework-4.2.4.release\docs\spring-framework-reference\html\xsd-configuration.htm

5、不要求xml文件的内容头能够背出来,但要了解的是你要知道它是怎么来的

6、xml文件的内容头添加后,将实现类交给spring管理
Spring框架学习总结(上)
Spring框架学习总结(上)
applicationcontext.xml配置文件如下

<?xml version="1.0" encoding="utf-8"?>
<beans 
    xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/xmlschema-instance"
    xsi:schemalocation="
        http://www.springframework.org/schema/beans 
        http://www.springframework.org/schema/beans/spring-beans.xsd">

 <!-- 实现类userdaoimpl交给spring管理 -->
     <bean id="iuserdao" class="com.gx.ioc.userdaoimpl" ></bean>
</beans>

Spring框架学习总结(上)

2.8编写测试类

package com.gx.ioc;

import org.junit.test;
import org.springframework.context.applicationcontext;
import org.springframework.context.support.classpathxmlapplicationcontext;

public class spingdemo1 {
    @test
    public void demo11() {
        // 面向接口传统方式
        userdaoimpl userdao = new userdaoimpl();
        userdao.eat();
    }
       //spring的bean管理方式
    @test
    public void demo22() {
        applicationcontext applicationcontext = new classpathxmlapplicationcontext("applicationcontext.xml");
        iuserdao userdao = (iuserdao) applicationcontext.getbean("iuserdao");
        userdao.eat();

    }

}

兄嘚,如果测试不成功最好看看二者是否对应!!!
Spring框架学习总结(上)
兄dei,到这里,spring的入门(ioc)算是入门了,是不是觉得很有成就感啊?

拉倒吧! 我都不好意思说了.(兄dei,我错了,是我飘了,呀呀呀,兄dei别打脸鸭qaq)

但是我依旧是阻止不了你骄傲的心.

那就顶我,让我感受感受你的骄傲!哈哈哈qaq

2.9 ioc和di

ioc不是什么技术,而是一种设计思想,ioc能指导我们如何设计出松耦合、更优良的程序。传统应用程序都是由我们在类内部主动创建依赖对象,从而导致类与类之间高耦合,难于测试;有了ioc容器后,把创建和查找依赖对象的控制权交给了spring容器,由容器进行注入组合对象,所以对象与对象之间是松散耦合,这样利于功能复用,更重要的是使得程序的整个体系结构变得非常灵活。
ioc:控制反转,将对象的创建权反转给了spring。
di:依赖注入,前提必须有ioc的环境,spring管理这个类的时候将类的依赖的属性注入(设置)进来。比如说下面讲到的spring的属性注入其实就是典型的di

所谓继承:is a

class a{

}
class b extends a{

}

所谓依赖:

class a{

}
class b{
    public void xxx(a a){

}
}

所谓聚合:has a

3、spring的工厂类

3.1spring工厂类的结构

Spring框架学习总结(上)

3.2老版本的工厂类:beanfactory

beanfactory:调用getbean的时候,才会生成类的实例。

3.3新版本的工厂类:applicationcontext

applicationcontext:加载配置文件的时候,就会将spring管理的类都实例化
applicationcontext有两个实现类
1、classpathxmlapplicationcontext :加载类路径下的配置文件
2、filesystemxmlapplicationcontext :加载文件系统下的配置文件

4、spring的配置

4.1xml的提示配置(schema的配置)

在xml文件中要使用各种标签来给spring进行配置,博主我这佩奇脑袋怎么可能记住spring中所有的标签呢,不怕不怕,博主我会配置xml的提示配置qaq,会了这一招就算兄dei你是乔治脑袋也不用担心(再说了我看兄dei各各英俊潇洒,玉树临风,聪明绝顶...咳咳,暴露了暴露了)
Spring框架学习总结(上)
Spring框架学习总结(上)
Spring框架学习总结(上)
Spring框架学习总结(上)

4.2bean的相关的配置(< bean >标签的id和name的配置)

id :使用了约束中的唯一约束。里面不能出现特殊字符的。上面提及到了要与getbean参数值对应

name :没有使用约束中的唯一约束(理论上可以出现重复的,但是实际开发不能出现的)。里面可以出现特殊字符。

4.3bean的生命周期的配置(了解)

init-method :bean被初始化的时候执行的方法
destroy-method :bean被销毁的时候执行的方法(bean是单例创建,工厂关闭)
Spring框架学习总结(上)

4.4bean的作用范围的配置(重点)

scope属性bean的作用范围

scope属性值如下(主要用的是前二者)
singletonscope属性的默认值,spring会采用单例模式创建这个对象。
prototype多例模式。(struts2和spring整合一定会用到)
request :应用在web项目中,spring创建这个类以后,将这个类存入到request范围中。
session :应用在web项目中,spring创建这个类以后,将这个类存入到session范围中。
globalsession :应用在web项目中,必须在porlet环境下使用。但是如果没有这种环境,相对于session。
Spring框架学习总结(上)
Spring框架学习总结(上)
Spring框架学习总结(上)

5、spring的属性注入

首先,创建几个普通类

com.gx.spring.demo.car
public class car {
    private string name;
    private double price;
    
    public car(string name, double price) {
        super();
        this.name = name;
        this.price = price;
    }
    @override
    public string tostring() {
        return "car [name=" + name + ", price=" + price + "]";
    }
}
com.gx.spring.demo.car2
/**
 * 用作set方法的属性注入类
 */
public class car2 {
    private string name;
    private double price;
    public void setname(string name) {
        this.name = name;
    }
    public void setprice(double price) {
        this.price = price;
    }
    @override
    public string tostring() {
        return "car2 [name=" + name + ", price=" + price + "]";
    }
    
}
com.gx.spring.demo.person 
/**
 * 用作set方法的对象属性注入类
 */
public class person {
    private string name;
    private car2 car2;
    public void setname(string name) {
        this.name = name;
    }
    public void setcar2(car2 car2) {
        this.car2 = car2;
    }
    @override
    public string tostring() {
        return "employee [name=" + name + ", car2=" + car2 + "]";
    }
}

5.1构造方法的方式的属性注入

构造方法的属性注入
constructor-arg 标签用于配置构造方法的属性注入
name :参数的名称
value:设置普通数据
ref:引用数据,一般是另一个bean id值

当然了,构造方法的方式的属性注入也支持对象属性的注入,标签中对应属性也是ref
如果只有一个有参数的构造方法并且参数类型与注入的bean类型匹配,那就会注入到该构造方法中

applicationcontext.xml中配置:

<!-- 构造方法的方式 -->
    <bean id="car" class="com.gx.spring.demo.car">
        <constructor-arg name="name" value="玛莎拉蒂"/>
        <constructor-arg name="price" value="800000"/>
    </bean>

测试方法:

    /**
     * 构造方法方式的普通属性注入方法
     */
    public void demo1(){
        applicationcontext applicationcontext = new classpathxmlapplicationcontext("applicationcontext.xml");
        car car = (car) applicationcontext.getbean("car");
        system.out.println(car);
    }

5.2set方法的方式的属性注入【开发常用】

set方法的普通属性注入
property 标签用于配置set方法的属性注入
name :参数的名称
value:设置普通数据
ref:引用数据,一般是另一个bean id值

applicationcontext.xml中配置:

<!-- set方法的方式 -->
<bean id="car2" class="com.gx.spring.demo.car2">
        <property name="name" value="法拉利黄金跑车"/>
        <property name="price" value="10000000"/>
</bean> 

测试方法:

@test
    /**
     * set方法方式的属性注入
     */
    public void demo2(){
        applicationcontext applicationcontext = new classpathxmlapplicationcontext("applicationcontext.xml");
        car2 car2 = (car2) applicationcontext.getbean("car2");
        system.out.println(car2);
    }

set方法设置对象类型的属性
applicationcontext.xml中配置:

<!-- set方法注入对象类型的属性 -->
<bean id="person" class="com.gx.spring.demo.person">
            <!-- value:设置普通类型的值,ref:设置其他的类的id或name-->
        <property name="name" value="涛哥"/>
        <property name="car2" ref="car2"/>
    </bean> 

测试方法:

@test
    /**
     * set方法注入对象类型
     */
    public void demo3(){
        applicationcontext applicationcontext = new classpathxmlapplicationcontext("applicationcontext.xml");
        person person= (person) applicationcontext.getbean("person");
        system.out.println(person);
    }

5.3注解的方式属性注入【开发常用】

@component (作用在类上通用:组件)
@component(“userservice”)相当于< bean id=”userservice” class=”...”>

衍生:
@controller web层
@service 业务层
@repository 持久层
这三个注解是为了让标注类本身的用途清晰

属性注入的注解 ( 可以没有set方法
普通类型属性:@value

对象类型属性:@resource对应bean中的id)= @autowired(类型)+ @qualifier(名称)
Spring框架学习总结(上)

5.3.1注解的理解

额,初学框架,注解二字可能对于大部分熊dei来说,太过于陌生,注解其实就是在一个类、方法、属性上,使用@注解名称,就比如是我们最熟悉的接实现口中的方法默认会有一个 @override (熊dei,这样理解能接受?)
Spring框架学习总结(上)

5.3.2注解的jar包导入

spring3.x注解的jar包
在spring3.x的版本中,使用注解开发,只需要 spring核心基础四包外 + log4j包 + 1个依赖包 即可
Spring框架学习总结(上)
spring4.x注解的jar包
然而在spring4.x版本之后则需在 再添加一个要引入 spring-aop 的 jar 包,因为,spring4.x版本中一些注解的依赖方法封装在spring-aop 的 jar 包中
Spring框架学习总结(上)

5.3.3引入注解的context约束

所谓约束就是就是就是约束啦(搽汗),其中bean约束是最基本的约束!(下图也可以看出)
Spring框架学习总结(上)
引入约束:(引入 context 的约束):

<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/xmlschema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemalocation="
http://www.springframework.org/schema/beans 
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context 
http://www.springframework.org/schema/context/spring-context.xsd">
</beans>
5.3.4编写相关的类
public interface userdao {
public void sayhello();
}
public class userdaoimpl implements userdao {
@override
public void sayhello() {
system.out.println("hello spring...");
} }
5.3.5配置注解扫描

spring的注解开发:组件扫描(不使用类上注解的时候可以不用组件扫描
使用注解方式,需要开启组件扫描< context:component-scan base-package=直接包名或者包名.类名/>,当然开发中一般都是base-package=包名,毕竟这样可以扫描整个包,方便开发
spring 的注解开发:组件扫描(类上注解: 可以直接使用属性注入的注解)

<!-- spring 的注解开发:组件扫描(类上注解: 可以直接使用属性注入的注解) -->
<context:component-scan base-package="com.gx.spring.demo1"/>
5.3.6 在相关的类上添加注解

1、使用类上注解方式@component(value=“userdao”),相当于< bean id="userdao class="com.gx.类名">< /bean>
当然value属性名可以省去直接@component("userdao"),当然@component(“value值任意写建议取的要有意义”)
2、注解方式可以没有set方法
Spring框架学习总结(上)

@component(value="userdao")  //相当于配置了<bean id="userdao" class="com.gx.userdaoimpl "></bean>
public class userdaoimpl implements userdao {
@override
public void sayhello() {
system.out.println("hello spring annotation...");
} }
5.3.7 编写测试类
@test
public void demo3() {
applicationcontext applicationcontext = new classpathxmlapplicationcontext("applicationcontext.xml");
userdao userdao = (userdao) applicationcontext.getbean("userdao");
userdao.sayhello();
}

5.4p名称空间的属性注入(spring2.5以后)

通过引入p名称空间完成属性的注入:
写法:
普通属性 p:属性名=”值”
对象属性 p:属性名-ref=”值”

p名称空间的约束引入
Spring框架学习总结(上)
使用p名称空间
Spring框架学习总结(上)

5.5 spel的属性注入(spring3.0以后)

spel:spring expression language,spring的表达式语言。
语法: #{spel}
Spring框架学习总结(上)

5.6集合类型属性注入(了解)

集合类型属性配置:
集合的注入都是在< property>标签中添加子标签
数组:< array >
list:< list >
set:< set >
map:< map > ,map存放k/v 键值对,使用描述
properties:< props> < prop key="">< /prop>
普通数据:< value >
引用数据:< ref >

    <!-- spring的集合属性的注入============================ -->
    <!-- 注入数组类型 -->
    <bean id="collectionbean" class="com.gx.spring.demo.collectionbean">
        <!-- 数组类型 -->
        <property name="arrs">
            <list>
                <value>天才</value>
                <value>王二</value>
                <value>冠希</value>
            </list>
        </property>
        
        <!-- 注入list集合 -->
        <property name="list">
            <list>
                <value>李兵</value>
                <value>赵如何</value>
                <value>邓凤</value>
            </list>
        </property>
        
        <!-- 注入set集合 -->
        <property name="set">
            <set>
                <value>aaa</value>
                <value>bbb</value>
                <value>ccc</value>
            </set>
        </property>
        
        <!-- 注入map集合 -->
        <property name="map">
            <map>
                <entry key="aaa" value="111"/>
                <entry key="bbb" value="222"/>
                <entry key="ccc" value="333"/>
            </map>
        </property>
    </bean>

6、spring的分模块开发的配置

分模块配置:
在加载配置文件的时候,加载多个,没错,这就是传说中的骚操作,堪称开挂级别的操作(当然,这是可以的不是开挂)
Spring框架学习总结(上)
在一个配置文件中引入多个配置文件,简直优秀!!!
Spring框架学习总结(上)
到这里,恭喜恭喜,各位熊dei以优雅的仪式感闯进spring世界,对spring的ioc以及di有了一定了解了,是不是也很期待spring的aop呐,毕竟spring的核心是控制反转(ioc)和面向切面(aop)。

【spring框架学习二】spring的aop通俗理解以及aop的入门开发(哎哎,别打..别打..别打脸....)

如果本文对你有一点点帮助,就请点个赞呗,手留余香,谢谢!

最后,欢迎各位关注我的公众号,一起探讨技术,向往技术,追求技术...

Spring框架学习总结(上)