Spring学习笔记

首先,感谢一下@狂神老师的Spring课程https://www.bilibili.com/video/BV1WE411d7Dv?spm_id_from=333.999.0.0

其次,感谢一下@黑心白莲同学的笔记https://blog.csdn.net/li643937579/article/details/109569887

前言:这一阶段的学习,主要注重思想上的学习,重点关注的是IOC和AOP,以及静态代理或者动态代理设计模式的学习

1、Spring概述

1.1 简介

  • spring:春天:也就是说给软件行业带来了春天
  • 官网 : http://spring.io/
  • 官方的参考文档:https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#beans-factory-scopes

1.2 优点

  • Spring是一个开源免费的框架、容器
  • Spring是一个轻量级的框架 , 非侵入式的
  • Spring的核心就是IOC和AOP

1.3 IOC

  • 控制翻转。通俗的来讲就是创建对象的方式不同,不用创建对象了,通过bean,已经Spring的容器技术自动的对其进行装配

1.4 APO

  • 面向切面编程
  • 通过使用Spring AOP,不用依赖组件,就可以将声明性事务管理集成到应用程序中

1.5 拓展

Springboot和Spring Cloud

  • Spring boot 是Spring 的一套快速配置脚手架,可以基于Spring Boot 快速开发单个微服务
  • Spring Cloud是基于Spring Boot实现的
  • SpringBoot在SpringClound中起到了承上启下的作用,如果要学习SpringCloud必须要学习 SpringBoot
  • 同样的道理,学习Springboot首先需要学习Spring 和SpringMVC(过度的承上启下作业)

2、IOC基础

2.1 需要的依赖包

<dependencies>
        <!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>5.2.0.RELEASE</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>5.2.0.RELEASE</version>
        </dependency>
        <!--junit测试工具包-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver  -->
        <!--使用AOP织入,需要导入一个依赖包-->
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.9.4</version>
        </dependency>

2.2 IOC的本质

  • 以前程序是主动创建对象,控制权在业务层,也就是在程序员的手上

  • 在这里插入图片描述

  • 现在可以交出程序的控制权,到用户的手上
    -在这里插入图片描述

  • IOC本质

个人认为控制反转就是:获得依赖对象的方式变了

采用XML方式配置Bean的时候,Bean的定义信息是和实现分离的,而采用注解的方式可以把两者合为一体,Bean的定义信息直接以注解的形式定义在实现类中,从而达到了零配置的目的。

控制反转是一种通过描述(XML或注解)并通过第三方去生产或获取特定对象的方式。在Spring中实现控制反转的是IoC容器,其实现方法是依赖注入(Dependency Injection,DI)。

3、HelloSpring

​ 对应程序是 Spring-02-hello

1. 新建一个Maven项目,编写实体类
package com.qin.dao;

public class Hello {
    private String str;

    public String getStr() {
        return str;
    }
    // spring 本质上是通过set方法进行注入的
    public void setStr(String str) {
        this.str = str;
    }

    @Override
    public String toString() {
        return "Hello{" +
                "str='" + str + '\'' +
                '}';
    }
}

2. 编写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
        https://www.springframework.org/schema/beans/spring-beans.xsd">
<!--
    使用Spring来创建对象,在Spring中这些称为Bean
    类型 变量名 = new 类型();

    id 相当于一个变量名
    class =new 一个对象
    property 相当于给对象中的属性设置一个值!

-->
    <bean id="hello" class="com.qin.dao.Hello">
        <property name="str" value="Spring!!!"/>
    </bean>


</beans>
3. 测试
import com.qin.dao.Hello;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MyTest {
    public static void main(String[] args) {
        // 第一步CPX 加载XML的配置文件
        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        // 第二步 getbean 获取bean的对象
        Hello hello = (Hello) context.getBean("hello");
        // 打印输出结果
        System.out.println(hello.toString());
    }
}

思考问题:

  • Hello对象由谁创建?(Spring创建的)
  • Hello对象的属性是怎么设置的?(Spring的容器设置的)

这个过程就叫做控制反转

控制:谁来控制对象的创建,传统应用程序的对象是由程序本身控制创建的,使用Spring后,对象是由Spring来创建的。

反转:程序本身不创建对象,而变成被动的接收对象。

依赖注入:就是利用set方法来进行注入的。

OK,到了现在,我们彻底不用在程序中去改动了,要实现不同的操作,只需要在xml配置文件中进行修改,所谓的IOC,一句话搞定:对象由Spring来创建,管理,装配!

总结:所谓的IOC是,对象由Spring来创建,管理和装配!

4、IOC创建对象的方式

对应的程序Spring-02-IOC

4.1 使用无参构造函数创建对象,默认的方式

1. User类
package com.qin.dao;

public class User {
    private String name;

    public User(){
        System.out.println("User的无参构造函数");

    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
    public void show(){
        System.out.println("name="+name);
    }
}

​ 2、UserT类

package com.qin.dao;

public class UserT {

    private String name;

    public UserT(String name){
        this.name = name;
        System.out.println("UserT的有参构造");

    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
    public void show(){
        System.out.println("name="+name);
    }
}

​ 3.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
        https://www.springframework.org/schema/beans/spring-beans.xsd">
<!--
    使用Spring来创建对象,在Spring中这些称为Bean
    类型 变量名 = new 类型();

    id 相当于一个变量名
    class =new 一个对象
    property 相当于给对象中的属性设置一个值!

-->

<!--    bean在创建对象的时候,默认调用无参的构造函数
        如果调用有参的构造函数,需要换一种方法初始化
-->
    <bean id="user" class="com.qin.dao.User">
        <property name="name" value="qinqs"/>
    </bean>
<!--    有参的构造函数,bean初始化对象 注意:属性的赋值的方式不一样-->
    <bean id="userT" class="com.qin.dao.UserT">
        <constructor-arg name="name" value="qinqsTTT"/>
    </bean>

<!--    总结:
        在beans.xml配置文件加载的时候,容器中管理的对象就已经初始化了!
-->
4. 测试类
import com.qin.dao.User;
import com.qin.dao.UserT;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MyTest {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        User user = context.getBean("user", User.class);
        user.show();
        // UserT userT = (UserT) context.getBean("userT");
        // userT.show();
    }
}

4.2 使用有参构造创建对象的时候

