Spring笔记(狂神说)

1、Spring概述及IOC本质

1.1 简介

在这里插入图片描述

  • SSH: Struct2 + Spring + Hibernate

  • SSM: SpringMVC + Spring + Mybatis

  • 官网 : http://spring.io/

  • 官方下载地址 : https://repo.spring.io/libs-release-local/org/springframework/spring/

  • GitHub : https://github.com/spring-projects

优点:

  1. Spring是一个开源免费的框架 , 容器
  2. Spring是一个轻量级的框架 , 非侵入式的 .
  3. 控制反转 IOC , 面向切面 AOP
  4. 对事物的支持 , 对框架的支持

总结:Spring就是一个轻量级的控制反转(IOC)和面向切面编程(AOP)的框架!

1.2 相关依赖

<dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-webmvc</artifactId>
   <version>5.3.4</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-jdbc</artifactId>
    <version>5.3.4</version>
</dependency>

1.3 IOC本质

控制反转IOC(Inversion of Control),是一种设计思想,DI(依赖注入)是实现IOC的一种方法,也有人认为DI只是IOC的另一种说法。没有IOC的程序中 , 我们使用面向对象编程 , 对象的创建与对象间的依赖关系完全硬编码在程序中,对象的创建由程序自己控制,控制反转后将对象的创建转移给第三方,个人认为所谓控制反转就是:获得依赖对象的方式反转了。

IOC是Spring框架的核心内容,使用多种方式完美的实现了IOC,可以使用XML配置,也可以使用注解,新版本的Spring也可以零配置实现IOC。

Spring容器在初始化时先读取配置文件,根据配置文件或元数据创建与组织对象存入容器中,程序使用时再从IOc容器中取出需要的对象。

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

2、快速上手Spring

2.1 HelloSpring

1、创建实体类

public class Hello {
    private String str;
    public String getStr() {
        return str;
    }
    public void setStr(String str) {
        this.str = str;
    }
    @Override
    public String toString() {
        return "Hello{" +
                "str='" + str + '\'' +
                '}';
    }   
}

2、配置文件bean.xml:其中bean标签中的id值相当于对象名,class的值表示要new的类,property标签表示给对象中的属性property设置一个值value。
如果property的值的类型是一个对象,可以使用ref,表示引用spring容器中创建好的对象

<?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">

    <!--bean就是java对象 , 由Spring创建和管理-->
    <bean id="hello" class="com.xmh.pojo.Hello">
        <property name="str" value="Spring"/>
    </bean>

</beans>

3、测试:
ApplicationContext context = new ClassPathXmlApplicationContext(“beans.xml”); 这句话表示拿到spring容器,然后用context.getBean(“id”) 来获取对象,而不用去new了

    @Test
    public void test(){
        //解析beans.xml文件 , 生成管理相应的Bean对象
        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        //getBean : 参数即为spring配置文件中bean的id .
        Hello hello = (Hello) context.getBean("hello");
        hello.show();
    }

2.2 IOC创建对象方式

通过无参构造函数来创建(默认)

1、User.java

public class Hello {
    private String str;
    public String getStr() {
        return str;
    }
    public void setStr(String str) {
        this.str = str;
    }
    @Override
    public String toString() {
        return "Hello{" +
                "str='" + str + '\'' +
                '}';
    }   
}

2、beans.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">

   <bean id="user" class="com.xmh.pojo.User">
       <property name="name" value="kuangshen"/>
   </bean>

</beans>

通过有参构造函数来创建

1、UserT.java

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

2、beans.xml有三种编写方式

<!-- 第一种根据index参数下标设置 -->
<bean id="userT" class="com.kuang.pojo.UserT">
   <!-- index指构造方法 , 下标从0开始 -->
   <constructor-arg index="0" value="kuangshen2"/>
</bean>
<!-- 第二种根据参数名字设置 -->
<bean id="userT" class="com.kuang.pojo.UserT">
   <!-- name指参数名 -->
   <constructor-arg name="name" value="kuangshen2"/>
</bean>
<!-- 第三种根据参数类型设置 -->
<bean id="userT" class="com.kuang.pojo.UserT">
   <constructor-arg type="java.lang.String" value="kuangshen2"/>
</bean>

2.3 Spring配置(别名、Bean、import)

1、别名:

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

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>

3、import
团队的合作通过import来实现 .

