Spring款框架详解(宝藏级)

  • Post author:
  • Post category:其他




简介

Spring : 春天 —>给软件行业带来了春天

2002年,Rod Jahnson首次推出了Spring框架雏形interface21框架。

2004年3月24日,Spring框架以interface21框架为基础,经过重新设计,发布了1.0正式版。

很难想象Rod Johnson的学历 , 他是悉尼大学的博士,然而他的专业不是计算机,而是音乐学。

Spring理念 : 使现有技术更加实用 . 本身就是一个大杂烩 , 整合现有的框架技术

  • 是一个轻量级的企业级应用框架
  • 企业应用开发的”一站式”选择,贯穿于表现层、业务层、持久层

  • 优点

    • 低侵入式设计
    • 独立于各种应用服务器
    • 依赖注入特性将组件关系透明化,降低耦合度
    • 面向切面编程特性允许将通用任务进行集中式处理
    • 与第三方框架的良好整合


Spring体系结构

在这里插入图片描述


Spring两大核心机制

  • IOC:工厂模式
  • AOP:代理模式



一,如何使用IOC

  • 在创建maven工程,在pom.xml中导入相关依赖
<?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">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.xinxi2</groupId>
    <artifactId>xinxi2-maven01</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <spring.version>5.2.5.RELEASE</spring.version>
    </properties>


    <dependencies>
        <!-- mysql 数据库驱动 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.29</version>
        </dependency>

        <!-- mybatis依赖 -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.6</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-tx</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>${spring.version}</version>
        </dependency>
    </dependencies>
</project>

  • 创建一个墨盒实体类
package com.xinxi2.printor;

public class Printor {

    private MoHe moHe; // 墨盒
    private Paper paper; // 纸


    // 目标对象
    public void print(){
        moHe.MoHe();
        paper.Print();
    }

    public MoHe getMoHe() {
        return moHe;
    }

    public void setMoHe(MoHe moHe) {
        this.moHe = moHe;
    }

    public Paper getPaper() {
        return paper;
    }

    public void setPaper(Paper paper) {
        this.paper = paper;
    }
}
  • 创建一个墨盒接口
package com.xinxi2.printor;

public interface MoHe {
    void MoHe();
}

  • 创建一个纸接口
package com.xinxi2.printor;

public interface Paper {
    void Print();
}

  • 创建一个类实现墨盒接口,重写墨盒方法,输出彩色墨盒
package com.xinxi2.printor;

public class ColorMoHelmpl implements MoHe{
    @Override
    public void MoHe() {
        System.out.println("彩色墨盒");
    }
}
  • 创建一个类实现墨盒接口,重写墨盒方法,输出黑色墨盒
package com.xinxi2.printor;

public class BlackMoHelmpl implements MoHe{
    @Override
    public void MoHe() {
        System.out.println("黑白墨盒");
    }
}

  • 创建一个类实现纸接口,重写纸方法,输出A4纸
package com.xinxi2.printor;

public class A4paperlmpl implements Paper{

    @Override
    public void Print() {
        System.out.println("A4纸");
    }
}

  • 在resources路径下创建applicationContext.xml配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:p="http://www.springframework.org/schema/p"
       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/aop
	http://www.springframework.org/schema/aop/spring-aop.xsd

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

    <bean id="mohe1" class="com.xinxi2.printor.BlackMoHelmpl"></bean>
    <bean id="A4paperimpl" class="com.xinxi2.printor.A4paperlmpl"></bean>
    <bean id="printor" class="com.xinxi2.printor.Printor">
        <property name="moHe" ref="mohe1"></property>
        <property name="paper" ref="A4paperimpl"></property>
    </bean>

</beans>
  • 调用API,从IOC获取对象
    @Test
    public void test02(){
    // 获取springContext上下文对象
        ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
        Printor printor = (Printor)ac.getBean("printor");
        printor.print();
    }
  • 输出结果

    在这里插入图片描述