  • 注意:在bean给属性赋值的时候,选用的参数不一样
  • 通过实验分析可以得出一个结论:在XML配置文件加载的时候,容器中管理的对象就自动的创建了。

5、Spring的配置

5.1 别名

<!--设置别名:在获取Bean的时候可以使用别名获取-->
<alias name="userT" alias="userNew"/>

5.2 Bean的配置

<!--bean就是java对象,由Spring创建和管理-->
<!--
id 是bean的标识符,要唯一,如果没有配置id,name就是默认标识符
如果配置id,又配置了name,那么name是别名
name可以设置多个别名,可以用逗号,分号,空格隔开
如果不配置id和name,可以根据applicationContext.getBean(.class)获取对象;
class是bean的全限定名=包名+类名
-->
<bean id="hello" name="hello2 h2,h3;h4" class="com.kuang.pojo.Hello">
<property name="name" value="Spring"/>
</bean>

5.3 import

  • 团队的协同开发中可以用到这个功能
  • 命名applicationContext.xml (使用的时候,直接调用这个配置就可以了)
<import resource="bean.xml"/>
<import resource="bean2.xml"/>
<import resource="bean3.xml"/>

6、依赖注入(DI)

对应的练习程序为Spring-04-ID

  • 依赖注入(Dependency Injection,DI)
  • 依赖:指Bean对象的创建依赖于容器
  • 注入:指Bean对象所需要依赖的资源,由容器来设置和装配

6.1 构造器注入

  • 4中IOC创建对象的方式(有参构造已经用过了)
<bean id="userT" class="com.qin.dao.UserT">
     <constructor-arg name="name" value="qinqsTTT"/>
</bean>

6.2 set注入(重点)

  • 要求被注入的属性,必须有set方法

  • 测试的pojo类(注意,要注入的熟悉中,都有需要的set方法)

    Address.class

    package com.qin.pojo;
    
    public class Address {
        private String address;
    
        public String getAddress() {
            return address;
        }
    
        public void setAddress(String address) {
            this.address = address;
        }
    
        @Override
        public String toString() {
            return "Address{" +
                    "address='" + address + '\'' +
                    '}';
        }
    }
    

    Student.class

    package com.qin.pojo;
    
    import java.util.*;
    
    public class Student {
        private String name;
        private Address address;
        private String[] books;
        private List<String> hobbies;
        private Map<String,String> card;
        private Set<String> games;
        private String wife;
        private Properties info;
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public Address getAddress() {
            return address;
        }
    
        public void setAddress(Address address) {
            this.address = address;
        }
    
        public String[] getBooks() {
            return books;
        }
    
        public void setBooks(String[] books) {
            this.books = books;
        }
    
        public List<String> getHobbies() {
            return hobbies;
        }
    
        public void setHobbies(List<String> hobbies) {
            this.hobbies = hobbies;
        }
    
        public Map<String, String> getCard() {
            return card;
        }
    
        public void setCard(Map<String, String> card) {
            this.card = card;
        }
    
        public Set<String> getGames() {
            return games;
        }
    
        public void setGames(Set<String> games) {
            this.games = games;
        }
    
        public String getWife() {
            return wife;
        }
    
        public void setWife(String wife) {
            this.wife = wife;
        }
    
        public Properties getInfo() {
            return info;
        }
    
        public void setInfo(Properties info) {
            this.info = info;
        }
    
        @Override
        public String toString() {
            return "Student{" +
                    "name='" + name + '\'' +
                    ", address=" + address +
                    ", books=" + Arrays.toString(books) +
                    ", hobbies=" + hobbies +
                    ", card=" + card +
                    ", games=" + games +
                    ", wife='" + wife + '\'' +
                    ", info=" + info +
                    '}';
        }
    }
    
    

    Mytest.class 测试类

    import com.qin.pojo.Student;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    public class MyTest {
        public static void main(String[] args) {
            ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
            Student student = (Student) context.getBean("student");
            System.out.println(student.toString());
        }
    }
    

    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
            https://www.springframework.org/schema/beans/spring-beans.xsd">
        
        <bean id="address" class="com.qin.pojo.Address">
            <property name="address" value="兰州"/>
        </bean>
        <bean id="student" class="com.qin.pojo.Student">
            <!--第一种,普通值注入-->
            <property name="name" value=""/>
            <!--第二种,bean注入-->
            <property name="address" ref="address"/>
    		<!--数组注入-->
            <property name="books">
                <array>
                    <value>红楼梦</value>
                    <value>西游记</value>
                    <value>三国演义</value>
                    <value>水浒传</value>
                </array>
            </property>
    		<!--list注入-->
            <property name="hobbies">
                <list>
                    <value>打篮球</value>
                    <value>踢足球</value>
                    <value>敲代码</value>
                </list>
            </property>
    		<!--map注入-->
            <property name="card">
                <map>
                    <entry key="身份证" value="1234"></entry>
                    <entry key="银行卡" value="789456"></entry>
                </map>
            </property>
    		<!--set注入-->
            <property name="games">
                <set>
                    <value>LOLO</value>
                    <value>CCO</value>
                </set>
            </property>
    		<!--null注入-->
            <property name="wife">
                <null></null>
            </property>
    		<!--Properties-->
            <property name="info">
                <props>
                    <prop key="urel">123</prop>
                    <prop key="pass">hhhhh</prop>
                </props>
            </property>
    
        </bean>
       
    </beans>
    

6.3 拓展方式注入(p命名空间和c命名空间)

  • P 命名空间的注入和C命名空间的使用,需要引入约束文件
  • P命名空间,适用于无参构造,对应properties
  • C命名空间,适用于有参构造,对应于Constructor
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:c="http://www.springframework.org/schema/c"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd">

    <!--p命名空间注入,可以直接注入属性的值:property-->
    <bean id="user" class="com.kuang.pojo.User" p:name="qin" p:age="20"/>

    <!--c命名空间注入,通过构造器注入:constructor-args-->
    <bean id="user2" class="com.kuang.pojo.User" c:name="狂神" c:age="22"/>

</beans>

6.4 Bean 的作用域

在这里插入图片描述

  • singleton单例模式(Spring默认的机制)

    <bean id="user2" class="com.kuang.pojo.User" c:name="狂神" c:age="22" scope="singleton"/>
    

​ 单例模型,每次产生的对象都是一样的