<import resource="{path}/beans.xml"/>

3、依赖注入

  • 依赖 : 指Bean对象的创建依赖于容器 . Bean对象的依赖资源 .
  • 注入 : 指Bean对象所依赖的资源 , 由容器来设置和装配 .

3.1 构造器注入

<!-- 第一种根据index参数下标设置 -->
<bean id="userT" class="com.kuang.pojo.UserT">
   <!-- index指构造方法 , 下标从0开始 -->
   <constructor-arg index="0" value="kuangshen2"/>
</bean>
<!-- 第二种根据参数名字设置 -->
<bean id="userT" class="com.kuang.pojo.UserT">
   <!-- name指参数名 -->
   <constructor-arg name="name" value="kuangshen2"/>
</bean>
<!-- 第三种根据参数类型设置 -->
<bean id="userT" class="com.kuang.pojo.UserT">
   <constructor-arg type="java.lang.String" value="kuangshen2"/>
</bean>

3.2 set方式注入*

1、实体类
Address.java

public class Address {
    private String address;

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }
}

Student.java

package com.xmh.pojo;

import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

/**
 * @author dinner
 * @description
 * @create 2021/3/16
 */
public class Student {
    private String name;
    private Address address;
    private String[] books;
    private List<String> hobbys;
    private Map<String,String> card;
    private Set<String> games;
    private String wife;
    private Properties info;

    public void setName(String name) {
        this.name = name;
    }
    public void setAddress(Address address) {
        this.address = address;
    }
    public void setBooks(String[] books) {
        this.books = books;
    }
    public void setHobbys(List<String> hobbys) {
        this.hobbys = hobbys;
    }
    public void setCard(Map<String, String> card) {
        this.card = card;
    }
    public void setGames(Set<String> games) {
        this.games = games;
    }
    public void setWife(String wife) {
        this.wife = wife;
    }
    public void setInfo(Properties info) {
        this.info = info;
    }
    public void show(){
        System.out.println("name="+ name
                + ",address="+ address.getAddress()
                + ",books="
        );
        for (String book:books){
            System.out.print("<<"+book+">>\t");
        }
        System.out.println("\n爱好:"+hobbys);
        System.out.println("card:"+card);
        System.out.println("games:"+games);
        System.out.println("wife:"+wife);
        System.out.println("info:"+info);
    }
}

2、注入:

常量注入

<property name="name" value="xmh"></property>

Bean注入

//注意点:这里的值是一个引用,ref
<property name="address" ref="address"></property>

数组注入

	<property name="books">
            <array>
                <value>西游记</value>
                <value>水浒传</value>
                <value>三国演义</value>
            </array>
	</property>

List注入

        <property name="hobbys">
            <list>
                <value>听歌</value>
                <value>写代码</value>
            </list>
        </property>

Map注入

        <property name="card">
            <map>
                <entry key="身份证" value="123456"></entry>
                <entry key="电话号" value="123456789"></entry>
            </map>
        </property>

set注入

<property name="games">
     <set>
         <value>LOL</value>
         <value>BOB</value>
         <value>COC</value>
     </set>
 </property>

Null注入

 <property name="wife"><null/></property>

Properties注入

 <property name="info">
     <props>
         <prop key="学号">20190604</prop>
         <prop key="性别"></prop>
         <prop key="姓名">小明</prop>
     </props>
 </property>

测试结果:
在这里插入图片描述

3.3 p命名和c命名注入

1、P命名空间注入 : 需要在头文件中加入约束文件

导入约束 : xmlns:p="http://www.springframework.org/schema/p"
 
 <!--P(属性: properties)命名空间 , 属性依然要设置set方法-->
 <bean id="user" class="com.xmh.pojo.User" p:name="dd" p:age="18"/>

2、c 命名空间注入 : 需要在头文件中加入约束文件

导入约束 : xmlns:c="http://www.springframework.org/schema/c"
 <!--C(构造: Constructor)命名空间 , 属性依然要设置set方法-->
 <bean id="user" class="com.kuang.pojo.User" c:name="dd" c:age="18"/>

3.4 bean的作用域

1.单例模式: Spring默认机制,一个类只实例化一次,通过get方法得到的对象,即使对象的名字不同,本质还是同一个

<bean id="" class="" scope="singleton"/>

2.原型模式:每次从容器中get时,都会产生一个新对象!适用于多线程

