一、基于xml的Spring

文章目录

一、Spring概念

1、概述

为了简化企业应用程序的开发而创建。
有以下优势:

  1. 分层架构(MVC模式分层架构)
  2. 为JavaEE程序开发集成各种框架(比如MyBatis)
  3. 遵守软件设计的五大原则
  4. 非侵入式框架(Servlet是侵入式组件):我们编写的业务不用继承或实现spring的任何组件;方便将当前业务剥离spring,移植到其他容器。

2、软件设计的五大规则

  1. 开闭原则:对源代码的修改关闭,对系统的升级维护开放
  2. 李斯特替代原则
  3. 依赖倒置原则:高层模块(业务)不依赖于底层模块(具体实现细节),都依赖于抽象。面向接口编程是这个原则的具体实现方式,在业务中,依赖的是接口,而不是具体实现,在运行时由容器注入具体依赖的实现,有利于降低耦合度。
  4. 组合组装原则
  5. 迪米特原则:组件独立,降低类之间的耦合性

3、Spring的组件构成

  1. Spring Core
    创建组件的容器,Spring核心,最基础的部分,包括Spring运行期间需要的工具类库。提供IoC特性和DI依赖注入特性。
  2. Spring AOP
    保证系统正常运行,记录系统运行时的状态,保证系统的事务和异常处理功能的组件。
  3. Spring ORM
    对象映射组件(实体化组件),用于不同系统的数据之间转换,支持流行的ORM框架整合,比如MyBatis等组件
  4. Spring Web
    提供对web工具的支持,包括:HttpSession、HttpServletRequest、HttpServletResponse、HttpServletContext
  5. Spring MVC
    把所有的用户请求转发给不同的控制器组件去处理,DispatcherServlet是SpringMVC的核心组件。替代Servlet,开发人员去关注业务处理,而不是数据传输。
  6. Spring DAO
    Spring数据持久化组件,用于Spring的JPA框架支持,springdata框架使用这个组件实现数据持久化。
  7. Spring Context
    Spring上下文容器,用于处理调用者和spring容器之间的会话。
    ApplicationContext是SpringContext的核心组件。
    用于加载applicationContext.xml文件(注入的类或者调用者依赖的组件类都要在这个文件中配置)

二、Spring核心——IoC

先导入spring依赖

<dependency>
	<groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>5.3.23</version>
</dependency>

1、控制反转定义

对象创建的控制权由代码转换到外部容器,这种思想称为控制反转。
传统的编程以硬编码的方式直接在代码中创建对象,替换对象时就得修改调用方,耦合度高;控制反转的方式是在运行时,容器会根据配置信息,自动创建并注入依赖关系。

2、依赖注入DI

2.1 定义

外部容器为应用程序提供依赖项,而不是对象自己创建所需的依赖,从而达到解耦,依赖注入是Spring控制反转思想的具体实现。
无参注入对象是提供应用程序运行所需的依赖,为对象赋值是提供对象调用所需的依赖,都是依赖注入

2.2 依赖注入的方式

2.2.1 构造器注入
  1. 无参构造注入:容器创建对象的时候不传参,就是无参构造器注入;注入了对象
  2. 带参构造注入:容器创建对象的时候传参就是使用带参构造器注入;即给容器中注入了对象,又为对象注入了属性
    index表示带参构造参数的索引
    为第一个属性品牌赋值:<constructor-arg index="0" value="罗技"/>
    为第二个属性颜色赋值:<constructor-arg index="1" value="紫色"/>
2.2.2 setter注入

是给对象注入属性
容器无参创建对象,创建完之后调用set方法为属性赋值
<property name="属性" value="属性值"/>

2.2.2.1注入集合
<bean id="usbService" class="com.service.impl.UsbMouseService">
        <property name="devName" value="罗技鼠标"/>
        <property name="pingJiaList">
            <list>
                <value>非常棒,手感很好</value>
                <value>鼠标质量很好</value>
                <value>鼠标很丝滑</value>
            </list>
        </property>
        <property name="liShiPriceSet">
            <set>
                <value>199</value>
                <value>129</value>
                <value>99</value>
            </set>
        </property>
        <property name="lingMinMap">
            <map>
                <entry key="600" value=""/>
                <entry key="800" value=""/>
                <entry key="1000" value=""/>
            </map>
        </property>
    </bean>
2.2.3 FactoryBean工厂注入
  1. 写一个工厂类,实现FactoryBean<>接口
  2. 重写接口方法
public class BookServiceFactory implements FactoryBean<BookService> {
    @Override
    public BookService getObject() throws Exception {
        return new BookServiceImp();//返回你要的对象
    }

    @Override
    public Class<?> getObjectType() {
        return BookService.class;//返回接口的字节码文件
    }

    @Override
    public boolean isSingleton() {
        return true;//true是单例,false是非单例
    }
}
  1. 将工厂对象注入容器
    <bean id="bookServiceFactory" class="com.jz.fanctory.BookServiceFactory"/>
  2. 使用的时候获取工厂对象
    BookService bookService = (BookService) ctx.getBean("bookServiceFactory");
2.2.4 接口注入