  • prototyper原型模型

    <bean id="user2" class="com.kuang.pojo.User" c:name="狂神" c:age="22" scope="prototype"/>
    

    每次从容器中getbean的时候,都会产生一个新的对象

7、Bean的自动装配(重点)

对应的练习程序为Spring-05-auto

  • 自动装配是Spring满足bean依赖的一种方式
  • Spring会在上下文中自动寻找,并给bean装配属性

在Spring中有三种装配的方式:

1. 在XML中显示的配置
1. 在java中显示的配置
1. 饮食的自动装配bean【重要】

7.1默认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"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        https://www.springframework.org/schema/context/spring-context.xsd">

        <context:annotation-config/>

    <bean id="cat" class="com.qin.pojo.Cat"></bean>
    <bean id="dog" class="com.qin.pojo.Dog"></bean>
    <bean id="user" class="com.qin.pojo.User" >
        <property name="cat" ref="cat"/>
        <property name="dog" ref="dog"/>
        <property name="name" value="qin"/>
    </bean>

</beans>

7.2 ByName自动装配

  • autowire byName(按名称自动装配)
<?xml version="1.0" encoding="UTF-8"?>
<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
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        https://www.springframework.org/schema/context/spring-context.xsd">

        <context:annotation-config/>

    <!--
       byName:会自动在容器上下文中查找,和自己对象set方法后面的值对应的bean id!
           -->


    <bean id="cat" class="com.qin.pojo.Cat"></bean>
    <bean id="dog" class="com.qin.pojo.Dog"></bean>
    <bean id="user" class="com.qin.pojo.User" autowire="byName">
        <property name="name" value="qin"/>
    </bean>

</beans>

7.3 ByType自动装配

  • autowire byType(按类型自动装配)
<?xml version="1.0" encoding="UTF-8"?>
<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
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        https://www.springframework.org/schema/context/spring-context.xsd">
    
		<!--开启注解的支持!!!-->
        <context:annotation-config/>

    <!--
        byType:会自动在容器上下文中查找,和自己对象属性类型相同的bean!
        必须保证全局唯一!!!
            -->

    <bean id="cat" class="com.qin.pojo.Cat"></bean>
    <bean id="dog" class="com.qin.pojo.Dog"></bean>
    <bean id="user" class="com.qin.pojo.User" autowire="byType">
        <property name="name" value="qin"/>
    </bean>

</beans>

小结:

  • ByName的时候,会自动在容器上下文中查找,和自己对象set方法后面的值对应的bean id!
  • ByType的时候,会自动在容器上下文中查找,和自己对象属性类型相同的bean!且必须保证全局唯一!!!

7.4 使用注解实现自动装配

  • jdk1.5支持的注解,Spring2.5就支持注解了!

  • 使用注解开发的时候,需要导入约束的头文件,并开启注解的支持!需要context的支持

    <?xml version="1.0" encoding="UTF-8"?>
    <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
            https://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/context
            https://www.springframework.org/schema/context/spring-context.xsd">
    
        <context:annotation-config/>
    
    </beans>
    
  • 在大部分的情况下,我们都会选用注解开发,尤其是在后期的SpringBoot中

  • Autowired的注解

    1. xml的配置只需要开启支持注解,然后注册bean,会变的非常的干净
    <?xml version="1.0" encoding="UTF-8"?>
    <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
            https://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/context
            https://www.springframework.org/schema/context/spring-context.xsd">
    
            <context:annotation-config/>
        <bean id="cat" class="com.qin.pojo.Cat"></bean>
        <bean id="dog" class="com.qin.pojo.Dog"></bean>
        <bean id="user" class="com.qin.pojo.User"></bean>
    
    </beans>
    
    1. User.class
    package com.qin.pojo;
    
    
    import org.springframework.beans.factory.annotation.Autowired;
    
    public class User {
        // Autowired的注解,在属性上可以使用,在set方法上也可以直接使用
        // 使用Autowired的注解,本质上利用的是反射的实现,连set方法也可以省略不要
        // 使用Autowired的注解,XML配置可以变的很干净,只需要注册bean,不需要装配属性
        @Autowired  // Autowired的注解,在属性上
        private Cat cat;
        @Autowired
        private Dog dog;
        private String name;
    
        public Cat getCat() {
            return cat;
        }
    
        public void setCat(Cat cat) {
            this.cat = cat;
        }
    
        public Dog getDog() {
            return dog;
        }
    
        public void setDog(Dog dog) {
            this.dog = dog;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        @Override
        public String toString() {
            return "com.qin.pojo.User{" +
                    "cat=" + cat +
                    ", dog=" + dog +
                    ", name='" + name + '\'' +
                    '}';
        }
    }
    
    1. 使用Autowired我们就可以不用编写set方法了,前提是你这个自动配置的属性在IOC(Spring)容器中存在,且符合名字byName!(本质上是,使用byType自动进行装配的!!!)
  • Qualifier注解(不能单独使用,必须配合autowire的注解使用)

    1. 如果@Autowired自动装配的时候环境比较复杂,自动装配无法通过一个注解【@Autowired】来完成的时候【本质上是通过byType来完成的注解】,我们可以通过【@Qualifier(value=“xxx”)】来配合@Autowired的使用

    2. 本质:@Autowired是根据类型自动装配的,加上@Qualifier则可以根据byName的方式自动装配;@Qualifier不能单独使用。

    3. 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"
             xmlns:context="http://www.springframework.org/schema/context"
             xsi:schemaLocation="http://www.springframework.org/schema/beans
              https://www.springframework.org/schema/beans/spring-beans.xsd
              http://www.springframework.org/schema/context
              https://www.springframework.org/schema/context/spring-context.xsd">
      
              <context:annotation-config/>
      
          <bean id="cat" class="com.qin.pojo.Cat"></bean>
          <bean id="dog" class="com.qin.pojo.Dog"></bean>
          <bean id="dog1" class="com.qin.pojo.Dog"></bean>
          <bean id="dog2" class="com.qin.pojo.Dog"></bean>
          <bean id="user" class="com.qin.pojo.User"></bean>
      
      </beans>
      
      
    4. User.calss