<bean id="" class="" scope="prototype"/>

3.其余的request,session,application,只能在web开发中使用到,表示对象的生存周期

4、自动装配

4.1 Bean的自动装配

1、实体类People,有两个宠物Cat,Dog

public class People {
        private Cat cat;
        private Dog dog;
        private String str;
}

2、spring配置文件
添加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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="dog" class="com.xmh.pojo.Dog"/>
    <bean id="cat" class="com.xmh.pojo.Cat"/>

    <bean id="people" class="com.xmh.pojo.People" autowire="byName">
        <property name="str" value="xmh"></property>
    </bean>
</beans>

byName

当一个bean节点带有 autowire byName的属性时。

  • 将查找其类中所有的set方法名,例如setCat,获得将set去掉并且首字母小写的字符串,即cat。
  • 去spring容器中寻找是否有此字符串名称id的对象。
  • 如果有,就取出注入;如果没有,就报空指针异常

byType

自动在容器中查找和自己对象类型相同的bean(同一个pojo中)

小结:

  • byName的时候,需要保证所有bean的id唯一,并且这个id要和自动注入的属性的set方法的值一致!
  • byType的时候,需要保证所有的bean的class唯一,并且这个bean的属性要和自动注入的属性类型一致!

4.2 使用注解自动装配

1、在xml配置文件中的beans标签中加入注解支持

<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"
>

2、开启注解扫描

<context:annotation-config/>
<context:component-scan base-package="com"/>

@Autowired

public class User {
   @Autowired
   private Cat cat;
   @Autowired
   private Dog dog;
   private String str;
}
  • @Autowired是按类型自动转配的,不支持id匹配。
  • @Autowired(required=false) 说明:false,对象可以为null;true,对象必须存对象,不能为null。

@Qualifier

@Autowired
@Qualifier(value = "cat2")
private Cat cat;
@Autowired
@Qualifier(value = "dog2")
private Dog dog;
  • @Autowired是根据类型自动装配的,加上@Qualifier则可以根据byName的方式自动装配
  • @Qualifier不能单独使用。

@Resource

public class People {
        @Resource(name = "cat2")
        private Cat cat;
        @Resource
        private Dog dog;
        private String str;
}
  • @Resource如有指定的name属性,先按该属性进行byName方式查找装配;
  • 其次再进行默认的byName方式进行装配;
  • 如果以上都不成功,则按byType的方式自动装配。
  • 都不成功,则报异常。

小结

  • @Autowired与@Resource异同:

    • 1、@Autowired与@Resource都可以用来装配bean。都可以写在字段上,或写在setter方法上。
    • 2、@Autowired默认按类型装配(属于spring规范),默认情况下必须要求依赖对象必须存在,如果要允许null 值,可以设置它的required属性为false,如:@Autowired(required=false) ,如果我们想使用名称装配可以结合@Qualifier注解进行使用
    • 3、@Resource(属于J2EE复返),默认按照名称进行装配,名称可以通过name属性进行指定。如果没有指定name属性,当注解写在字段上时,默认取字段名进行按照名称查找,如果注解写在setter方法上默认取属性名进行装配。当找不到与名称匹配的bean时才按照类型进行装配。但是需要注意的是,如果name属性一旦指定,就只会按照名称进行装配。
    • 4、它们的作用相同都是用注解方式注入对象,但执行顺序不同。@Autowired先byType,@Resource先byName。

5、使用注解开发

5.1 注解开发

1、在xml配置文件中的beans标签中加入注解支持

<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">
<!--指定注解扫描包-->
<context:component-scan base-package="com.xmh.pojo"/>
<context:annotation-config/>
</beans>

2、在指定包下编写类,增加注解

@Component

@Component("user")
// 相当于配置文件中 <bean id="user" class="当前注解的类"/>
public class User {
   @Value("xmh")
   // 相当于配置文件中 <property name="name" value="xmh"/>
   public String name;
}

@Component三个衍生注解
为了更好的进行分层,Spring可以使用其它三个注解,功能一样,目前使用哪一个功能都一样。

  • @Controller:web层
  • @Service:service层
  • @Repository:dao层

@scope

  • singleton:默认的,Spring会采用单例模式创建这个对象。关闭工厂 ,所有的对象都会销毁。
  • prototype:多例模式。关闭工厂 ,所有的对象不会销毁。内部的垃圾回收机制会回收
