一. 什么是Spring

  1. Spring是一个轻量级开源的控制反转(IOC)和面向切面编程(AOP)的容器框架。

    (1) 轻量级:相对于重量级(框架设计比较繁琐,配置较多,例如EJB(tomcat不支持),现在基本不用了)而言,开发使用都比较简单,功能强大;

    (2) IOC(Inverse of control - 控制反转):将创建对象的权利和依赖关系维护(字段赋值)交给Spring容器(不再使用以前new关键字创建对象)。对于某个具体的对象而言,以前是它控制其他对象,现在是所有对象都被Spring控制,所以这叫控制反转;

    (3)AOP(Aspect Oriented Programming):将相同的逻辑抽取出来,即将业务逻辑从应用服务中分离出来。然后以拦截的方式作用在一个方法的不同位置。例如日志,事务的处理;

    (4)Spring底层原理:xml+dom4j+工厂设计模式+反射

二. Spring框架的好处

  1. 方便解耦,降低维护难度,提高开发效率(Spring相当于是一个大的工厂,它提供的IOC思想,可以将对象的创建和依赖关系维护都交给spring管理);
  2. spring支持AOP编程(spring提供面向切面编程,可以很方便的实现对程序进行权限拦截和运行监控等功能,可以将一些通用任务如安全、事务、日志等进行集中式管理,从而提供了更好的复用);
  3. 方便程序的测试(Spring 对junit4支持,可以通过注解测试Spring 程序,非常便捷);

三. Spring框架的模块化

  1. 模块化就是有组织地把一个大文件拆成独立并互相依赖的多个小模块;

  2. 图片

    image-20220802160457828

  3. Spring框架的功能大约由20个模块组成,这些模块按组可以分为:

    3.1 Core Container(核心容器):

    • Beans:负责Bean工厂中Bean的装配,所谓Bean工厂即是创建对象的工厂,Bean的装配也就是对象的创建工作;
    • Core:这个模块即是负责IOC(控制反转)最基本的实现;
    • Context:SpringIOC容器,因大量调用Spring Core中的函数,整合了Spring的大部分功能。Bean创建好对象后,由Context负责建立Bean与Bean之间的关系并维护。所以也可以把Context看成是Bean关系的集合;
    • SpEl:即Spring Expression Language(Spring表达式语言);
  4. AOP:面向切面;

    Aspects:同样是面向切面的一个重要的组成部分,提供对AspectJ框架的整合;

    image-20220802175237418

  5. 通常被Spring管理的类称之为Bean,在Spring容器中的对象称之为Bean对象;

  6. 依赖关系维护:DI(Dependency Injection)依赖注入。

四. 配置介绍

1
2
3
4
5
6
7
<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">

<bean id="myBean" class="com.coderyeah.MyBean"></bean>
</beans>
  • bean元素:表示对象配置或注册标签;

  • id属性:这个bean对象在Spring容器中的唯一标识,也可以使用name,常用id(唯一特性),获取这个对象的时候就可以通过这个表示来获取;

  • class属性:对应对象所属类的完全限定名。注意这里可以是JDK自带的类,也可以是自己新建的类;

  • 注意:Spring容器中不允许有两个名字【不管是id指定还是name指定】一个的对象。

五. Spring容器实例化

  1. Spring容器对象有两种:BeanFactoryApplicationContext(推荐使用)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    @Test
    public void test1() {
    //1.创建容器 加载配置文件
    Resource resource = new ClassPathResource("applicationContext.xml");
    //2.获取bean工厂 懒加载模式 淘汰了! 调用无参构造
    final BeanFactory factory = new XmlBeanFactory(resource);
    final User user = (User) factory.getBean("user");
    System.out.println(user);
    }
    1
    2
    3
    4
    5
    6
    7
    @Test
    public void test2() {
    //迫切加载 BeanFactory是ApplicationContext的父接口
    final ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
    final User user = app.getBean("user", User.class);
    System.out.println(user);
    }
  2. ApplicationContextBeanFactory的区别

    • ApplicationContextBeanFactory的子接口,拥有更多的功能与方法;
    • ApplicationContext默认是在读取配置文件的时候就会根据配置创建Bean对象(迫切加载)。而BeanFactory是在使用的时候才进行对象的创建(懒加载/延迟加载);
    • ApplicationContext实现懒加载配置:
      • ①让所有Bean都变成懒加载,只需要在标签中加入default-lazy-init="true"
      • ②让其中一个Bean变成懒加载,在标签中加入lazy-init="true"