      package com.qin.pojo;
      
      
      import org.springframework.beans.factory.annotation.Autowired;
      import org.springframework.beans.factory.annotation.Qualifier;
      
      public class User {
          // Autowired的注解,在属性上可以使用,在set方法上也可以直接使用
          // 使用Autowired的注解,本质上利用的是反射的实现,连set方法也可以省略不要
          // 使用Autowired的注解,XML配置可以变的很干净,只需要注册bean,不需要装配属性
          @Autowired  // Autowired的注解,在属性上
          private Cat cat;
          @Autowired
          @Qualifier(value = "dog1")  // Qualifier注解配合Autowired注解的使用,来增强bean的自动装配
          private Dog dog;
          private String name;
      
          public Cat getCat() {
              return cat;
          }
      
          public void setCat(Cat cat) {
              this.cat = cat;
          }
      
          public Dog getDog() {
              return dog;
          }
      
          public void setDog(Dog dog) {
              this.dog = dog;
          }
      
          public String getName() {
              return name;
          }
      
          public void setName(String name) {
              this.name = name;
          }
      
          @Override
          public String toString() {
              return "com.qin.pojo.User{" +
                      "cat=" + cat +
                      ", dog=" + dog +
                      ", name='" + name + '\'' +
                      '}';
          }
      }  
      
  • Resource注解

    1. Resource注解的使用,也是直接放在属性的字段上面

      @Resource
      private Cat cat;
      @Resource
      private Dog dog;
      private String name;
      
    2. Autowired和Resource的区别

      • 相同点:都是用来实现bean的自动装配的
      • 区别1:Autowired通过byType的方式实现,而且必须要求这个对象存在,如果遇到复杂的情况,可以配合Qualifier注解来使用。【常用】
      • 区别2:Resource默认通过byName的方式实现,如果找不到名字,则自动的通过byType的方式实现,如果两个都找不到,则就报错。需要注意的是,如果name属性一旦指定,就只会按照名称ByName进行装配。【常用】

7.5 小结

  • @Autowired与@Resource都可以用来装配bean。都可以写在字段上,或set方法上。
  • 它们的作用相同都是用注解方式注入对象,但执行顺序不同。@Autowired先byType,@Resource先 byName(Resource的功能更加的强大)。
  • @Autowired 是Spring的注解 ,@Resource 是java的注解

8、使用注解开发(重点)

对应的练习程序为:Spring-06-anno

使用注解开发,必须导入AOP包,同时使用注解的时候,要在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"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        https://www.springframework.org/schema/context/spring-context.xsd">
    <!--指定要扫描的包,在这个包下的注解就会生效,包的位置可以进行更改-->
    <context:component-scan base-package="com.qin.pojo"/>
    <context:annotation-config/>
    <!--开启注解驱动的支持-->

</beans>
  1. bean(@Component注解来注册bean)

    package com.qin.pojo;
    
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.stereotype.Component;
    
    // 这个注解就等价于 <bean id="user" class="com.qin.pojo.User">
    // @Component 代表的是组件
    @Component // 一般情况下放在类上,说明这个类被Spring管理了
    public class User {
        @Value("哈哈") // 这个等价于属性的注入    <property name="name" value="秦疆"/>
        public  String name;
    }
    
    
  2. 属性如何注入

    // 这个注解就等价于 <bean id="user" class="com.qin.pojo.User">
    // @Component 代表的是组件
    @Component
    public class User {
        @Value("哈哈") // 这个等价于属性的注入    <property name="name" value="秦疆"/>
        public  String name;
    }
    
  3. 衍生的注解

    @Component的有几个衍生的注解,我们在web的开发中,会按照MVC三成架构来进行分层

    • dao层【@Repository】

    • service层【@Service】

    • web层【@Controller】

      这四个注解的功能都是一样的,都是将某个类注册到Spring中的容器中,进行装配

  4. 自动装配

    • @Autowired
    • @Qualifier
    • @Resource
  5. 作用域

    • @Scope(“singleton”) 有单例模式和原型模式
  6. XML和注解

    • XML更加的万能,适用于任何场合,维护简单方便!
    • 注解不是自己的类使用不了,维护相对复杂!
    • 最佳实践:
      • xml用来管理bean
      • 注解只负责完成属性的注入
      • 我们在使用的过程中,只需要注意一个问题,必须让注解生效,就需要开启注解的支持

9、使用Java的方式配置Spring

对应的练习程序为:Spring-07-anno2

本质上,使用的还是注解

现在我们完全不使用XML进行配置了,全权交给Java来进行配置

本质就是:用一个配置类来代替原来的XML来实现bean的注册的装配

User.class

package com.qin.pojo;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

// 注解的意思是,说明这个类完全呗Spring接管了,注册到容器中了
@Component
public class User {
    @Value("qin") // 给属性注入值
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                '}';
    }
}

Myconfig.class

package com.qin.config;

import com.qin.pojo.User;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

// 现在我们完全不需要Spring的xml配置信息了,全权交给Java来做

// @Configuration 代表的这是一个配置类,和原来的beans.xml道理一样
@Configuration
public class Myconfig {

    @Bean // 注册一个bean  方法的名字就相当于bean标签中的id属性
    public User user(){
        return new User();
        // 返回值相当于bean标签中的class属性
    }

    // 总结:这种用java来接管的配置,在SpringBoot中随处可见
}

Mytest.class测试类

import com.qin.config.Myconfig;
import com.qin.pojo.User;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class MyTest {
    public static void main(String[] args) {
        // 如果完全使用了配置类方式去做,我们就只能通过 AnnotationConfig 上下文来获取容器,
        // 通过配置类的class对象加载!
        ApplicationContext context = new AnnotationConfigApplicationContext(Myconfig.class);

        User user = (User) context.getBean("user");

        System.out.println(user.getName());
    }
}

总结:这种用java来接管的配置,在SpringBoot中随处可见!!!Spring完全可以摒弃XML的配置!!!

10、AOP(面向切面编程)

AOP的实现本质上利用的是代理模式(静态代理和动态代理)----代理的是接口

对应的程序为Spring-09-aop

再不改变原有的业务的情况下,添加新的功能(比如添加日志)!

10.1 什么是AOP

AOP(Aspect Oriented Programming)意为:面向切面编程,通过预编译方式和运行期动态代理实现 程序功能的统一维护的一种技术。AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的 一个重要内容,是函数式编程的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使 得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。

通俗的来讲:AOP就是在不改变原有逻辑的情况下,添加新的功能,如:日志、安全、缓存、事务等等!!!

10.2 AOP在Spring中的应用