@Controller("user")
@Scope("prototype")
public class User {
   @Value("xmh")
   public String name;
}

小结:

  • XML更加万能,适用于任何场合,维护简单方便!
  • 注解不是自己的类使用不了,维护相对复杂
  • xml用来管理bean,注解只完成属性的注入。

5.2 注解自动装配

见4.2

5.3 基于Java类进行配置

使用一个JavaConfig类,来替代原来的beans.xml

1、新建一个config配置包,编写一个MyConfig配置类

@Configuration
@ComponentScan("pojo")
//这个类也会被注入到Spring容器中,其本质就是一个@Component
//@Configuration代表这是一个配置类,用于替代beans.xml
//@ComponentScan("pojo") 开启扫描
public class MyConfig {
    @Bean
    //注册一个bean,相当于xml里的一个bean标签
    //方法的名字相当于bean标签的id值
	//方法的返回类型相当于bean标签的class属性值
    public User getUser(){
        return new User();
    }
}

2、测试
注意:用ApplicationContext applicationContext =
new AnnotationConfigApplicationContext(MyConfig.class);
获取context

@Test
public void test2(){
   ApplicationContext applicationContext =
           new AnnotationConfigApplicationContext(MyConfig.class);
   User user= (User) applicationContext.getBean("getUser");
   System.out.println(user);
}

@import (合并配置类)

1、再编写一个配置类

@Configuration  //代表这是一个配置类
public class MyConfig2 {
}

2、在之前的配置类中我们来选择导入这个配置类

@Configuration
@Import(MyConfig2.class)  //导入合并其他配置类,类似于配置文件中的 inculde 标签
public class MyConfig {

   @Bean
   public Dog dog(){
       return new Dog();
  }

}

6、AOP

  • 横切关注点:横跨多个模块的方法或功能,待加入到业务层实现功能扩充,如日志功能
  • 切面(aspect):是动作,把通知应用到切入点
  • 通知(advice):实际增强的逻辑部分称为通知
    • 前置通知
    • 后置通知
    • 环绕通知
    • 异常通知
    • 最终通知
  • 目标(target):被通知对象,下文中的UserServiceImpl类的对象
  • 代理(proxy):向目标对象加入通知创建的新对象
  • 切入点(pointcut):实际被真正增强的方法,称为切入点
  • 连接点(jointpoint):类里面的哪些方法可以被增强,这些方法称为连接点

6.1 切入点表达式

(1)切入点表达式作用:知道对哪个类里面的哪个方法进行增强
(2)语法结构: execution([权限修饰符] [返回类型] [类全路径] [方法名称] ([参数列表]) )

  • 举例 1:对 com.xmh.dao.BookDao 类里面的 add 进行增强
execution(* com.xmh.dao.BookDao.add(..))
  • 举例 2:对 com.xmh.dao.BookDao 类里面的所有的方法进行增强
execution(* com.xmh.dao.BookDao.* (..))
  • 举例 3:对 com.xmh.dao 包里面所有类,类里面所有方法进行增强
execution(* com.xmh.dao.*.* (..))

6.2 AOP注解实现

1、引入依赖

<!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
<dependency>
       <groupId>org.aspectj</groupId>
       <artifactId>aspectjweaver</artifactId>
       <version>1.9.5</version>
</dependency>

2、引入约束,开启注解扫描

<?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" 
 xmlns:aop="http://www.springframework.org/schema/aop" 
 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 
 http://www.springframework.org/schema/aop 
http://www.springframework.org/schema/aop/spring-aop.xsd">
 <!-- 开启注解扫描 -->
 <context:component-scan base-package="com.xmh"></context:component-scan>
 <aop:aspectj-autoproxy/>
 </beans>

3、被增强的类

@Component
public class User {
    public void add(){
        System.out.println("执行了add方法");
    }
}

4、增强的代理类
(1)在增强类的里面,在作为通知方法上面添加通知类型注解,使用切入点表达式配置

