spring笔记

1.SpringFramework

loc

ioc中用到了 反射 工厂模式 xml解析

ioC:inversion of control 控制反转

作用:将创建对象的过程交由ioc管理

ioc管理的对象默认都是单例的

Spring提供的两个ioc接口:

1: BeanFactory:ioc容器基本实现,是spring内部使用的接口,不提供开发人员使用,

2: ApplicationContext: BeanFactory接口的子接口,提供的功能更多,提供给开发人员使用

//BeanFactory[Bean工厂]   管理实现类的工厂(懒汉:在第一次使用时实例化对象)
//ApplicationContext 管理实现类的工厂(饿汉:在服务器启动时把所有对象实例化)   extends BeanFactory

Bean管理:

bean管理指的是两个操作
(1)spring创建对象
(2)spring注入属性

ioc操作bean管理:

基于xml方式创建对象:

<bean id="iocService" class="com.javakc.spring.ioc.service.impl.IocServiceImpl"/>

(1) 在spring配置文件中使用bean标签,在bean标签里面添加对应属性就可以实现对象创建

(2)bean标签中常用的属性

  • id 唯一标示(起别名)
  • class 写类的全路径

(3)创建对象时,会默认执行无参构造方法


spring中有两种bean(普通bean和工厂bean(FactoryBean))

1.普通bean:在配置文件中定义bean类型就是返回类型

2.工厂bean:在配置文件定义bean类型可以和返回类型不一样

工厂bean操作

第一步 创建类,让这个类作为工厂 bean,实现接口 FactoryBean
第二步 实现接口里面的方法,在实现的方法中定义返回的 bean 类型

public class MyBean implements FactoryBean<Course> {
 //定义返回 bean
 @Override
 public Course getObject() throws Exception {
 Course course = new Course();
 course.setCname("abc");
 return course;
 }
 @Override
 public Class<?> getObjectType() {
 return null;
 }
 @Override
 public boolean isSingleton() {
 return false;
 } }
1.bean的作用域

Spring 里面,设置创建 bean 实例是单实例还是多实例(单实例表示只有一个对象,多实例表示每次都创建一个新的对象)默认是单实例对象

如何设置单实例还是多实例

(1) 在 spring 配置文件 bean 标签里面有属性(scope)用于设置单实例还是多实例

(2) scope 属性值 第一个值 默认值 singleton 表示是单实例对象

​ 第二个值 prototype,表示是多实例对象

<bean id="book" class="com.atguigu.spring5.bean.Book" scope="prototype">
        <property name="bname" ref="bookList"/>
</bean>

singleton 和 prototype 区别

第一 singleton 单实例,prototype 多实例

第二 设置 scope 值是 singleton 时候,加载 spring 配置文件时候就会创建单实例对象

设置 scope 值是 prototype 时候,不是在加载 spring 配置文件时候创建 对象,在调用

getBean 方法时候创建多实例对象

2.bean的生命周期

1)通过构造器创建 bean 实例(通过执行无参数构造,把对象创建)

2)为 bean 的属性设置值和对其他 bean 引用(调用 set 方法)

3)后置处理器方法postProcessBeforeInitialization(在初始化方法之前运行)

4)调用 bean 的初始化的方法(需要进行配置初始化的方法)

5)后置处理器方法postProcessAfterInitialization(在初始化方法之后运行)

6 ) bean 可以使用了(对象获取到了)

7 ) 当容器关闭时候,调用 bean 的销毁的方法(需要进行配置销毁的方法)

public Orders(){
        System.out.println("第一步 执行无参构造创建bean实例");
    }

    private String oname;

    public void setOname(String oname) {
        this.oname = oname;
        System.out.println("第二步 调用set方法设置属性值");
    }

    //创建初始化方法
    public void initMethod(){
        System.out.println("第四步 执行初始化方法"); //需要在xml中配置该方法为初始化方法
    }

    //创建销毁方法
    public void destroyMethod(){
        System.out.println("第七步 执行销毁方法"); //需要在xml中配置该方法为初始化方法
    }

xml配置文件代码

<bean id="orders" class="com.atguigu.spring5.bean2.Orders" init-method="initMethod" destroy-method="destroyMethod">
    <property name="oname" value="手机"/>
</bean>

<!--配置后置处理器-->
<bean id="mybeanPost" class="com.atguigu.spring5.bean2.MybeanPost"/>

测试代码

@Test
    public void testbean2() {
        ApplicationContext context = new ClassPathXmlApplicationContext("bean2.xml");

        Orders orders = context.getBean("orders", Orders.class);
        System.out.println("第六步 获取创建bean实例对象");

        //手动让bean实例销毁
        ((ClassPathXmlApplicationContext)context).close();
    }

    //销毁方法二
    @Test
    public void testbean3(){
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("bean2.xml");

        Orders orders = context.getBean("orders", Orders.class);
        System.out.println("第六步 获取创建bean实例对象");

        //手动让bean实例销毁
        context.close();
    }

后置处理器方法代码

public class MybeanPost implements BeanPostProcessor {
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("第三步 在初始化方法之前执行");
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("第五步 在初始化方法之后执行");
        return bean;
    }
}

后置处理器写法: (1).实现BeanPostProcessor接口 (2).重写后置方法 (3).在xml文件中配置后置处理器(将该类交由ioc容器管理)

后置处理器的作用:会为当前配置文件中所有bean对象添加后置处理器

3.xml自动装配
  1. 什么是自动装配

(1)根据指定装配规则(属性名称或者属性类型),Spring 自动将匹配的属性值进行注入

  1. 实现自动装配

bean 标签属性 autowire,配置自动装配

autowire 属性常用两个值:

byName 根据属性名称注入 ,注入值 bean 的 id 值和类属性名称一样

byType 根据属性类型注入

根据名称装配

<bean id="emp" class="com.atguigu.spring5.autowire.Emp" autowire="byName"/>

<bean id="dept" class="com.atguigu.spring5.autowire.Dept"/>

根据类型装配

<bean id="emp" class="com.atguigu.spring5.autowire.Emp" autowire="byType"/>

<bean id="dept" class="com.atguigu.spring5.autowire.Dept"/>
4.外部属性文件