  • 横切关注点:通俗的讲就是,在不改变原有逻辑的情况下,执行添加新功能的点!

  • 切面:自定义的一个类,后面还需要关注点和通知

  • 通知:切面必须要完成的工作,通俗的讲就是类中的一个方法

-在这里插入图片描述

  • Spring支持五种通知:

    1、前置通知 2、后置通知 3、环绕通知 4、异常抛出通知 5、引介入通知

  • 总结:AOP就是在不改变原有代码的情况下,去增加新的功能

10.3 使用Spring实现AOP

  • 方式一:使用Spring的API接口实现

    1. 首先导入Maven的依赖

      <!--使用AOP织入,需要导入一个依赖包-->
              <dependency>
                  <groupId>org.aspectj</groupId>
                  <artifactId>aspectjweaver</artifactId>
                  <version>1.9.4</version>
              </dependency>
      
    2. 然后再servlet的包下,定义UserService业务接口和UserServiceImpl实现类

      • UserService的接口
      package com.qin.service;
      
      public interface UserService {
          public void add();
          public void delete();
          public void update();
          public void select();
      }
      
      
      package com.qin.service;
      
      public class UserServiceImpl implements UserService{
          @Override
          public void add() {
              System.out.println("增加了一个用户!");
          }
      
          @Override
          public void delete() {
              System.out.println("删除了一个用户!");
          }
      
          @Override
          public void update() {
              System.out.println("更新了一个用户!");
          }
      
          @Override
          public void select() {
              System.out.println("查询了一个用户!");
          }
      }
      
      
    3. 在log包下,定义我们的增强类,一个前置通知和一个后置通知

      • Log类
      package com.qin.log;
      
      import org.springframework.aop.MethodBeforeAdvice;
      
      import java.lang.reflect.Method;
      
      public class Log implements MethodBeforeAdvice {
          @Override
          // method :表示要执行的目标对象的方法
          // agrs :参数
          // target :目标对象
          public void before(Method method, Object[] agrs, Object target) throws Throwable {
              System.out.println(target.getClass().getName()+"的"+method.getName()+"方法被执行");
          }
      
      }
      
      package com.qin.log;
      
      import org.springframework.aop.AfterReturningAdvice;
      
      import java.lang.reflect.Method;
      
      public class AfterLog implements AfterReturningAdvice {
          @Override
          public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
              System.out.println("执行了"+method.getName()+"方法,返回结果为:"+returnValue);
          }
      
      }
      
      
    4. 配置benas.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"
             xmlns:aop="http://www.springframework.org/schema/aop"
             xsi:schemaLocation="http://www.springframework.org/schema/beans
              https://www.springframework.org/schema/beans/spring-beans.xsd
              http://www.springframework.org/schema/aop
              https://www.springframework.org/schema/aop/spring-aop.xsd">
      
          <bean id="userService" class="com.qin.service.UserServiceImpl"></bean>
          <bean id="log" class="com.qin.log.Log"/>
          <bean id="afterlog" class="com.qin.log.AfterLog"/>
      
      <!--    方式一:使用原生的Spring API接口-->
      <!--    配置AOP:需要导入AOP的约束-->
          <aop:config>
              <!-- 切入点:就是我们的代码在哪执行-->
              <aop:pointcut id="pointcut" expression="execution(* com.qin.service.UserServiceImpl.*(..))"/>
              <!-- 执行环绕增加!!!-->
              <aop:advisor advice-ref="log" pointcut-ref="pointcut"/>
              <aop:advisor advice-ref="afterlog" pointcut-ref="pointcut"/>
          </aop:config>
      
      </beans>
      
    5. 测试

      • MyTest类
      import com.qin.service.UserService;
      import org.springframework.context.ApplicationContext;
      import org.springframework.context.support.ClassPathXmlApplicationContext;
      
      public class MyTest {
          public static void main(String[] args) {
              ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
              // 此处唯一一点的不同是:到那个太代理代理的是接口:这个是注意点
              UserService userService = (UserService) context.getBean("userService");
              userService.delete();
          }
          // AOP 就是在不影响原来业务的情况下,实现动态增强
      }
      
      
  • 方式二:自定义的类来实现AOP【主要是切面定义】

    1. 创建DIYPointCut.class

      package com.qin.diy;
      
      public class DiyPointCut {
          public void before(){
              System.out.println("=======方法执行前========");
          }
          public void after(){
              System.out.println("=======方法执行后========");
          }
      }
      
      
    2. 注册bean.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"
             xmlns:aop="http://www.springframework.org/schema/aop"
             xsi:schemaLocation="http://www.springframework.org/schema/beans
              https://www.springframework.org/schema/beans/spring-beans.xsd
              http://www.springframework.org/schema/aop
              https://www.springframework.org/schema/aop/spring-aop.xsd">
      
          <bean id="userService" class="com.qin.service.UserServiceImpl"></bean>
      
      <!--    方式二:自定义类  相对来说比较简单,但是不如第一种使用-->
          <bean id="diy" class="com.qin.diy.DiyPointCut"/>
      
          <aop:config>
              <!-- 自定义切面,ref要引用的类-->
              <aop:aspect ref="diy">
                  <!--切入点-->
                  <aop:pointcut id="point" expression="execution(* com.qin.service.UserServiceImpl.*(..))"/>
                  <!--通知-->
                  <aop:after method="after" pointcut-ref="point"/>
                  <aop:before method="before" pointcut-ref="point"/>
              </aop:aspect>
          </aop:config>
      
      
      </beans>
      
    3. 测试

  • 方式三:注解实现AOP【注解实现还是有一定的约束和限制】

    1. 定义一个类【在类中,标注切面】
    package com.qin.diy;
    
    import org.aspectj.lang.ProceedingJoinPoint;
    import org.aspectj.lang.annotation.After;
    import org.aspectj.lang.annotation.Around;
    import org.aspectj.lang.annotation.Aspect;
    import org.aspectj.lang.annotation.Before;
    
    @Aspect //标注这是一个切面
    public class AnnotationPointCut {
    
        // 前置通知  注解的内容主要是写切入点
        @Before("execution(* com.qin.service.UserServiceImpl.*(..))")
        public void before(){
            System.out.println("=====方法执行前=======");
        }
        // 后置通知
        @After("execution(* com.qin.service.UserServiceImpl.*(..))")
        public void after(){
            System.out.println("=====方法执行后=======");
        }
        // 环绕通知
        @Around("execution(* com.qin.service.UserServiceImpl.*(..))")
        public void around(ProceedingJoinPoint jp) throws Throwable {
            System.out.println("环绕前");
            Object proceed = jp.proceed();
            System.out.println("环绕后");
        }
    
    }
    
    
    1. beans.xml的配置
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:aop="http://www.springframework.org/schema/aop"
           xsi:schemaLocation="http://www.springframework.org/schema/beans
            https://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/aop
            https://www.springframework.org/schema/aop/spring-aop.xsd">
    
        <bean id="userService" class="com.qin.service.UserServiceImpl"></bean>
    
    
    <!--第三种方式:使用注解来实现-->
        <bean id="annotationPointCut" class="com.qin.diy.AnnotationPointCut"/>
        <!--开启注解支持-->
        <aop:aspectj-autoproxy/>
    