@Component
@Aspect
public class UserProxy {
    //前置通知
    //@Before 注解表示作为前置通知
    @Before(value = "execution(* com.xmh.dao.User.*(..))")
    public void before() {
        System. out .println( "before.........");
    }
    //后置通知(返回通知)
    @AfterReturning(value = "execution(* com.xmh.dao.User.*(..))))")
    public void afterReturning() {
        System. out .println( "afterReturning.........");
    }
    //最终通知
    @After(value = "execution(* com.xmh.dao.User.*(..))))")
    public void after() {
        System. out .println( "after.........");
    }
    //异常通知
    @AfterThrowing(value = "execution(* com.xmh.dao.User.*(..))))")
    public void afterThrowing() {
        System. out .println( "afterThrowing.........");
    }
    //环绕通知
    @Around(value = "execution(* com.xmh.dao.User.*(..))))")
    public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        System. out .println("环绕之前 .........");
        //被增强的方法执行
        proceedingJoinPoint.proceed();
        System. out .println("环绕之后 .........");
    }
}

5、测试

public class MyTest {
    @Test
    public void test(){
        ApplicationContext applicationContext =
                new ClassPathXmlApplicationContext("beans.xml");
        User user = (User) applicationContext.getBean("user");
        user.add();
    }
}

6.3 相同的切入点抽取

public class UserProxy {

	//相同切入点抽取
    @Pointcut(value = "execution(* com.xmh.dao.User.*(..))")
    public void pointdemo() {
    }

    //前置通知
    //@Before 注解表示作为前置通知
    @Before(value = "pointdemo()")
    public void before() {
        System. out .println( "before.........");
    }
    //后置通知(返回通知)
    @AfterReturning(value = "pointdemo()")
    public void afterReturning() {
        System. out .println( "afterReturning.........");
    }
    //最终通知
    @After(value = "pointdemo()")
    public void after() {
        System. out .println( "after.........");
    }

}

7、整合Mybatis

7.1 相关依赖

  • junit
  • mybatis
  • mysql数据库
  • spring相关
  • aop织入器
  • mybatis-spring整合包【重点】在此还导入了lombok包。
  • 配置Maven静态资源过滤问题!
    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.8.1</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>5.3.4</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>5.3.4</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/javax.annotation/javax.annotation-api -->
        <dependency>
            <groupId>javax.annotation</groupId>
            <artifactId>javax.annotation-api</artifactId>
            <version>1.2</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.9.5</version>
        </dependency>
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.4.5</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.49</version>
        </dependency>
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-spring</artifactId>
            <version>2.0.2</version>
        </dependency>

    </dependencies>

    <build>
        <resources>
            <resource>
                <directory>src/main/resources</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
                <filtering>true</filtering>
            </resource>
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.xml</include>
                    <include>**/*.properties</include>
                    <include>**/*.tld</include>
                </includes>
                <filtering>true</filtering>
            </resource>
        </resources>

    </build>

7.2 回忆Mybatis

1、编写pojo实体类

public class User {
    private int id;
    private String name;
    private String  pwd;
}

2、编写Mybatis的配置文件

<?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>
    <!--导入properties文件-->
    <properties resource="db.properties"/>


    <typeAliases>
        <package name="com.xmh.pojo"/>
        <!--<typeAlias type="com.xmh.pojo.User" alias="user"/>-->
    </typeAliases>

    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="${jdbc.driver}"/>
                <property name="url" value="${jdbc.url}"/>
                <property name="username" value="${jdbc.username}"/>
                <property name="password" value="${jdbc.password}"/>
            </dataSource>
        </environment>
    </environments>

    <mappers>
        <mapper class="com.xmh.dao.UserMapper"></mapper>
    </mappers>
</configuration>

3、编写UserMapper接口

public interface UserMapper {
    public List<User> selectUser();
}

4、编写UserMapper.xml文件

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.xmh.dao.UserMapper">

    <!--sql-->
    <select id="selectUser" resultType="user">
        select * from user
    </select>
</mapper>

5、测试

@Test
    public void test() throws IOException {
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        SqlSession sqlSession = sqlSessionFactory.openSession();

        UserMapper mapper = sqlSession.getMapper(UserMapper.class);

        List<User> userList = mapper.selectUser();
        for (User user: userList){
            System.out.println(user);
        }

        sqlSession.close();
    }

7.3 Mybatis-Spring

MyBatis-Spring 会帮助你将 MyBatis 代码无缝地整合到 Spring 中。
文档链接:链接: http://mybatis.org/spring/zh/index.html
如果使用 Maven 作为构建工具,仅需要在 pom.xml 中加入以下代码即可:

 <!-- https://mvnrepository.com/artifact/org.mybatis/mybatis-spring -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-spring</artifactId>
            <version>2.0.2</version>
        </dependency>