二,AOP

  • AOP目标
  • 让我们专注于业务功能处理
  • AOP原理
  • 将复杂的需求分解出不同方面,将不同对象、不同模块之间的共同业务集中解决
  • 通过动态代理的方式,把抽离出来的共性代码”织入”到业务代码中,实现对原有代码的增强处理


    如图


    在这里插入图片描述
  • AOP相关术语
  • Aspect(切面)
  • Advice(增强处理)
  • Pointcut(切入点)
  • Join Point(连接点)
  • Target Object(目标对象)
  • AOP proxy(AOP 代理)
  • Weaving(织入)


定义切入点


切入点:简单来说,就是连接点的查询条件

    <aop:config>
        <aop:pointcut id="loggerPointcut"
                      expression="execution(public void print(..))"/>
        <aop:aspect ref="sysLogger">
            
        </aop:aspect>
    </aop:config>


表达式匹配规则举例

    expression="execution(public void print(..))"/>
  • 各种增强
增强类型 特点
Before 前置增强处理,在目标方法前织入增强处理
AfterReturning 后置增强处理,在目标方法正常执行(不出现异常)后织入增强处理
AfterThrowing 异常增强处理,在目标方法抛出异常后织入增强处理
After 最终增强处理,不论方法是否抛出异常,都会在目标方法最后织入增强处理
Around 环绕增强处理,在目标方法的前后都可以织入增强处理。可以控制目标方法是否执行


织入增强处理


织入:在切入点插入增强处理

在这里插入图片描述

  • 演示:创建实体类添加增强方法
package com.xinxi2.aspect;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

@Aspect
@Component()
public class LoggerAdvic {

    @Before("execution(public void wprk())")
    public void before(JoinPoint jp){
        System.out.println("前缀增强");
    }

    @AfterReturning("execution(public void wprk())")
    public void retuRning(JoinPoint jp){
        System.out.println("后置增强");
    }

    @AfterThrowing("execution(public void wprk())")
    public void afterException(JoinPoint jp){
        System.out.println("异常增强");
    }

    @Around("execution(public void wprk())")
    public Object around(ProceedingJoinPoint pjp){
        Object result = null;
        try {
            System.out.println("--------------------");
            result = pjp.proceed(); // 执行方法
            System.out.println("********************");
        }catch (Throwable e){
            e.printStackTrace();
        }

        System.out.println("环绕增强");
        return result;
    }

    @After("execution(public void wprk())")
    public void after(JoinPoint jp){
        System.out.println("最终增强");
    }
}
  • 在applicationContext.xml中写aop:config标签


    <aop:config>
        <aop:pointcut id="loggerPointcut"
                      expression="execution(public void print(..))"/>
        <aop:aspect ref="sysLogger">
            <aop:before method="beforeLogger" pointcut-ref="loggerPointcut"></aop:before>

            <aop:after-returning method="afterReturning" pointcut-ref="loggerPointcut" returning="obj"></aop:after-returning>

            <aop:after-throwing method="afterException" pointcut-ref="loggerPointcut" throwing="e"></aop:after-throwing>

            <aop:around method="around" pointcut-ref="loggerPointcut" ></aop:around>

            <aop:after method="after" pointcut-ref="loggerPointcut"></aop:after>
        </aop:aspect>
    </aop:config>


解释以上几种增强方法



异常抛出增强

  • 特点

    • 在目标对象方法抛出异常时织入增强处理
    • 可灵活拔插的异常处理方案
    <aop:config>
        <aop:pointcut id="loggerPointcut"
                      expression="execution(public void print(..))"/>
        <aop:aspect ref="sysLogger">

<!--      异常增强      -->
            <aop:after-throwing method="afterException" pointcut-ref="loggerPointcut" throwing="e"></aop:after-throwing>


        </aop:aspect>
    </aop:config>