六. Spring依赖注入

  1. 给Spring中对象的属性字段赋值,这称为依赖注入DI(Dependency Injection);

  2. xml注入:

    1
    2
    3
    4
    5
    6
    7
    8
    9
         <bean id="user1" class="com.lqs.domain.User"/>
    <!-- xml方式进行依赖注入 DI -->
    <bean id="myDataSource" class="com.lqs.domain.MyDataSource">
    <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
    <property name="url" value="jdbc:mysql://localhost:3306///test"/>
    <property name="username" value="root"/>
    <property name="password" value="123456"/>
    <property name="user" ref="user1"/>
    </bean>
  3. 注解注入:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    /*
    * 注解注入
    *
    * Autowired 直接通过类型去匹配,如果只有一个bean类型为User,就直接注入该bean
    * 如果有多个在匹配变量名字
    * Qualifier 当有类型,名字不一样的时候,该注解配合使用,找到对应的名字
    * Qualifier必须配合Autowired使用,不能单独使用
    */
    @Autowired
    @Qualifier("user1")
    private User user1;
    1
    2
    3
    @Resource //默认按照名字匹配【名字对了,类型也必须一致】,然后按照类型匹配
    //@Resource(name="otherBean1")//指定Bean的名称
    private OtherBean otherBean;

七. Spring测试

  1. 需要导入的jar包:

    **spring-test-4.1.2****.RELEASE.jar** 测试包

    **spring-aop-4.1.2.RELEASE.jar** AOP

  2. 注解

    • @RunWith:表示先启动Spring容器,把junit运行在Spring容器中;

    • @ContextConfiguration("classpath:applicationContext.xml"):表示从CLASSPATH路径去加载资源文件;

    • @Autowired:表示自动装配,自动从Spring容器中取出对应bean赋值给当前使用的属性。

      1
      2
      3
      4
      5
      6
      @RunWith(SpringJUnit4ClassRunner.class)//声明这是一个spring测试
      @ContextConfiguration("classpath:applicationContext.xml")//classpath:后面就是配置文件的路径
      public class SpringTest {
      @Autowired
      private MyDataSource myDataSource;
      }

八. 配置细节

  1. 通过Bean元素中的scope属性指定模式(默认单例):①singleton:默认值,单例;② prototype:多例。

  2. Bean对象的生命周期:

    (1)Bean对象的生命周期指的是:从对象创建、初始化、调用执行到销毁的一个过程;

    • Bean对象的实例化和初始化:

      ​ ① 实例化实质是Spring容器调用Bean的无参构造创建Bean对象;

      ​ ②初始化实质上是Spring容器调用指定的初始化方法;

      ​ ③BeanFactory管理的Bean默认是在使用的时候才创建Bean对象,即延迟加载,而AppliacationContext管理的Bean默认是在容器创建的时候就会创建Bean对象,即迫切加载。

    • Bean对象的销毁:

      ① 实质上是Spring容器调用指定的销毁方法(并不是真正意义上的销毁Bean对象);

      ② 在容器关闭的时候(ApplicationContext对象没有close方法,其实现类有),Spring

      容器会自动调用指定的销毁方法;

      image-20220802193022706

    2

九. mybatis高级查询, 将需要查询的条件封装成一个实体类。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<select id="queryByCondition" resultType="com.lqs.exam.domain.User">
<!--字符串不为null 并且不为空字符串-->
select *
from tb_user
<include refid="whereQuery"/>

</select>
<!-- 抽取公共sql id不为空唯一 -->
<sql id="whereQuery">
<where>
<if test="qname != null and !''.equals(qname.trim())">
<!--#过滤前后空格 -->
name=trim(#{qname})
</if>
<if test="qaddress != null and !''.equals(qaddress.trim())">
and address=trim(#{qaddress})
</if>
<if test="qtel != null and !''.equals(qtel.trim())">
or tel like concat('%',#{qtel},'%')
<!--tel like '%${qtel}%'-->
</if>
<if test="qid != null">
<!--and id &gt;#{qid}-->
and <![CDATA[id>#{qid}]]>
</if>
</where>
</sql>