整合方式一:

1、引入Spring配置文件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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd">
       
</beans>

2、配置数据源替换mybaits的数据源

<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/mybatis?useSSL=true&amp;useUnicode=true&amp;characterEncoding=utf8"/>
        <property name="username" value="root"/>
        <property name="password" value="123456"/>
    </bean>

3、配置SqlSessionFactory,关联MyBatis

<!--sqlSessionFactory-->
    <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/xmh/dao/UserMapper.xml"/>
    </bean>

4、注册sqlSessionTemplate,关联sqlSessionFactory

<!--SqlSessionTemplate:就是我们使用的sqlSession-->
    <bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
        <!--只能使用构造器注入sqlSessionFactory,因为它没有set方法-->
        <constructor-arg index="0" ref="sqlSessionFactory" />
    </bean>

5、需要UserMapper接口的UserMapperImpl 实现类,私有化sqlSessionTemplate

@Repository
public class UserMapperImpl implements UserMapper{
    @Autowired
    private SqlSessionTemplate sqlSession;

    public void setSqlSession(SqlSessionTemplate sqlSession) {
        this.sqlSession = sqlSession;
    }

    @Override
    public List<User> selectUser() {
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        return mapper.selectUser();
    }
}

6、在总的spring配置文件中引入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:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       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
       http://www.springframework.org/schema/aop
       http://www.springframework.org/schema/aop/spring-aop.xsd">
    <!-- 开启注解扫描 -->
    <context:component-scan base-package="com.xmh"></context:component-scan>
    <aop:aspectj-autoproxy/>

    <import resource="spring-dao.xml"></import>
</beans>

7、测试

    @Test
    public void test1() throws IOException {

        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");

        UserMapper userMapper = context.getBean("userMapperImpl", UserMapper.class);
        for (User user : userMapper.selectUser()) {
            System.out.println(user);
        }
    }

整合方式二:

mybatis-spring1.2.3版以上的才有这个 .

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

1、新建UserMapper实现类,UserMapperImpl2

public class UserMapperImpl2 extends SqlSessionDaoSupport implements UserMapper{

    @Override
    public List<User> selectUser() {
        return getSqlSession().getMapper(UserMapper.class).selectUser();
    }
}

2、注入到Spring配置文件中。

<bean id="userMapperImpl2" class="com.xmh.dao.UserMapperImpl2">
        <property name="sqlSessionFactory" ref="sqlSessionFactory" />
    </bean>

3、测试

    @Test
    public void test1() throws IOException {

        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");

        UserMapper userMapper = context.getBean("userMapperImpl2", UserMapper.class);
        for (User user : userMapper.selectUser()) {
            System.out.println(user);
        }
    }

8、声明式事务

8.1 AOP事务

1、使用Spring管理事务,注意头文件的约束导入 : tx

xmlns:tx="http://www.springframework.org/schema/tx"

http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">

2、JDBC事务

 <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>

3、配置好事务管理器后我们需要去配置事务的通知

    <!--结合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>

4、配置AOP,导入aop的头文件

 <!--配置事务切入-->
    <aop:config>
        <aop:pointcut id="txPointCut" expression="execution(* com.kuang.mapper.*.*(..))"/>
        <aop:advisor advice-ref="txAdvice" pointcut-ref="txPointCut"/>
    </aop:config>

5、测试

@Test
public void test2(){
   ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
   UserMapper mapper = (UserMapper) context.getBean("userDao");
   List<User> user = mapper.selectUser();
   System.out.println(user);
}

8.2 注解声明事务

1、配置事务管理器

 <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>

2、引入命名空间

xmlns:tx="http://www.springframework.org/schema/tx"

http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">

3、开启事务注解扫描

<!--开启事务注解-->
<tx:annotation-driven transaction-manager="transactionManager"></tx:annotation-driven>

4、在 service 类上面(或者 或者 service 类里面方法上面)添加事务注解
(1)@Transactional,这个注解添加到类上面,也可以添加方法上面
(2)如果把这个注解添加类上面,这个类里面所有的方法都添加事务
(3)如果把这个注解添加方法上面,为这个方法添加事务

@Repository
@Transactional
public class UserMapperImpl implements UserMapper{
	...
}