druid

引入外部属性文件配置数据库连接池

(1).引入druid(德鲁伊)jar包

(2).引入mysql驱动Jar包

(3).创建外部属性文件,properties 格式文件,写数据库信息

prop.driverClass=com.mysql.jdbc.Driver
prop.url=jdbc:mysql://127.0.0.1:3306/spring5?serverTimezone=Asia/Shanghai&use Unicode=true&characterEncoding=UTF-8&useSSL=false
prop.userName=root
prop.possword=123456

(4).把外部 properties 属性文件引入到 spring 配置文件中

<!--引入context命名空间-->
<!--引入properties文件-->
<context:property-placeholder location="classpath:jdbc.properties"/>

(5)配置连接池

<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="driverClassName" value="${prop.driverClass}"/>
        <property name="url" value="${prop.url}"/>
        <property name="username" value="${prop.userName}"/>
        <property name="password" value="${prop.possword}"/>
    </bean>
从bean管理中获取对象:
  1. 将类写入到ioc容器中

     <bean id="iocService" class="com.javakc.spring.ioc.service.impl.IocServiceImpl"/>
    
  2. 加载xml配置文件 (加载配置文件时,写入到配置文件中的类将会被实例化)

     ApplicationContext context = new ClassPathXmlApplicationContext("spring-ioc.xml");
    

    ClassPathXmlApplicationContext 可以换成 FileSystemXmlApplicationContext

ClassPathXmlApplicationContext : xml文件在src下有这个 (在src目录下可以直接写文件名)

FileSystemXmlApplicationContext : xml文件在盘符路径下用这个 (需要写全路径)

ClassPathXmlApplicationContext 和 FileSystemXmlApplicationContext 都实现了 ApplicationContext接口

  1. 从ioc容器里获取bean对象

     IocService iocservice= context.getBean("iOCService",IocService.class);
    写法二
        context.getBean("iOCService")	//返回object类型
    

    或者写 context.getBean(“iocService”,IocService.class); //IocService.class表示转换成该类型,如果不转换返回的是object类型

DI

DI:Dependency Injection 依赖注入

依赖注入的两种方式?

  1. setter注入
  2. 构造器注入 (官方推荐)

基于xml方式 手动装配

1.set方法注入属性

(1) 创建类,定义属性和对应的set方法

//创建属性
 private String name;
 private String age;

 //创建set方法
 public void setName(String name) {
     this.name = name;
 }

 public void setAge(String age) {
     this.age = age;
 }

(2) 在spring配置文件中 配置属性注入

<bean id="springdi" class="com.atguigu.spring5.SpringDi">
     <!--使用property完成属性注入
         name:类里面属性名称
         value:向属性里注入的值
		 ref:向属性中注入对象,里面写的是bean标签中的id值
     -->
     <property name="name" value="安鹏"/>
     <property name="age" value="21"/>
</bean>

注入其他类型属性

(1) 注入null值

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

(2)属性值包含特殊符号

​ 方法一 将符号转义 &gt …

​ 方法二将内容写到CDATA //了解就行

2.有参构造注入属性

(1)创建属性 , 和属性对应的有参构造方法

//创建属性
 private String name;
 private int age;
 //创建有参构造方法
 public SpringDi1(String name,int age){
     this.name=name;
     this.age=age;
 }

(2) 在spring配置文件中 配置属性注入

<bean id="springdi1" class="com.atguigu.spring5.SpringDi1">
     <!--使用constructor-arg完成属性注入
         name:类里面属性名称
         value:向属性里注入的值
			ref:注入类
			index: 表示构造方法里的第n个参数(0表示第一个)
     -->
     <constructor-arg name="name" value="anpeng"/>
     <constructor-arg name="age" value="21"/>
</bean>

如果要注入对象 用 ref=“类名” //注入的类需要在ioc容器中

3.外部bean-注入属性

(1)创建两个类service和dao

(2)在service中调用dao中的方法

(3)创建属性 和对应的注入方式(set或构造方法)

//创建SpringDiDao类型的属性
    private SpringDiDao springDiDao;

    //有参构造 创建SpringDiDao类型的参数
    public SpringDiService(SpringDiDao springDiDao){
        this.springDiDao=springDiDao;
    }

(4)在spring配置文件中进行配置

<!--创建dao和service对象-->
    <bean id="springDiDao" class="com.atguigu.spring5.dao.SpringDiDaoImpl"></bean>
    <bean id="springDiService" class="com.atguigu.spring5.service.SpringDiService">
        <!--将dao注入到service中-->
        <constructor-arg ref="springDiDao"/>
 </bean>

使用set方法注入:

4.内部bean和级联赋值
<bean id="emp" class="com.atguigu.spring5.bean.Emp">
        <property name="ename" value="安鹏"/>
        <property name="gender" value=""/>
        <property name="dept">
            <bean id="dept" class="com.atguigu.spring5.bean.Dept">
                <property name="dname" value="财务部"/>
            </bean>
        </property>
    </bean>

在bean标签里嵌套一个bean

5.xml注入数组集合类型属性

(1)定义 数组,set,list,map集合属性,并创建get方法或有参构造

 //数组类型属性
 private String[] courses;

 //list集合类型属性
 private List<String> list;

 //set集合属性
 private Set<String> sets;

 //map集合属性
 private Map<String,String> maps;

 public void setCourses(String[] courses) {
     this.courses = courses;
 }

 public void setSets(Set<String> sets){
     this.sets=sets;
 }

 public void setList(List<String> list) {
     this.list = list;
 }

 public void setMaps(Map<String, String> maps) {
     this.maps = maps;
 }

(2)在spring配置文件中进行配置

<bean id="springDi2" class="com.atguigu.spring5.SpringDi2">
     <!--注入数组类型-->
     <property name="courses">
         <array>
             <value>java课程</value>
             <value>数据库课程</value>
         </array>
     </property>
     <!--注入list类型-->
     <property name="list">
         <list>
             <value>张三</value>
             <value>李四</value>
         </list>
     </property>
     <!--注入set类型-->
     <property name="sets">
         <set>
             <value>Mysql</value>
             <value>Redis</value>
         </set>
     </property>
     <!--注入map集合-->
     <property name="maps">
         <map>
             <entry key="JAVA" value="java"></entry>
             <entry key="PYTHON" value="python"></entry>
         </map>
     </property>
 </bean>