非常不常用。需要依赖的类实现指定接口,重写方法,做赋值操作就是接口注入

3、配置Bean

3.1 常用属性

  1. scope:不设置scope属性,默认单例,即创建的是同一个对象。单例:singleton;非单例:prototype
  2. init-method:bean初始化执行的方法
  3. destroy-method:bean销毁时(容器正常关闭)执行的方法
    <bean id="bookService" class="com.jz.service.imp.BookServiceImp" scope="singleton" init-method="init" destroy-method="destory" />

3.2 控制bean的生命周期的第二种方式

spring容器提供了两个接口:InitializingBean、DisposableBean
指定的Bean实现这两个接口,重写两个方法就是初始化和销毁执行的方法。

3.3 正常关闭容器

一般情况下,Bean销毁之前的方法不会被调用执行的。因为spring容器不负责主动执行销毁方法,只有容器正常关闭时才会执行。

3.3.1 注册关闭钩子

可以放在任何位置

3.3.2 close直接关闭容器

只能放在最后

3.3.3 演示

两个方法都在ClassPathXmlApplicationContext类中

public static void main(String[] args) {
        ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
        ctx.registerShutdownHook();//注册关闭钩子,可以放在任何位置
        BookService bookService = (BookService) ctx.getBean("bookService");
        bookService.save();
        //ctx.close();直接关闭容器,只能放在最后
}

4、Spring的装配模式

spring容器为属性赋值的方式,装配是依赖注入的具体实现。

4.1 xml配置

可以在xml的<bean/>中配置属性autowire的值,默认为no、byType、byName、constructor

  1. 按类型装配
  2. 按名称装配
  3. 构造器装配

4.2 注解配置

  1. @Resource:@Resource(name=“类名”, type=类.class)更加精准,是jdk提供的,jdk11后就没有了,再由jacket提供
  2. @Autowired:默认按类型装配;无此类型时,或者依赖的接口不止一个实现类,容器就不知道装配哪个就报错
  3. @Autowired和@Qualifier("name"):如果容器中接口有多个类型,容器不知道装配哪个,就用第二个注解配合指定名称,联合装配

5、注入第三方Bean

比如我们要注入数据库连接池Druid对象

5.1 导入依赖

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>6.1.10</version>
</dependency>
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid</artifactId>
    <version>1.2.8</version>
</dependency>
<dependency>
    <groupId>com.mysql</groupId>
    <artifactId>mysql-connector-j</artifactId>
    <version>8.0.32</version>
</dependency>

5.2 编写jdbc.properties配置文件

jdbc.开头,避免和系统环境变量名冲突

jdbc.driverClassName=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/bankdb
jdbc.username=root
jdbc.password=123456

5.3 在xml中开启命名空间,加载properties文件

5.4 注入依赖

在xml中注入DruidDataSource对象,
并通过${}占位符为其属性注入文件中的值

<?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
       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:property-placeholder location="jdbc.properties"/>

    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="driverClassName" value="${jdbc.driverClassName}"/>
        <property name="url" value="${jdbc.url}"/>
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
    </bean>
</beans>

6、使用注解与配置文件实现注入

不需要在配置文件中注入bean类。只用在配置文件的头文件引入命名空间和注解扫描器

6.1 配置文件的头部引入命名空间和注解扫描器

6.1.1 引入代码:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx"
       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
            
            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
            
            http://www.springframework.org/schema/tx 
            http://www.springframework.org/schema/tx/spring-tx.xsd
        ">
<!-- 注入注解的支持描述 -->
    <context:annotation-config></context:annotation-config>
<!-- 注入注解扫描器 -->
    <context:component-scan base-package="com.dao"/>
    <context:component-scan base-package="com.service"/>
</beans>
6.1.2 可能报错:

引入事务命名空间报错
解决
引入事务命名空间解决报错

6.2 注入Bean的注解

都用于描述bean的注入方式,替代<bean id="" class=""/>
@Component:声明bean的基础注解,若有类不属于mvc三层时;比如工具类就用此注解
@Controller:标注在控制器类上
@Service:标注在业务类上
@Repository:标注在数据访问类上,由于MyBatis整合了,用的少
@Bean:表示当前方法的返回值是一个Bean
@Configuration:配置类


三、Spring核心——Aop

1、定义

面向切面编程:横向操作,在不惊动原始设计的情况下为其增加功能

2、作用

对业务逻辑各部分进行隔离,使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性、维护性,同时提高了开发的效率。

3、应用场景

在开发中将公共的事务、日志、安全、异常处理等组件独立出来,作为公共模块作用于系统的所有业务组件,不纠缠在业务代码中,开发者就不关心这些了。

4、AOP的底层实现——动态代理

通过代理对象和拦截器去实现的,这些代理对象可以拦截和增强目标对象的方法调用。

5、使用步骤

5.1 编写拦截器,并注入spring容器。这也是通知类

<bean id="serviceInterceptor" class="com.interceptor.ServiceMethodInterceptor"/>
实现了MethodInterceptor接口的类就是拦截器,重写invoke方法。在里面可以控制访问原方法
Object obj = invocation.proceed();就是放行对原方法的访问,有返回值的话要将返回值返回出去。
通知类