最终增强

  • 特点

    • 无论方法正常运行还是抛出异常,都会在目标方法最后织入增强处理,即:该增强都会得到执行
    • 与Java中finally代码块的作用相似,通常用于释放资源
    • 可灵活拔插
    <aop:config>
        <aop:pointcut id="loggerPointcut"
                      expression="execution(public void print(..))"/>
        <aop:aspect ref="sysLogger">

<!--      最终增强      -->
            <aop:after method="after" pointcut-ref="loggerPointcut"></aop:after>
        </aop:aspect>
    </aop:config>


环绕增强

  • 特点

    • 目标方法前后都可织入增强处理
    • 可获取或修改目标方法的参数、返回值
    • 可对目标方法进行异常处理,甚至可以决定目标方法是否执行
    <aop:config>
        <aop:pointcut id="loggerPointcut"
                      expression="execution(public void print(..))"/>
        <aop:aspect ref="sysLogger">
 
        <!-- 环绕增强 -->
            <aop:around method="around" pointcut-ref="loggerPointcut" ></aop:around>

        </aop:aspect>
    </aop:config>


构造注入

  • 可以使用带参构造

    • Spring通过构造方法为属性赋值的一种注入方式
    • 可以在对象初始化时对属性赋值,具有良好的时效性
    <bean id="daodao" class="com.xinxi2.bean.TSysUser">
        <constructor-arg name="acccunt" value="王某某"></constructor-arg>
        <constructor-arg name="address" value="王某"></constructor-arg>
    </bean>


P命名的注入


使用属性而不是子元素的形式配置Bean的属性

<bean id="唯一标识" class="类的全路径"
	p:"属性1"="注入的值" p:"属性2"="注入的值"  />
<bean id="唯一标识" class="类的全路径"
	p:属性-ref="注入的Bean" />

配置文件中使用p命名空间时,需要先添加p命名空间的声明

xmlns:p=“http://www.springframework.org/schema/p”



三,Spring表单标签



3.1,Spring常用表单标签
名称 说明
fm:form/ 渲染表单元素
fm:input/ 输入框组件标签
fm:password/ 密码框组件标签
fm:hidden/ 隐藏框组件标签
fm:textarea/ 多行输入框组件标签
fm:radiobutton/ 单选框组件标签
fm:checkbox/ 复选框组件标签
fm:select/ 下拉列表组件标签
fm:error/ 显示表单数据校验对应的错误信息


fm:form标签

  1. modelAttribute

    指定绑定的模型属性

    若不指定该属性,默认从模型中尝试获取名为”command”的表单属性,建议指定该属性
  2. action

    指定表单提交的目标URL

    可不指定,则自动以获取表单页面的URL为目标进行提交,可以通过不同请求方式区分不同操作
  3. method

    GET

    POST


3.2,标签属性
属性 描述
path 属性路径,表示表单对象属性,如account、realName等
cssClass 表单组件对应的CSS样式类名
cssErrorClass 当提交表单后报错(服务端错误),采用的CSS样式类
cssStyle 表单组件对应的CSS样式
htmlEscape 绑定的表单属性值是否要对HTML特殊字符进行转换,默认为true


3.3,数据校验


JSR 303 约束

约束 说明
@Null 被注释的元素必须为null
@NotNull 被注释的元素必须不为null
@AssertTrue 被注释的元素必须为true
@AssertFalse 被注释的元素必须为false
@Min(value) 被注释的元素必须是一个数字,其值必须大于等于指定的最小值
@Max(value) 被注释的元素必须是一个数字,其值必须小于等于指定的最大值
@DecimalMin(value) 被注释的元素必须是一个数字,其值必须大于等于指定的最小值
@DecimalMax(value) 被注释的元素必须是一个数字,其值必须小于等于指定的最大值
@Size(max,min) 被注释的元素的大小必须在指定的范围内
@Digits(integer,fraction) 被注释的元素必须是一个数字,其值必须在可接受的范围内
@Past 被注释的元素必须是一个过去的日期
@Future 被注释的元素必须是一个将来的日期
@Pattern(value) 被注释的元素必须符合指定的正则表达式