在注入属性标签(property或constructor-arg)里使用对应标签(array,list,set,map)来添加多个值

6.在集合里面设置对象类型的值

(1)在集合里面设置对象类型的值

<bean id="springDi22" class="com.atguigu.spring5.SpringDi2">
        <property name="courselist">
            <list>
                <ref bean="course1"/>
                <ref bean="course2"/>
            </list>
        </property>
    </bean>

(2)创建多个coursel对象

<bean id="course1" class="com.atguigu.spring5.bean.Course">
        <property name="cname" value="Spring5"/>
        <property name="cnumber" value="2022/3/1"/>
    </bean>
    <bean id="course2" class="com.atguigu.spring5.bean.Course">
        <property name="cname" value="Mybatis"/>
        <property name="cnumber" value="2022/3/1"/>
    </bean>
7.把集合注入部分提取出来
<!--提取list集合类型属性注入-->
    <util:list id="bookList">	//引入命名空间:util
        <value>苹果</value>
        <value>小米</value>
        <value>华为</value><!--注入对象类型用ref-->
    </util:list>

    <!--提取list集合类型属性使用-->
    <bean id="book" class="com.atguigu.spring5.bean.Book" scope="prototype">
        <property name="bname" ref="bookList"/>
    </bean>
使用方法 基于xml方式:

1.构造方法注入

  1. 方法注入

     <bean id="iocService" class="com.javakc.spring.ioc.service.impl.IocServiceImpl">
            <!--        构造方法注入-->
            <constructor-arg ref="iocDao"/>
    </bean>
    
  2. 注入

       IocDao iocDao;
        //构造方法注入
        public IocServiceImpl(IocDao iocDao) {
            this.iocDao=iocDao;
        }
    

2.set方法注入

  1. 方法注入

     <property name="iocDao123" ref="iocDao"/>
    

Ioc基于注解

使用注解的目的:为了简化xml配置

1.使用注解创建对象

Spring 针对 Bean 管理中创建对象提供注解

1)@Component //通用

2)@Controller //web表现层

3)@Service //service逻辑层

4)@Repository //dao数据层

参数: value=“” 等同于 基于配置里面的bean的id


基于注解方式实现对象创建

(1).注入AOP依赖

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QzhgJI4F-1648730877378)(spring%E7%AC%94%E8%AE%B0.assets/image-20220302211129213.png)]

(2).开启注解扫描

<context:component-scan base-package="com.atguigu.spring5.comment,com.atguigu.spring5.bean"/>

扫描多个包用逗号分割

(3).创建类,在类上面添加创建对象注解

@Service(value = "userService") //value属性值可以省略不写,默认值是类名 首字母小写

开启注解扫描细节配置(指定扫描注解)

<!--
 use-default-filters="false" 表示不使用默认filter, 自己配置filter  (自己指定扫描哪写注解)
 context:include-filter  设置扫描那些注解
    -->
    <context:component-scan base-package="com.atguigu.spring5.comment" use-default-filters="false">
        <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
    </context:component-scan>

2.使用注解实现属性注入

  1. @AutoWired 根据属性类型进行自动装配

    1. 第一步 把 service 和 dao 对象创建,在 service 和 dao 类添加创建对象注解

      第二步 在 service 注入 dao 对象,在 service 类添加 dao 类型属性,在属性上面使用注解

      @Autowired
      private DiDao diDao;
      
  2. @Qualifier 根据属性名称进行注入

    1. @Qualifier 注解需要和上面@Autowired 一起使用

    2. 在属性上添加注解

      @Autowired  //根据类型注入
      @Qualifier(value = "diDaoImpl")  //根据名称注入   名称默认是类的首字母小写
      private DiDao diDao;
      
  3. @Resource 可以根据属性注入,也可以根据名称注入

    1. 引入jar包[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IqyceHn0-1648730877381)(spring%E7%AC%94%E8%AE%B0.assets/image-20220304120236575.png)]

    2. 在属性上添加注解

      //@Resource   //根据类型注入
      @Resource(name = "diDaoImpl")   //根据名称注入
      private DiDao diDao;
      
  4. @Value 注入普通类型属性

    1. 在属性上添加注解

      @Value(value = "写要注入的值")
      private String name;
      

3.完全注解开发

目的:为了代替xml配置文件

步骤一:创建配置类

@Configuration  //作为配置类,代替xml配置文件
@ComponentScan(basePackages = {"com.atguigu.spring5"})  //开启注解扫描
public class SpringConfig {
    
}

步骤二:编写测试类

@Test
public void SpringConfigTest() {
        //加载配置类
        ApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);
    }
配置属性
属性名称默认值属性作用
idnull唯一标识符用于获取示例
namenull别名 可以定义多个(别名)name=“a,b”
classnull有ioc容器负责实例化的对象
lazy-initfalsefalse:单例 饿汉
true:单例 懒汉
init-methodnullioc容器在对象全部实例化完成后调用
destroy-methodnullioc容器在对象销毁前调用的方法
primaryfalse优先装配
depends-onnull优先实例化
autowirenullbyName:根据属性名称自动装配
byType:根据属性类型自动装配
constructor:根据构造方法primary name type
scopesingleton1.singleton:单例模式
2.prototype:原型模式
3.request:请求模式
4.session:会话模式
5.application:应用模式
6.websocket:web通信模式
基于注解

常用注解

控制反转
@Controller声明表现层实现类
@Service声明逻辑层实现类
@Repository声明数据层实现类
@Component声明通用组件
依赖注入
@Resourc
@Autowired
@Qualifier
@Value
属性注解
@Primary优先装配
@Lazy改变单例模式为懒汉模式
@Scope改变类的实现化方式原型
@PostConstructioc容器在对象全部实例化完成后调用
@PreDestroyioc容器在对象销毁前调用的方法
测试注解
@Test修饰测试方法
@Before测试方法前调用
@RunWith运行spring-test方法
@ContextConfiguration读取配置文件

jdk9以后引入模块