8.3事务传播特性

spring事务传播特性:
事务传播行为就是多个事务方法相互调用时,事务如何在这些方法间传播。spring支持7种事务传播行为:

  • propagation_requierd:如果当前没有事务,就新建一个事务,如果已存在一个事务中,加入到这个事务中,这是最常见的选择。
  • propagation_supports:支持当前事务,如果没有当前事务,就以非事务方法执行。
  • propagation_mandatory:使用当前事务,如果没有当前事务,就抛出异常。
  • propagation_required_new:新建事务,如果当前存在事务,把当前事务挂起。
  • propagation_not_supported:以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
  • propagation_never:以非事务方式执行操作,如果当前事务存在则抛出异常。
  • propagation_nested:如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与propagation_required类似的操作

Spring 默认的事务传播行为是 PROPAGATION_REQUIRED,它适合于绝大多数的情况。

就好比,我们刚才的几个方法存在调用,所以会被放在一组事务当中!

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 很抱歉,我是AI语言模型,无法回答关于“狂神springsecurity笔记”的问题。但我可以告诉你,Spring Security是一个基于Spring框架的安全框架,用于保护Web应用程序。它提供了身份验证、授权、攻击防护等功能,可以帮助开发人员构建安全可靠的Web应用程序。狂神是一位知名的Java技术博主,他在自己的博客和视频中分享了很多关于Spring Security的知识和经验。如果你想学习Spring Security,可以参考他的笔记和教程。 ### 回答2: Spring Security 是一个强大的开源安全框架,用于保护 Spring 应用程序。它提供了一系列的安全服务,例如身份验证(Authentication)、授权(Authorization)、密码加密、会话管理等。 狂神在他的 Spring Security 笔记中详细介绍了该框架的使用方式和相关概念。首先,他解释了身份验证的重要性,提及了不同的身份验证方法,如基于表单的认证、基于记住我(Remember Me)的认证以及基于 HTTP Basic 和 Digest 验证等。他还介绍了如何自定义认证过程和处理认证失败的方法。 其次,狂神介绍了授权的概念和不同的授权方式。他解释了基于角色(Role)的访问控制和基于资源(Resource)的访问控制,并示范了如何在 Spring Security 中实现这些授权方式。他还介绍了如何使用注解和表达式来简化授权配置。 此外,狂神还介绍了 Spring Security 提供的其他功能,如密码加密、会话管理、防止跨站点请求伪造(CSRF)攻击等。他指导读者如何使用这些功能来增强应用程序的安全性。 总的来狂神Spring Security 笔记对于初学者来是一个很好的入门指南。他提供了丰富的示例代码和详细解释,让读者可以很容易地理解和使用 Spring Security。无论是开发 Web 应用程序还是企业级应用程序,掌握 Spring Security 都是非常重要的,狂神笔记提供了一个很好的起点。 ### 回答3: spring security 是一个开源的安全框架,可以为应用程序提供身份验证和授权管理的功能。它基于 JavaEE 标准认证和授权机制,并提供了一套更灵活的安全性管理机制。 首先,Spring Security 实现了用户认证的功能,可以通过多种认证方式来验证用户的身份,包括基于数据库的认证、LDAP 认证、OAuth2 认证等。可以根据具体的需求选择使用不同的认证方式。 其次,Spring Security 提供了授权管理的功能,可以设置不同的权限角色,对不同的用户进行授权。可以通过配置的方式进行权限的控制,通过注解或者编程的方式进行细粒度的控制,可以灵活地满足不同的应用需求。 另外,Spring Security 还提供了许多其他的安全支持功能,如防止 CSRF 攻击、防止点击劫持、防止 SQL 注入等。它还支持与其他框架的集成,如与 Spring Boot、Spring MVC 的集成,可以方便地在现有的应用中集成安全功能。 Spring Security 的架构清晰,易于理解和使用。它的设计模式和扩展机制可以满足不同级别的定制需求,使得我们可以根据实际情况来灵活地进行使用和扩展。同时,Spring Security 还提供了丰富的文档和示例代码,方便开发者学习和使用。 总之,Spring Security 是一个功能强大且灵活的安全框架,可以在应用程序中实现身份验证和授权管理的功能。通过使用 Spring Security,我们可以有效地保护和管理我们的应用程序,提升系统的安全性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值