10.4 总结

AOP主要学习的是一种横向编程的思想,即在不改变原有代码的情况下,实现业务的增强(本质上是使用的动态代理模式)!!!

11、整合Mybatis

11.1 回忆mybatis

步骤:

  1. 导入相应的jar包

    • junit 测试工具包
    • mybatis 包
    • mysql-connector-java mysql的包
    • Spring-webmvc的包
    • aop的织入包
    • mybatis-spring 整合包
    • Spring-jdbc Spring操作数据库的包
    • lombok 偷懒工具包
    • 最后还需要配置资源过滤!!!
    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <parent>
            <artifactId>Spring-study</artifactId>
            <groupId>com.qin</groupId>
            <version>1.0-SNAPSHOT</version>
        </parent>
        <modelVersion>4.0.0</modelVersion>
    
        <artifactId>Spring-10-Mybatis</artifactId>
    
        <dependencies>
            <!--mysql的驱动-->
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>5.1.49</version>
            </dependency>
            <!--mybatis的依赖包-->
            <dependency>
                <groupId>org.mybatis</groupId>
                <artifactId>mybatis</artifactId>
                <version>3.5.2</version>
            </dependency>
            <!-- https://mvnrepository.com/artifact/log4j/log4j -->
            <dependency>
                <groupId>log4j</groupId>
                <artifactId>log4j</artifactId>
                <version>1.2.17</version>
            </dependency>
            <!--junit测试工具包-->
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>4.12</version>
            </dependency>
            <!--偷懒工具lombok-->
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <version>1.18.10</version>
            </dependency>
            <!--Spring的包-->
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-webmvc</artifactId>
                <version>5.2.0.RELEASE</version>
            </dependency>
            <!--Spring操作数据库的话,需要这么一个包-->
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-jdbc</artifactId>
                <version>5.2.0.RELEASE</version>
            </dependency>
            <!--使用AOP织入,需要导入一个依赖包-->
            <dependency>
                <groupId>org.aspectj</groupId>
                <artifactId>aspectjweaver</artifactId>
                <version>1.9.4</version>
            </dependency>
    <!--        整合mybatis和spring的包-->
            <dependency>
                <groupId>org.mybatis</groupId>
                <artifactId>mybatis-spring</artifactId>
                <version>2.0.2</version>
            </dependency>
    
            
        </dependencies>
        <!--资源过滤-->
        <build>
            <resources>
                <resource>
                    <directory>src/main/java</directory>
                    <includes>
                        <include>**/*.properties</include>
                        <include>**/*.xml</include>
                    </includes>
                    <filtering>false</filtering>
                </resource>
                <resource>
                    <directory>src/main/resources</directory>
                    <includes>
                        <include>**/*.properties</include>
                        <include>**/*.xml</include>
                    </includes>
                    <filtering>false</filtering>
                </resource>
            </resources>
    
        </build>
    
    </project>
    
  2. Mybatis的步骤

    • 导入jar包
    • 编写xml配置文件
    • 编写工具类
    • 编写pojo实体类
    • 编写接口
    • 绑定接口
    • 测试

11.2 Mybatis-Spring