annotation [注解]


2.AOP

aop的作用:在不修改原有代码的同时,添加一些新的功能

有两种情况动态代理

第一种 有接口情况,使用 JDK 动态代理

​ 创建接口实现类代理对象,增强类的方法

​ [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iDfpeSzH-1648730877384)(spring%E7%AC%94%E8%AE%B0.assets/image-20220304150249675.png)]

第二种 没有接口情况,使用 CGLIB 动态代理

​ 创建子类的代理对象,增强类的方法

​ [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pYIOX3Pq-1648730877385)(spring%E7%AC%94%E8%AE%B0.assets/image-20220304150336175.png)]

JDK动态代理

  1. 使用 JDK 动态代理,使用 Proxy 类里面的方法创建代理对象

    1. 调用 newProxyInstance 方法

      1. 方法有三个参数:

        第一参数,类加载器

        第二参数,增强方法所在的类,这个类实现的接口,支持多个接口

        第三参数,实现这个接口 InvocationHandler,创建代理对象,写增强的部分

AOP(术语)
  1. 连接点

    类里面可以被增强的方法叫连接点

  2. 切入点

    实际真正被增强的方法,叫切入点

  3. 通知

    1. 实际增强的部分叫通知
    2. 通知有多重类型
      1. 前置通知
      2. 后置通知
      3. 环绕通知
      4. 异常通知
      5. 最终通知
  4. 切面

    把通知应用到切入点的过程

AOP操作(准备工作)
  1. Spring 框架一般都是基于 AspectJ 实现 AOP 操作

(1)AspectJ 不是 Spring 组成部分,独立 AOP 框架,一般把 AspectJ 和 Spirng 框架一起使

用,进行 AOP 操作

  1. 在项目工程里面引入 AOP 相关依赖

    1. [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bY09ySg4-1648730877386)(spring%E7%AC%94%E8%AE%B0.assets/image-20220308135746784.png)][外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0ZHFOMfj-1648730877386)(spring%E7%AC%94%E8%AE%B0.assets/image-20220308135842300.png)][外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0OCCP1H0-1648730877387)(spring%E7%AC%94%E8%AE%B0.assets/image-20220308140031614.png)]
  2. 切入点表达式

    1. 切入点表达式作用:知道对哪个类里面的哪个方法进行增强

    2. 语法结构: execution([权限修饰符] [返回类型] [类全路径] 方法名称 ) //返回类型可以省略不写

      1. 举例 1:对 com.atguigu.dao.BookDao 类里面的 add 进行增强

        execution(* com.atguigu.dao.BookDao.add(…))

      2. 举例 2:对 com.atguigu.dao.BookDao 类里面的所有的方法进行增强

        execution(* com.atguigu.dao.BookDao.* (…))

      3. 举例 3:对 com.atguigu.dao 包里面所有类,类里面所有方法进行增强

        execution(* com.atguigu.dao.*.* (…))

      4. 第一个 星号 表示任何权限都可以,

        第二个 星号 表示所有方法

        第三个 星号 表示所有类

        第一个 点点 表示任何类型的任意数量的参数

    3. 2)

AOP操作(注解)
  1. 创建被增强类,在类里面定义方法

    @Component
    public class User {
        public void add(){
            System.out.println("add方法");
        }
    }
    
  2. 创建增强类(编写增强逻辑)

    @Aspect
    @Component
    public class UserProxy {
        //前置通知
        public void before(){
            System.out.println("before 前置通知");
        }
    }
    
  3. 进行通知的配置

    1. 在 spring 配置文件中,开启注解扫描

      <context:component-scan base-package="com.atguigu.spring5.AspectJAOP"/>
      
    2. 使用注解创建 User 和 UserProxy 对象

      @Component
      
    3. 在增强类上面添加注解 @Aspect

      @Aspect
      
    4. 在 spring 配置文件中开启生成代理对象

      <!--开启 Aspect 生成代理对象-->
      <aop:aspectj-autoproxy/><!--扫描到Aspect注解后将改类定为代理类-->
      
  4. 配置不同类型的通知

    //增强类
    @Aspect
    @Component
    public class UserProxy {
        //前置通知
        @Before(value = "execution(* com.atguigu.spring5.AspectJAOP.User.add(..))")
        public void before(){
            System.out.println("before 前置通知");
        }
        //后置通知
        @AfterReturning(value = "execution(* com.atguigu.spring5.AspectJAOP.User.add(..))")
        public void afterReturning(){
            System.out.println("后置通知");
        }
        //最终通知
        @After(value = "execution(* com.atguigu.spring5.AspectJAOP.User.add(..))")
        public void after(){
            System.out.println("最终通知");
        }
        //异常通知
        @AfterThrowing(value = "execution(* com.atguigu.spring5.AspectJAOP.User.add(..))")
        public void afterThrowing(){
            System.out.println("异常通知");
        }
        //环绕通知
        @Around(value = "execution(* com.atguigu.spring5.AspectJAOP.User.add(..))")
        public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
            System.out.println("环绕通知前");
            proceedingJoinPoint.proceed();
            System.out.println("环绕通知后");
        }
                                     
    }
                                     
    

    相同切入点抽取

    @Pointcut(value = "execution(* com.atguigu.spring5.AspectJAOP.User.add(..))")
        public void pointdemo(){
                                             
        }
        //前置通知
        @Before(value = "pointdemo()")
        public void before(){
            System.out.println("before 前置通知");
        }
                                         
    

    有多个增强类多同一个方法进行增强,设置增强类优先级

    在增强类上面添加注解 @Order(数字类型值),数字类型值越小优先级越高

    @Aspect
    @Component
    @Order(1)
    public class PersonProxy {
                                     
        @Before(value = "execution(* com.atguigu.spring5.AspectJAOP.User.add(..))")
        public void before(){
            System.out.println("PersonProxy");
        }
    }
                                     
    

    完全注解开发

    @Configuration  //作为配置类,代替xml配置文件
    @ComponentScan(basePackages = {"com.atguigu.spring5"})  //开启注解扫描
    @EnableAspectJAutoProxy(proxyTargetClass = true)//开启 Aspect 生成代理对象
    public class ConfigAop {
                                     
    }
                                     
    