5.2 注入代理工厂,并绑定拦截器

Spring容器处理Aop的核心组件——ProxyFactoryBean:负责创建接口的代理对象,而不是普通对象,只有代理对象访问才会被拦截,增强效果。
有JDK动态代理工厂和CGLIB动态代理工厂
proxyTargetClass:指定true使用cglib代理,false或不写这个属性都是jdk
proxyInterfaces:指定要代理的接口,只有jdk需要写
target:指定代理的具体类
interceptorNames:指定拦截器

<!--  注入代理bean工厂,代理业务接口类  -->
    <bean id="serviceProxy" class="org.springframework.aop.framework.ProxyFactoryBean">
    	<!-- 指定使用cglib代理,值为false或不写这行默认就是jdk代理 -->
        <property name="proxyTargetClass" value="false"/>
        <!-- 描述将要代理的接口(jdk代理才需要写) -->
        <property name="proxyInterfaces" value="com.service.EmpService"/>
        <!-- 指定接口的实现目标类 -->
        <property name="target" ref="empService"/>
        <!-- 指定拦截器 -->
        <property name="interceptorNames" value="serviceInterceptor"/>
    </bean>
5.2.3 二者区别
  1. jdk只能代理实现了接口的类,cglib可以代理单独的类
  2. jdk指定代理的类,cglib接口的全部类都代理
  3. jdk通过反射机制实现,cglib直接在使用cglib库生成生成字节码,性能比jdk好得多
  4. jdk用于接口较多的场景,如果有单独类的话只能用cglib

6、相关名词

  1. 连接点:程序执行过程中能够插入切面的一个点,这个点可以是任何位置(调用方法,抛出异常,修改打印等等)
  2. 切入点:匹配通知要植入的连接点的式子
  3. 通知:切入点要执行的操作,也就是共性的功能
  4. 通知类:包含通知方法的类
  5. 切面:描述通知与切入点的对应关系

四、Spring的事务处理

1、事务处理的方式

1.1 编程式事务

使用TransactionTemplate对象调用方法,显式管理事务,比如,需要显示调用commit或者rollback方法

1.2 声明式事务

建立在aop基础上的,通过aop对注解的方法拦截,在方法执行前开启事务,方法执行完后根据情况提交或回滚事务。通过配置文件和注解实现自动开启提交回滚。

1.2.1 优缺点

优点:不需要在业务代码中掺杂事务管理,减少代码污染
缺点:只能做到方法级别,不能做到像编程式事务那样的代码块级别

2、事务管理器的分类

PlatformTransactionManager是所有事务管理器的父类

  1. JDBC的事务管理器:DataSourceTrancationManager,MyBatis使用这个
  2. Hibernate的事务管理器:HibernateTrancationManager
  3. JPA的事务管理器:JtaTrancationManager,SpringData使用这个

3、声明式事务管理器使用步骤

  1. 在配置文件中配置数据源,链接数据库
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/bankdb?useSSL=false"/>
        <property name="username" value="root"/>
        <property name="password" value="123456"/>
</bean>
  1. 注入事务管理器,并指定事务管理器用于哪个数据源
<!-- 注入事务管理器,指定用于哪个数据源 -->
<bean id="txtransaction" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
</bean>
  1. 启用基于注解的事务管理功能,指定要使用的事务管理器
    这个标签内部还配置了aop功能用于拦截配置了@Transactional的方法
<!-- 启用基于注解的事务管理功能,属性指定用哪个事务管理器,隐式配置了aop功能 -->
<tx:annotation-driven transaction-manager="txtransaction"/>
  1. 在要使用事务的类或方法前加注解@Transactional

五、SpringMVC

1、概念

MVC是一种设计模式,将应用程序分为模型、视图、控制器三个独立的组件。
SpringMVC是基于Servlet实现了MVC模式的轻量级的Web框架,是Spring的子框架,替换servlet做控制层开发。

2、作用

  1. 用于替代Servlet构建控制器层:接收请求参数,产生响应结果。
  2. 减少开发者对数据传输细节的处理,省去了request.getParameter(…)
  3. 非侵入组件技术,方便代码的移植和维护升级

3、SpringMVC的构成

  1. DispatcherServlet
    是SpringMVC的核心组件,它实现了Servlet接口
  2. 配置文件
    dispatcher-servlet.xml
  3. 拦截器组件
    Bean的注入拦截器
    参数拦截器
    文件上传拦截器
    安全验证和类型转换拦截器
    请求链接的拦截器:哪些请求归mvc处理

4、使用步骤

4.1 引入依赖:spring-webmvc、javax.servlet.api,创建目录结构包

4.2 编写两个配置文件,修改web.xml

  1. 编写applicationContext.xml文件,注入注解扫描器,扫描除过控制器之外的包
  2. 编写SpringMVC的配置文件dispatcher-servlet.xml,扫描控制器类所在的包
  3. 修改web.xml文件,注入spring和springmvc容器的启动

4.3 编写业务类,控制器类,并注入spring容器

4.4 构建前端界面,前后端交互

5、SpringMVC的执行流程

  • 24
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值