配合联系的代码程序:Spring-10-Mybatis

  • 整合方式一

    首先需要导入需要的maven包 mybatis-spring

    1. 在Spring-dao.xml中:使用Spring的数据源替换Mybatis的数据源

      <!-- 使用Spring的数据源替换Mybatis的配置  1、替换mybatis的数据源-->
          <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
              <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
              <property name="url" value="jdbc:mysql://ip地址:3306/test_1?useSSL=false&amp;useUnicode=true&amp;characterEncoding=utf8"/>
              <property name="username" value="test_1"/>
              <property name="password" value="LAbrXKKXMsH3bwPn"/>
          </bean>
      
    2. 配置SqlSessionFactory,关联Mybatis

      <!--配置SqlSessionFactory,关联Mybatis  第2步-->
          <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
              <property name="dataSource" ref="dataSource"/>
          <!--关联mybatis的配置文件-->
              <property name="configLocation" value="classpath:mybatis-config.xml"/>
              <property name="mapperLocations" value="classpath:com/qin/dao/*.xml"/>
          </bean>
      
    3. 注册sqlSessionTemplate,也就是我们需要的sqlsession

      <!--注册注册sqlSessionTemplate,关联sqlSessionFactory-->
          <bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
              <constructor-arg index="0" ref="sqlSessionFactory" />
          </bean>
      
    4. 创建一个实现类(这就麻烦了!)(需要给接口加实现类,这是多了一步而已)

      package com.qin.dao;
      
      import com.qin.pojo.User;
      import org.mybatis.spring.SqlSessionTemplate;
      
      import java.util.List;
      
      public class UserMapperImpl implements UserMapper{
      
          private SqlSessionTemplate sqlSession;
      
          // Spring需要set方法的注入
          public void setSqlSession(SqlSessionTemplate sqlSession) {
              this.sqlSession = sqlSession;
          }
      
          @Override
          public List<User> selectUser() {
              // 需要getmapper
              UserMapper mapper = sqlSession.getMapper(UserMapper.class);
              return mapper.selectUser();
          }
      }
      
      
    5. 注册bean.xml(将自己写的实现类,注册到Spring中)

      <!-- 注册bean-->
          <bean id="userMapper" class="com.qin.dao.UserMapperImpl">
              <property name="sqlSession" ref="sqlSession"/>
          </bean>
      
      
    6. 测试

      import com.qin.dao.UserMapper;
      import com.qin.pojo.User;
      import com.qin.utils.MybatisUtils;
      import org.apache.ibatis.session.SqlSession;
      import org.junit.Test;
      import org.springframework.context.ApplicationContext;
      import org.springframework.context.support.ClassPathXmlApplicationContext;
      
      import java.util.List;
      
      public class MyTest {
          @Test
          public void test01(){
      
              ApplicationContext context = new ClassPathXmlApplicationContext("spring-dao.xml");
      
              UserMapper userMapper =  context.getBean("userMapper",UserMapper.class);
              for (User user : userMapper.selectUser()) {
                  System.out.println(user);
      
              }
          }
      }
      
      
    7. 总结思路:(不需要mybatis中的工具类了!!!)

      mybatis-config.xml

      <?xml version="1.0" encoding="UTF-8" ?>
      <!DOCTYPE configuration
              PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
              "http://mybatis.org/dtd/mybatis-3-config.dtd">
      <!--核心配置文件
      属性、配置、别名这三个务必掌握
      -->
      <configuration>
      
      
      </configuration>
      

      spring-dao.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"
             xmlns:aop="http://www.springframework.org/schema/aop"
             xsi:schemaLocation="http://www.springframework.org/schema/beans
              https://www.springframework.org/schema/beans/spring-beans.xsd
              http://www.springframework.org/schema/aop
              https://www.springframework.org/schema/aop/spring-aop.xsd">
      
          <!-- 使用Spring的数据源替换Mybatis的配置  1、替换mybatis的数据源-->
          <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
              <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
              <property name="url" value="jdbc:mysql:/ip地址:3306/test_1?useSSL=false&amp;useUnicode=true&amp;characterEncoding=utf8"/>
              <property name="username" value="test_1"/>
              <property name="password" value="LAbrXKKXMsH3bwPn"/>
          </bean>
          <!--配置SqlSessionFactory,关联Mybatis  第2步-->
          <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
              <property name="dataSource" ref="dataSource"/>
          <!--关联mybatis的配置文件  ,第三部-->
              <property name="configLocation" value="classpath:mybatis-config.xml"/>
              <property name="mapperLocations" value="classpath:com/qin/dao/*.xml"/>
          </bean>
          <!--注册注册sqlSessionTemplate,关联sqlSessionFactory-->
          <bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
              <constructor-arg index="0" ref="sqlSessionFactory" />
          </bean>
      
      <!--    第4步,需要接口的实现类-->
          <bean id="userMapper" class="com.qin.dao.UserMapperImpl">
              <property name="sqlSession" ref="sqlSession"/>
          </bean>
      
      </beans>
      

      需要Spring的托管,所以需要实现类UserMapperImple.java

      package com.qin.dao;
      
      import com.qin.pojo.User;
      import org.mybatis.spring.SqlSessionTemplate;
      
      import java.util.List;
      
      public class UserMapperImpl implements UserMapper{
      
          private SqlSessionTemplate sqlSession;
      
          // Spring需要set方法的注入
          public void setSqlSession(SqlSessionTemplate sqlSession) {
              this.sqlSession = sqlSession;
          }
      
          @Override
          public List<User> selectUser() {
              // 需要getmapper
              UserMapper mapper = sqlSession.getMapper(UserMapper.class);
              return mapper.selectUser();
          }
      }
      
      
  • 整合方式二

SqlSessionDaoSupport

dao继承Support类 , 直接利用 getSqlSession() 获得 , 然后直接注入SqlSessionFactory . 比起方式1 , 不 需要管理SqlSessionTemplate , 而且对事务的支持更加友好 .

  1. UserMapperImplTwo.java

    package com.qin.dao;
    
    import com.qin.pojo.User;
    import org.mybatis.spring.support.SqlSessionDaoSupport;
    
    import java.util.List;
    
    public class UserMapperImplTwo extends SqlSessionDaoSupport implements UserMapper {
        @Override
        public List<User> selectUser() {
            return getSqlSession().getMapper(UserMapper.class).selectUser();
        }
    }
    
    
  2. Spring-dao.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"
           xmlns:aop="http://www.springframework.org/schema/aop"
           xsi:schemaLocation="http://www.springframework.org/schema/beans
            https://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/aop
            https://www.springframework.org/schema/aop/spring-aop.xsd">
    
        <!-- 使用Spring的数据源替换Mybatis的配置  1、替换mybatis的数据源-->
        <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
            <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
            <property name="url" value="jdbc:mysql://ip地址:3306/test_1?useSSL=false&amp;useUnicode=true&amp;characterEncoding=utf8"/>
            <property name="username" value="test_1"/>
            <property name="password" value="LAbrXKKXMsH3bwPn"/>
        </bean>
        <!--配置SqlSessionFactory,关联Mybatis  第2步-->
        <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
            <property name="dataSource" ref="dataSource"/>
        <!--关联mybatis的配置文件-->
            <property name="configLocation" value="classpath:mybatis-config.xml"/>
            <property name="mapperLocations" value="classpath:com/qin/dao/*.xml"/>
        </bean>
    
    <!--    第4步,需要接口的实现类-->
      
        <bean id="userMappertwo" class="com.qin.dao.UserMapperImplTwo">
            <property name="sqlSessionFactory" ref="sqlSessionFactory"/>
        </bean>
    
    
    </beans>
    
  3. mybatis-config,xml

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE configuration
            PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
            "http://mybatis.org/dtd/mybatis-3-config.dtd">
    <!--核心配置文件
    属性、配置、别名这三个务必掌握
    -->
    <configuration>
    
    </configuration>
    
  4. 测试类

    import com.qin.dao.UserMapper;
    import com.qin.pojo.User;
    import com.qin.utils.MybatisUtils;
    import org.apache.ibatis.session.SqlSession;
    import org.junit.Test;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    import java.util.List;
    
    public class MyTest {
        @Test
        public void test01(){
    
            ApplicationContext context = new ClassPathXmlApplicationContext("spring-dao.xml");
    
            UserMapper userMapper =  context.getBean("userMappertwo",UserMapper.class);
            for (User user : userMapper.selectUser()) {
                System.out.println(user);
    
            }
        }
    }
    