AOP操作(基于配置)

1、创建两个类,增强类和被增强类,创建方法

2、在spring 配置文件中创建两个类对象

<bean id="book" class="com.atguigu.spring5.AopXml.Book"/>
<bean id="bookProxy" class="com.atguigu.spring5.AopXml.BookProxy"/>

3**、在** spring 配置文件中配置切入点

<!--配置aop增强-->
    <aop:config>
        <!--切入点-->
        <aop:pointcut id="p" expression="execution(* com.atguigu.spring5.AopXml.Book.buy(..))"/>

        <!--配置切面-->
        <aop:aspect ref="bookProxy"><!--ref里面写增强类-->
            <!--增强作用在具体的方法上-->
            <aop:before method="before" pointcut-ref="p"/><!--method写增强的方法  arg-names写切入点-->
        </aop:aspect>
    </aop:config>

JdbeTemplate

JdbcTemplate(概念和准备)
  1. 什么是 JdbcTemplate

    Spring 框架对 JDBC 进行封装,使用 JdbcTemplate 方便实现对数据库操作

  2. 准备工作

    1. 引入相关 jar 包

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-h180yhxA-1648730877396)(spring%E7%AC%94%E8%AE%B0.assets/image-20220309161748151.png)]

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fUfXcA06-1648730877397)(spring%E7%AC%94%E8%AE%B0.assets/image-20220309161813170.png)]mysql驱动

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bdORgNkI-1648730877399)(spring%E7%AC%94%E8%AE%B0.assets/image-20220309161951353.png)]底层封装了jdbc

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-22T0KyaX-1648730877399)(spring%E7%AC%94%E8%AE%B0.assets/image-20220309162041846.png)]针对事务想过操作的依赖

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NlCsSDs6-1648730877400)(spring%E7%AC%94%E8%AE%B0.assets/image-20220309162135901.png)]整合Mybatis或其他框架时使用

    2. 在 spring 配置文件配置数据库连接池

      <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" destroy-method="close">
              <property name="url" value="jdbc:mysql:///spring5" />
              <property name="username" value="root" />
              <property name="password" value="123456" />
              <property name="driverClassName" value="com.mysql.jdbc.Driver" />
          </bean>
      
    3. 配置jdbcTemplate对象,注入数据源

      <!--JdbcTemplate对象-->
          <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
              <!--注入数据源-->
              <property name="dataSource" ref="dataSource"/>
          </bean>
      
    4. 创建 service 类和 dao 类,在 dao 注入 jdbcTemplate 对象

      扫描包

      <context:component-scan base-package="com.atguigu.jdbeTemplate"/>
      

      注入对象

      @Repository
      public class BookDaoImpl implements BookDao{
          @Autowired
          private JdbcTemplate jdbcTemplate;
      }
      
JdbcTemplate操作数据库(添加)
  1. 对应数据库字段创建实体类,并生成get set方法

  2. 编写 service dao

    1. 调用 JdbcTemplate 对象里面 update 方法实现添加操作

      1. [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tIW3SQY8-1648730877401)(spring%E7%AC%94%E8%AE%B0.assets/image-20220309172013130.png)]

      2. 第一个参数:写sql 语句

        第二个参数:写可变参数,设置 sql 语句值

      3. @Repository
        public class BookDaoImpl implements BookDao {
            @Autowired
            private JdbcTemplate jdbcTemplate;
                                                                                         
            @Override
            public void add(Book book) {
                //创建sql语句
                String sql = "insert into jdbctemplate value(?,?,?)";
                //调用方法实现
                int update = jdbcTemplate.update(sql, book.getUserId(), book.getUsername(), book.getUstatus());
                System.out.println(update);
            }
        }
        
      4. 测试类

        public class JdbcTemplateTest {
            @Test
            public void test() {
                ClassPathXmlApplicationContext contest = new ClassPathXmlApplicationContext("dbPool.xml");
                BookService bookService = contest.getBean("bookService", BookService.class);
                Book book=new Book();
                book.setUserId(3);
                book.setUsername("java");
                book.setUstatus("a");
                bookService.add(book);
            }
        }
        
JdbcTemplate操作数据库(修改,删除)
//修改方法
    @Override
    public void updateBook(Book book) {
        //创建sql语句
        String sql = "update jdbctemplate set book_name=?,ustatus=?  where book_id=?";
        int update = jdbcTemplate.update(sql, book.getBookname(), book.getUstatus(), book.getBookId());
        System.out.println(update);
    }

    //删除方法
    @Override
    public void deleteBook(String id) {
        String sql="delete from jdbctemplate where book_id=?";
        int update= jdbcTemplate.update(sql,id);
        System.out.println(update);
    }
JdbcTemplate操作数据库(查询)
查询返回单个值

使用[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LUI9GqW4-1648730877402)(spring%E7%AC%94%E8%AE%B0.assets/image-20220313181149861.png)]
方法

第一个参数:sql 语句
第二个参数:返回类型 Class

//查询表中有多少条记录
    @Override
    public int findCount() {
        String sql = "select count(*) from jdbctemplate";
        Integer count = jdbcTemplate.queryForObject(sql, Integer.class);//第二个参数是 返回类型.class
        return count;
    }
查询返回对象

使用[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5BbKHXAf-1648730877403)(spring%E7%AC%94%E8%AE%B0.assets/image-20220313181305484.png)]
方法

第一个参数:sql 语句
第二个参数:RowMapper 是接口,针对返回不同类型数据,使用这个接口里面实现类完成数据封装
第三个参数:sql 语句值

//查询返回对象
    @Override
    public Book findOne(String id) {
        String sql = "select * from jdbctemplate where book_id=?";
        Book book = jdbcTemplate.queryForObject(sql, new BeanPropertyRowMapper<Book>(Book.class), id);
        return book;
    }

查询返回集合

//查询返回集合(查询全部数据)
 @Override
 public List<Book> findAll() {
     String sql = "select * from jdbctemplate";
     List<Book> list = jdbcTemplate.query(sql,new BeanPropertyRowMapper<Book>(Book.class));
     return list;
 }

JdbcTemplate操作数据库(批量添加)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4cggm9Tc-1648730877404)(spring%E7%AC%94%E8%AE%B0.assets/image-20220315184953944.png)]

第一个参数:sql 语句
第二个参数:List 集合,添加多条记录数据

添加方法

//批量添加
    @Override
    public void batchAdd(List<Object[]> batchArgs) {
        String sql="insert into jdbctemplate value(?,?,?)";
        jdbcTemplate.batchUpdate(sql,batchArgs);
    }

测试方法

//批量添加
        List<Object[]> list=new ArrayList<>();
        Object[] o1={6,"ppp","aaa"};
        Object[] o2={7,"ooo","acccaa"};
        Object[] o3={8,"qqq","nnn"};
        list.add(o1);
        list.add(o2);
        list.add(o3);
        bookService.batchAdd(list);

JdbcTemplate操作数据库(批量修改)

//批量修改
    @Override
    public void batchUpdate(List<Object[]> batchArgs) {
        String sql = "update jdbctemplate set book_name=?,ustatus=? where book_id=?";
        int[] ints = jdbcTemplate.batchUpdate(sql, batchArgs);
        System.out.println(Arrays.toString(ints));
    }

JdbcTemplate操作数据库(批量删除)

//批量删除
    @Override
    public void batchDelete(List<Object[]> batchArgs) {
        String sql="delete from jdbctemplate where book_id=?";
        int[] ints=jdbcTemplate.batchUpdate(sql,batchArgs);
        System.out.println(Arrays.toString(ints));
    }

事务操作

事务概念

事务是数据库操作最基本单元,操作一条或多条sql语句时,要么都成功,要么都失败

事务的四个特性:

2、事务四个特性(ACID)

1)原子性 一个事务(transaction)中的所有操作,要么全部完成,要么全部不完成
2)一致性 在事务开始之前和事务结束以后,数据库的完整性没有被破坏
3)隔离性 事务和事务之间相互隔离
4)持久性 事务处理结束后,对数据的修改就是永久的,即便系统故障也不会丢失

搭建实务操作环境

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NSsezF5U-1648730877404)(spring%E7%AC%94%E8%AE%B0.assets/image-20220316104132732.png)]

  1. 创建 service,搭建dao,完成对象创建和注入关系
    (1)service 注入 dao,在 dao 注入 JdbcTemplate,在 JdbcTemplate 注入 DataSource

  2. dao 创建两个方法:多钱和少钱的方法,在 service 创建方法(转账的方法)

    @Repository
    public class UserDaoImpl implements UserDao{
        @Autowired
        private JdbcTemplate jdbcTemplate;
    
        //添加钱
        @Override
        public void addMoney() {
            String sql="update account set money=money+? where username=?";
            jdbcTemplate.update(sql,100,"lucy");
        }
    
        //减少钱
        @Override
        public void reduceMoney() {
            String sql="update account set money=money-? where username=?";
            jdbcTemplate.update(sql,100,"mary");
        }
    }
    
  3. 在service中添加 转账方法

    @Service
    public class UserService {
        @Autowired
        private UserDao userDao;
    
        //转账方法
        public void accountMoney() {
            //加钱
            userDao.addMoney();
            //少钱
            userDao.reduceMoney();
        }
    }
    
  4. 添加事务

事务的操作过程
@Service
public class UserService {
    @Autowired
    private UserDao userDao;

    //转账方法
    public void accountMoney() {
        try{
            //第一步 开启事务

            //第二步 进行也不操作
            //加钱
            userDao.addMoney();

            //模拟异常
            int i=10/0;

            //少钱
            userDao.reduceMoney();

            //第三步 没有异常提交事务
        }catch (Exception e){
            //第四步 出现异常事务回滚
        }

    }
}
事务管理介绍
  1. 事务添加到 逻辑层

  2. 在Spring 进行事务管理操作

    1. 有两种方式:
      1. 编程式事务管理
      2. 声明式事务管理(使用)
  3. 声明式事务管理

    1. 基于注解方式(使用)
    2. 基于 xml 配置文件方式
  4. 在Spring进行声明式事务管理,底层使用AOP原理

  5. Spring事务管理API

    1. 提供一个接口,代表事务管理器,这个接口针对不同的框架提供不同的实现类

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7bqVGTFs-1648730877405)(spring%E7%AC%94%E8%AE%B0.assets/image-20220317151116873.png)]

事务操作(注解)
  1. 在spring配置文件配置事务管理器

        <!--创建事务管理器-->
        <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <!--不同框架的事务管理器不同如
            Mybaties用的是DataSourceTransactionManager
            Hibernate用的是HibernateTransactionManager
        -->
            <!--注入数据源-->
            <property name="dataSource" ref="dataSource"/>
        </bean>
    
  2. 在spring配置文件,开启事务注解

    1. 在 spring 配置文件引入名称空间 tx

    2. 开启事务注解

      <!--开启事务注解-->
          <tx:annotation-driven transaction-manager="transactionManager"/>
      
    3. 在service类上面(或者在方法上面)添加事务注解

      1. @Transactional,这个注解添加到类上面,也可以添加方法上面

      2. 如果把这个注解添加类上面,这个类里面所有的方法都添加事务

      3. 如果把这个注解添加方法上面,只为这个方法添加事务

      4. @Service
        @Transactional
        public class UserService {
        }
        
事务参数配置
事务传播行为
  1. propagation:事务传播行为

    1. 多事务方法之间进行调用,这个过程中事务 是如何进行管理的(如:有事务的调用没事务的)

    2. [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ar25Cypn-1648730877405)(spring%E7%AC%94%E8%AE%B0.assets/image-20220317174903537.png)]

    3. [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OU3H7e7R-1648730877406)(spring%E7%AC%94%E8%AE%B0.assets/image-20220317174943719.png)]

    4. @Service
      @Transactional(propagation = Propagation.REQUIRED)
      public class UserService {
      }
      
    5. PROPAGATION_REQUIRED (默认值)

事务隔离级别