12、声明式事务

12.1 回顾事务

  • 把一组业务当成一个业务来做;要么都成功,要么都失败!
  • 事务在项目的开发中,十分的重要,涉及到数据的一致性问题,不能马虎!
  • 确保完整性和一致性。

事务ACID原则

  • 原子性:
    • 事务是原子性操作,由一系列动作组成,事务的原子性确保动作要么全部完成,要么完全不起作用。
  • 一致性:
    • 一旦所有事务动作完成,事务就要被提交。数据和资源处于一种满足业务规则的一致性状态中。
  • 隔离性:(重点是防止数据的损坏!)
    • 可能多个事务会同时处理相同的数据,因此每个事务都应该与其他事务隔离开来,防止数据损坏。
  • 持久性:
    • 事务一旦完成,无论系统发生什么错误,结果都不会受到影响。通常情况下,事务的结果被写到持久化存储器中。

引入程序Spring-11-transaction

  1. 导入jar包依赖
  2. 配置mybatis-config.xml
  3. 配置Spring-dao.xml操作
  4. 编写pojo的实体类
  5. dao中写接口
  6. 配置Mapper.xml
  7. 实现接口的类(目的是为了让Spring对类进行接管)
  8. 根据相应的需要配置Spring-dao(目的是为了实现AOP来管理事务)
  • Spring支持编程式事务和声明式事务管理

    • 编程式事务

    • 声明式事务

      将事务管理的代码,从业务中分离出来,以声明的方式来管理事务**(其实是死的,谁需要配置事务,直接更改AOP的切入点即可)**

      将事务管理作为横切关注点,通过aop方法模块化。Spring中通过Spring AOP框架支持声明式事务 管理

  • 导入相应的约束tx

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:tx="http://www.springframework.org/schema/tx"
           xmlns:aop="http://www.springframework.org/schema/aop"
           xsi:schemaLocation="http://www.springframework.org/schema/beans
            https://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/tx
            https://www.springframework.org/schema/tx/spring-tx.xsd
            http://www.springframework.org/schema/aop
            https://www.springframework.org/schema/aop/spring-aop.xsd">
    
        <!-- 使用Spring的数据源替换Mybatis的配置  1、替换mybatis的数据源-->
        <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
            <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
            <property name="url" value="jdbc:mysql://ip地址:3306/test_1?useSSL=false&amp;useUnicode=true&amp;characterEncoding=utf8"/>
            <property name="username" value="test_1"/>
            <property name="password" value="LAbrXKKXMsH3bwPn"/>
        </bean>
        <!--配置SqlSessionFactory,关联Mybatis  第2步-->
        <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
            <property name="dataSource" ref="dataSource"/>
        <!--关联mybatis的配置文件-->
            <property name="configLocation" value="classpath:mybatis-config.xml"/>
            <property name="mapperLocations" value="classpath:com/qin/dao/*.xml"/>
        </bean>
    
        <bean id="userMapperImpl" class="com.qin.dao.UserMapperImpl">
            <property name="sqlSessionFactory" ref="sqlSessionFactory"/>
        </bean>
    
        <!--    开始Spring的事务管理(开启声明性事务)-->
        <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
            <property name="dataSource" ref="dataSource"/>
        </bean>
    
        <!--结合AOP实现事务的织入   事务交给容器管理-->
        <!--配置事务的类:配置事务通知-->
        <tx:advice id="txAdvice" transaction-manager="transactionManager">
            <!--给那些方法配置事务-->
            <!--配置事务的传播特性: new -->
            <tx:attributes>
                <tx:method name="add" propagation="REQUIRED"/>
                <tx:method name="delete" propagation="REQUIRED"/>
                <tx:method name="update" propagation="REQUIRED"/>
                <tx:method name="query" read-only="true"/>
                <tx:method name="*" propagation="REQUIRED"/>
            </tx:attributes>
        </tx:advice>
    
        <!--配置AOP的操作-->
        <aop:config>
            <!--切入点pointcut-->
            <aop:pointcut id="txPointCut" expression="execution(* com.qin.dao.*.*(..))"/>
            <aop:advisor advice-ref="txAdvice" pointcut-ref="txPointCut"/>
        </aop:config>
    
    
    
    </beans>
    
  • 为什么要配置事务:事务在项目的开发过程中非常的重要,尤其是涉及到数据的一致性的问题,不容马虎!!!

13、Spring总结

  • Spring重点是思想的学习 IOC和AOP
  • 重点是7、8、9的使用
  • 反射原理的学习!

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring是一个开源的Java框架,用于构建企业级应用程序。它提供了一种轻量级的、非侵入式的开发方式,通过依赖注入和面向切面编程等特性,简化了Java应用程序的开发过程。 以下是关于Spring学习的一些笔记: 1. IoC(控制反转):Spring通过IoC容器管理对象的创建和依赖关系的注入。通过配置文件或注解,将对象的创建和依赖关系的维护交给Spring容器来管理,降低了组件之间的耦合度。 2. DI(依赖注入):Spring通过依赖注入将对象之间的依赖关系解耦。通过构造函数、Setter方法或注解,将依赖的对象注入到目标对象中,使得对象之间的关系更加灵活和可维护。 3. AOP(面向切面编程):Spring提供了AOP的支持,可以将与业务逻辑无关的横切关注点(如日志、事务管理等)从业务逻辑中分离出来,提高了代码的可重用性和可维护性。 4. MVC(模型-视图-控制器):Spring提供了一个MVC框架,用于构建Web应用程序。通过DispatcherServlet、Controller、ViewResolver等组件,实现了请求的分发和处理,将业务逻辑和视图展示进行了分离。 5. JDBC和ORM支持:Spring提供了对JDBC和ORM框架(如Hibernate、MyBatis)的集成支持,简化了数据库访问的操作,提高了开发效率。 6. 事务管理:Spring提供了对事务的支持,通过声明式事务管理和编程式事务管理,实现了对数据库事务的控制和管理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值