ioslation事务隔离级别

  1. 脏读: 事务读取到了另一个未提交的事务

  2. 不可重复度: 一个未提交的事务读取到一个已提交的事务

  3. 幻读: 一个未提交事务读取到另一提交事务添加数据

  4. 解决方法: 使用 隔离级别

    1. [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hxeChwgE-1648730877406)(spring%E7%AC%94%E8%AE%B0.assets/image-20220317210445990.png)]

      mysql默认是可重复读

    2. 如何使用格林级别

      @Transactional(propagation = Propagation.REQUIRED,isolation = Isolation.REPEATABLE_READ)
      
超时时间

timeout:超时时间

  1. 事务如果未在指定时间内提交,则进行回滚

  2. 默认值:-1(-1表示不超时),设置时间以秒为单位

  3. timeout = -1

    @Transactional(timeout = -1, propagation = Propagation.REQUIRED,isolation = Isolation.REPEATABLE_READ)
    
是否只读

readOnly:是否只读

1)读:查询操作,写:添加修改删除操作

2)readOnly 默认值 false,表示可以查询,可以添加修改删除操作

3)设置 readOnly 值是 true,设置成 true 之后,只能查询

readOnly = false

@Transactional(readOnly = false, timeout = -1, propagation = Propagation.REQUIRED,isolation = Isolation.REPEATABLE_READ)
回滚

设置出现哪些异常进行事务回滚

不回滚

设置出现哪些异常不进行事务回滚

完全注解开发
  1. 创建配置类,使用配置类替代 xml 配置文件

  2. 配置类

    
    @Configuration //定义该类为配置类
    @ComponentScan(basePackages = "com.atguigu") //扫描包
    @EnableTransactionManagement //开启事务
    public class TxConfig {
        //创建数据库连接池
        @Bean
        public DruidDataSource getDataSource(){
            DruidDataSource dataSource = new DruidDataSource();
            dataSource.setDriverClassName("com.mysql.jdbc.Driver");
            dataSource.setUrl("jdbc:mysql://127.0.0.1:3306/spring5?serverTimezone=Asia/Shanghai&use Unicode=true&characterEncoding=UTF-8&useSSL=false");
            dataSource.setUsername("root");
            dataSource.setPassword("123456");
            return dataSource;
        }
    
        //创建jdbcTemplate对象
        @Bean
        public JdbcTemplate getJdbcTemplate(DataSource dataSource){
            JdbcTemplate jdbcTemplate=new JdbcTemplate();
            //注入DataSource
            jdbcTemplate.setDataSource(dataSource);
            return jdbcTemplate;
        }
    
        //创建事务管理器对象
        @Bean
        public DataSourceTransactionManager getTransactionManager(DataSource dataSource){
            DataSourceTransactionManager transactionManager=new DataSourceTransactionManager();
            transactionManager.setDataSource(dataSource);
            return transactionManager;
        }
    }
    
    
  3. 测试类

    @Test
        public void test2() {
            ApplicationContext context = new AnnotationConfigApplicationContext(TxConfig.class);
            UserService userService = context.getBean("userService", UserService.class);
            userService.accountMoney();
        }
    

xml代码


    <!--扫描包-->
    <context:component-scan base-package="com.atguigu"/>

    <!--引入properties-->
    <context:property-placeholder location="classpath:dataSource.properties"/>

    <!--创建数据源-->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" destroy-method="close">
        <property name="url" value="${prop.url}" />
        <property name="username" value="${prop.userName}" />
        <property name="password" value="${prop.password}" />
        <property name="driverClassName" value="${prop.driverClass}" />
    </bean>

    <!--创建JdbcTemplate对象-->
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <!--注入数据源-->
        <property name="dataSource" ref="dataSource"/>
    </bean>

    <!--创建事务管理器-->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <!--不同框架的事务管理器不同如
        Mybaties用的是DataSourceTransactionManager
        Hibernate用的是HibernateTransactionManager
    -->
        <!--注入数据源-->
        <property name="dataSource" ref="dataSource"/>
    </bean>
    <!--开启事务注解-->
    <tx:annotation-driven transaction-manager="transactionManager"/>

之后 学 spring5新特性

spring5整合Junit4

  1. 引入依赖

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4kU95c5G-1648730877407)(spring%E7%AC%94%E8%AE%B0.assets/image-20220318095616696.png)]

  2. 创建测试类 添加注解@RunWith和@ContextConfiguration

    @RunWith(SpringJUnit4ClassRunner.class)//定义Junit框架版本
    @ContextConfiguration("classpath:Transaction.xml")//加载配置文件
    public class JTest4 {
                      
        @Autowired
        private UserService userService;
                      
        @Test
        public void test1(){
            userService.accountMoney();
        }
    }
    

原测试文件

public class accountTest {
    @Test
    public void test1() {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("Transaction.xml");
        UserService userService = context.getBean("userService", UserService.class);
        userService.accountMoney();
    }
}

2.SpringMVC

执行流程

  1. DispatcherServlet表示前置控制器,是整个SpingMVC的控制中心,用户发出请求,
    DispatcherServlet接收请求并拦截请求
  2. 通过映射器将请求的url和Handler进行映射,然后返回给DispatcherServlet
  3. 根据HandlerAdapter(适配器)去找对应Controller类
  4. 在调用逻辑层调数据层
  5. 数据层返回数据到表现层
  6. 表现层携带数据(模型)和跳转的视图返回给HandlerAdapter(适配器)
  7. HandlerAdapter(适配器)在返回给DispatcherServlet
  8. DispatcherServlet再去调用视图解析器,将视图和模型传给视图解析器
    1. 视图解析器的任务
      1. 获取ModeAndView(模型和视图)
      2. 解析ModeAndView(模型和视图)的视图名字
      3. 拼接视图名字
      4. 将数据渲染到视图上
  9. 视图解析器将解析后的视图传给DispatcherServlet
  10. DispatcherServlet去找对应的视图
  11. 最终将视图返回给用户

使用步骤

  1. 创建maven项目

  2. 右击项目 选择

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ytbCRaWO-1648730877408)(spring笔记.assets/image-20220325170749072.png)]
    定义成web项目

  3. 在web.xml文件中注册DispatchServlet (注意修改 要关联springmvc的配置文件名 )

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
             version="4.0">
        <!--注册DispatchServlet-->
        <servlet>
            <servlet-name>springmvc</servlet-name>
            <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    
            <!--关联springmvc的配置文件-->
            <!--classpath: 只会到你的class路径中查找文件。
               classpath*: 不仅包含class路径,还包括jar文件中(class路径)进行查找-->
            <init-param>
                <param-name>contextConfigLocation</param-name>
                <param-value>classpath:springmvc-servlet.xml</param-value>
            </init-param>
    
            <!--启动级别 表示服务器启动时跟着启动-->
            <load-on-startup>1</load-on-startup>
        </servlet>
    
    
        <!-- / 匹配所有请求: (不包含.jsp)-->
        <!-- /* 匹配所有请求: (包含.jsp)-->
        <servlet-mapping>
            <servlet-name>springmvc</servlet-name>
            <url-pattern>/</url-pattern>
        </servlet-mapping>
    </web-app>
    
  4. 创建springmvc-servlet.xml文件 (在resources中创建)

    <?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:mvc="http://www.springframework.org/schema/mvc"
           xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd">
    
        <!--扫描包-->
        <context:component-scan base-package="com.kuang.controller"/>
    
        <!--让springmvc不处理静态资源(过滤资源,不交给视图解析器处理)(如 .css  .js   .html   .mp3    .mp4    ...)-->
        <mvc:default-servlet-handler/>
    
        <!--注册映射器和适配器 注册之后才能使@RequestMapping注解生效-->
        <mvc:annotation-driven/>
    
        <!--视图解析器-->
        <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="internalResourceViewResolver">
            <!--前缀-->
            <property name="prefix" value="/WEB-INF/jsp/"/>
            <!--后缀-->
            <property name="suffix" value=".jsp"/>
        </bean>
    </beans>
    
  5. 创建表现层

    @Controller
    @RequestMapping("/hello")   //父接收请求
    public class HelloMVC {
        
        @RequestMapping("/h1")   //接收请求
        public String Hello(Model model){
            //调用逻辑层
    
            //封装数据
            //model添加的值,可以再jsp页面中取出并渲染
            model.addAttribute("msg","Hello123123123123");
    
            //如果返回值是String,并且有具体页面可以跳转,就会被视图解析器处理,返回就是视图,
            return "hello";
        }
    }
    
  6. 创建要返回的jsp文件

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
        <title>Title</title>
    </head>
    <body>
    	${msg}<%--接收后端传来的参数--%>
    </body>
    </html>
    
  7. [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MoQaSCBs-1648730877408)(spring笔记.assets/image-20220325171418552.png)]

RestFul风格

@RequestMapping 能够处理HTTP请求的方法,比如 get; put; post; delete; ratch

地址栏请求默认是get请求

@GetMapping

@PostMapping

@PutMapping

@DeleteMapping

@PatchMapping

用法:@GetMapping(“/add/{参数a}/{参数b}”)

@PathVariable 接收请求路径中占位符的值
通过 @PathVariable 可以将 URL 中占位符参数绑定到控制器处理方法的入参中

表现层代码

@Controller
public class ResFul {
    /*
    * @PathVariable 接收请求路径中占位符的值
    * */
    @GetMapping("/get/{a}/{b}")
    public String GetUser(@PathVariable int a,@PathVariable int b, Model model){
        int msg=a+b;
        model.addAttribute("msg",msg);
        return "test";
    }
}

.jsp页面代码

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
  ${msg}
</body>
</html>

出现问题,检查tomcat和引包情况

转发和重定向

SpringMVC 默认是转发

重定向不能

如果要改成重定向需要添加redirect:

    @GetMapping("/get")
    public String GetUser1(Model model){
        String msg="123123";
        model.addAttribute("msg",msg);
        return "redirect:index.jsp";
    }

接收参数及数据回显

接收的参数和方法参数名一致

接收的参数名和方法参数名一致时可以直接接收到

@GetMapping("/user1")
public String User1(String name,Model model){
    //接收前端参数
    String msg=name;
    //将返回结果传递给前端
    model.addAttribute("msg",msg);
    //视图跳转
    return "test";
}

接收的参数和方法参数名不一致

需要用@RequestParam() 里面写接收的参数名

@GetMapping("/user2")
public String User2(@RequestParam("username") String name, Model model){
    //接收前端参数
    String msg=name;
    //将返回结果传递给前端
    model.addAttribute("msg",msg);
    //视图跳转
    return "test";
}

接收对象参数

接收的参数名需要和对象中的属性名一致,否则接收不到(会得到null值)

@GetMapping("/user3")
public String User3(User user){
    /*//接收前端参数
    String msg=user;
    //将返回结果传递给前端
    model.addAttribute("msg",msg);*/
    System.out.println(user);
    //视图跳转
    return "test";
}

测试路径 localhost:8080/user?id=1&name=an&age=3
? 号后 写接收的参数
& 号后 分割多个参数

返回字符串类型

使用@ResponseBody //他就不会走视图解析器,会直接返回一个字符串

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2KGLUSkp-1648730877409)(spring笔记.assets/image-20220328172348036.png)]

使用@RestController //他会将所有方法都返回一个字符串,不走视图解析器

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FBmdoPl5-1648730877409)(spring笔记.assets/image-20220328173046181.png)]

乱码问题

在web.xml文件中添加过滤器

<!--乱码过滤器-->
<filter>
    <filter-name>encoding</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    <init-param>
        <param-name>encoding</param-name>
        <param-value>utf-8</param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>encoding</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

Json

[]表示一个集合

{}表示对象

json解析工具 Jackson和阿里巴巴fastjson等等

<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.13.2.1</version>
</dependency>

<!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.75</version>
</dependency>

springmvc解决json乱码(添加到sping配置文件中)

<!--springmvc解决json乱码-->
<mvc:annotation-driven>
    <mvc:message-converters register-defaults="true">
        <bean class="org.springframework.http.converter.StringHttpMessageConverter">
            <constructor-arg value="UTF-8"/>
        </bean>
        <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
            <property name="objectMapper">
                <bean class="org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean">
                    <property name="failOnEmptyBeans" value="false"/>
                </bean>
            </property>
        </bean>
    </mvc:message-converters>
</mvc:annotation-driven>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值