• Spring 知识点


    Spring

    官网:https://spring.io/

    官网下载地址:https://repo.spring.io/release/org/springframework/spring/

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

    1.1 简介

    • 2002 年 首次推出Spring框架雏形:interface21.io
    • Spring 框架以 interface21.io 为基础,于 2004 年 3 月 24 号 发布 1.0 版本
    • Spring Framework 创建人:Rod Johnson 悉尼大学 音乐出身
    • Spring 理念:使现有的技术更加容易使用
    • Spring 是为了解决企业级应用开发的复杂性而创建的,简化开发。

    SSH

    • Struct2 + Spring + Hibernate

    SSM

    • SpringMVC + Spring + Mybatis

    Maven Jar

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>5.2.7.RELEASE</version>
    </dependency>
    

    1.2 概念

    • Spring 是一个开源的免费的框架
    • Spring 是一个轻量级的,非入侵式的框架
    • 特性:控制反转(IOC)、面向切面编程(AOP)
    • 支持事务处理,对框架整合的支持

    总结:Spring 是一个轻量级的 控制反转和面向切面编程的框架

    1.3 组成

    Spring 框架指的是 Spring Farmework,它是很多模块的组合,使用这些模块可以很方便协助开发。这些模块是:

    核心容器、数据访问、Web、AOP、工具、消息、测试模块。

    Core Container 中的 Core 组件是 Spring 所有组件的核心;Beans 组件和 Context 组件是实现 IOC 和 依赖注入的基础;AOP组件用于实现面向切面编程。

    六个特性:

    • 核心技术:依赖注入(DI), AOP, 事件, 资源, i18n, 验证, 数据绑定, 类型转换, SpEL
    • 测试:
    • 数据访问:事务, DAO支持, JDBC, ORM, 编组XML
    • Web支持:Spring MVC, Spring WebFlux Web 框架
    • 集成:远程处理
    • 语言:Kotlin, Groovy, 动态语言

    1

    • Spring Core:基础,可以说Spring 其他所有的功能都需要依赖于该类库。主要提供 IoC 依赖注入功能。
    • Spring Aspects:该模块为与 AspectJ 集成提供支持
    • Spring AOP:面向切面编程
    • Spring JDBC:Java 数据库连接
    • Spring JMS:Java 消息服务
    • Spring ORM:用于支持 Hibernate 等 ORM 工具
    • Spring Web:为创建 Web 应用程序提供支持

    1.4 拓展

    • Spring Framkwork
    • Spring Boot
      • 快速开发的脚手架
      • 基于SpringBoot 可以快速的开发单个微服务
      • 约定大于配置
    • Spring Cloud
      • SpringCloud是基于 SpringBoot 实现的

    2.IOC 理论

    2.1 IOC 本质

    IOC: 对象由Spring来创建、管理、装配!

    IOC 是一种编程思想,由主动的编程变成被动的接收

    1.对象由谁创建?

    • 对象由Spring 创建

    2.对象的属性由谁设置?

    • 对象的属性由Spring容器设置

    这个过程就叫控制反转:

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

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

    依赖注入:利用Set方法来进行注入

    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
            https://www.springframework.org/schema/beans/spring-beans.xsd">
    
    </beans>
    

    样例:

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://www.springframework.org/schema/beans
            https://www.springframework.org/schema/beans/spring-beans.xsd">
    
        <bean id = "useDaoImpl" class="dao.UserDaoImpl" />
        <bean id = "useMysqlDaoImpl" class="dao.UserMysqlDaoImpl" />
    
        <!-- ref 引用Spring容器创建好的对象,value 具体的值 -->
        <bean id="useServiceImpl" class="service.UserServiceImpl">
            <property name="userDao" ref = "useMysqlDaoImpl" />
        </bean>
    </beans>
    

    使用样例:

    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    import pojo.User;
    import service.UserServiceImpl;
    
    public class BeanTest {
    
        public static void main(String[] args) {
            ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
    
            UserServiceImpl userService = (UserServiceImpl) context.getBean("useServiceImpl");
            userService.getUserById();
    
            User user = (User) context.getBean("user");
            System.out.println(user.getId());
        }
    
    }
    

    2.2 IOC 创建对象的方式

    1.使用无参构造创建对象。默认

    2.有参构造创建对象

    1. 下标赋值

      <bean id="exampleBean" class="examples.ExampleBean">
          <constructor-arg index="0" value="7500000"/>
          <constructor-arg index="1" value="42"/>
      </bean>
      
    2. 类型赋值(不建议使用)

      <bean id="exampleBean" class="examples.ExampleBean">
          <constructor-arg type="int" value="7500000"/>
          <constructor-arg type="java.lang.String" value="42"/>
      </bean>
      
    3. 参数名

      <bean id="exampleBean" class="examples.ExampleBean">
          <constructor-arg name="name" value="Vincent"/>
      </bean>
      

    总结:在配置文件加载的时候,容器中的对象就已经初始化了!

    3.Spring 配置

    3.1别名

    <!-- alias 别名,可以使用别名获取对象 -->
    <alias name="user" alias="usershow" />
    

    3.2 bean 的配置

    <bean id="user" class="pojo.User">
        <property name="id" value="1" />
    </bean>
    
    • id:bean 的唯一标识符,也就是对象名
    • class:bean 对象 对应的权限定名(包名+类名)
    • name:别名

    3.3 import

    import 一般用于团队开发,可以将多个配置文件导入合并为一个。

    <import resource="classpath:****.xml" />
    

    4.依赖注入 DI

    4.1 构造器注入

    转:2.2

    4.2 Set 方式注入(重点)

    依赖注入本质是 Set 注入

    • 依赖:Bean 对象的创建依赖于容器
    • 注入:Bean 对象中的所有属性由容器注入

    Set 注入样例

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://www.springframework.org/schema/beans
            https://www.springframework.org/schema/beans/spring-beans.xsd">
    
        <bean id="user" class="pojo.User">
            <property name="id" value="1" />
        </bean>
    
        <bean id="stu" class="pojo.Student">
            <!-- 普通属性注入 -->
            <property name="name" value="Vincent" />
    
            <!-- 对象注入 ref  -->
            <property name="user" ref="user" />
    
            <!-- 数组 -->
            <property name="books">
                <array>
                    <value>遮天</value>
                    <value>完美世界</value>
                    <value>神墓</value>
                </array>
            </property>
    
            <!-- List -->
            <property name="hobbys">
                <list>
                    <value>BALL</value>
                    <value>GAMES</value>
                </list>
            </property>
    
            <!-- Map -->
            <property name="card">
                <map>
                    <entry key="cardno" value="1231412214"/>
                </map>
            </property>
    
            <!-- Set -->
            <property name="games">
                <set>
                    <value>lol</value>
                    <value>cf</value>
                </set>
            </property>
    
            <!-- 空值注入 / null 注入 -->
    
            <property name="wife">
                <null/>
            </property>
    
            <!-- Properties -->
            <property name="info">
                <props>
                    <prop key="1">1111</prop>
                    <prop key="2">2222</prop>
                </props>
            </property>
        </bean>
    
    </beans>
    

    4.3 拓展方式注入

    p 命名空间 和 c 命名空间

    • 不可直接使用,需要导入 xml 配置

    p 命名配置:

    xmlns:p="http://www.springframework.org/schema/p"
    
    # 使用
    <bean name="p-namespace" class="com.example.ExampleBean"
            p:email="someone@somewhere.com"/>
    
    

    c 命名配置:

    xmlns:c="http://www.springframework.org/schema/c"
    
    <bean id="beanOne" class="x.y.ThingOne" 
          c:thingTwo-ref="beanTwo"
          c:thingThree-ref="beanThree" 
          c:email="something@somewhere.com"/>
    

    4.4 Bean 的作用域

    image-20200620152556816

    • singleton: 唯一 bean 实例,Spring 中的 bean 默认都是 单例的。
    • prototype: 每次请求都会创建一个新的 bean 实例
    • request: 每一次Http请求都会产生一个新的bean, 该bean 仅在当前 Http request 有效
    • session: 每一次Http请求都会产生一个新的bean, 该bean 仅在当前 Http session 有效
    • global-session: 全局session作用域,仅仅在基于portlet的web应用中才有意义,Spring5已经没有了。

    5.Bean 的自动装配

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

    Spring 中三种装配方式

    • 在 xml 中显示装配
    • 在 java 代码中装配
    • 隐式的装配

    5.1 ByName 自动装配

    • 会自动在Spring容器上下文中,查询与set属性相对于的 bean id
    <bean name="p-namespace" class="com.example.ExampleBean" autowire="buName"/>
    

    5.2 ByType 自动装配

    • 会自动在Spring容器上下文中,查找与对象类型相对于的bean
    <bean name="p-namespace" class="com.example.ExampleBean"autowire="buType"/>
    

    小结:

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

    5.3 使用注解自动装配

    使用注解配置

    • 导入约束:context
    • 添加配置
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:context="http://www.springframework.org/schema/context"
        xsi:schemaLocation="http://www.springframework.org/schema/beans
            https://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/context
            https://www.springframework.org/schema/context/spring-context.xsd">
    
        <!-- 开启自动注入配置 -->
        <context:annotation-config/>
    
    </beans>
    

    @Autowired

    • 在属性上使用即可, 也可以在SET上使用
    • 可不用编写 SET 方法,

    @Resource

    小结:

    @Autowired@Resource 区别

    • 都是用来自动装配,都可以放在属性字段上
    • @Autowired 默认通过 byType 的方式实现,对象必须存在
    • @Resource 默认通过 byName 的方式实现,如果找不到 name, 则自动通过 byType 方式找,都找不到就报错
    • 执行顺序不同:

    6. 使用注解开发

    @Autowired

    @Resource

    @Component : 组件,说明bean 被Spring容器管理了

    @Value : 属性注入

    @Repository: dao

    @Service:service

    @Controller:controller

    @Scope:作用域

    小结:

    @Component 、@Repository、@Service、@Controller、将类注册到Spring容器中,装配Bean

    配置需要扫描的包:

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

    7. Java 配置Spring

    7.1 JavaConfig

    @Configuration 代表这是一个配置类,相当于beans.xml,它本身是一个 @Component 组件

    @ComponentScan 自动扫描包

    @Import 导入类

    @Bean

    8.代理模式

    为什么学习代理模式?

    • Spring AOP 的底层

    代理模式分类

    • 静态代理
    • 动态代理

    8.1 静态代理

    角色分析:

    • 抽象角色:一般使用接口或者抽象类解决
    • 真实角色:被代理的角色
    • 代理角色:代理真是角色,代理真实角色后,
    • 客户:访问代理角色的人

    代理模式实现步骤:

    • 接口

      public interface Rent {
      
          public void rent();
      
      }
      
    • 真实角色

      public class Host implements Rent{
      
          @Override
          public void rent() {
              System.out.println("我要出租房子");
          }
      }
      
    • 代理角色

      public class Proxy {
      
          private Host host;
      
          public Proxy() {
          }
      
          public Proxy(Host host) {
              this.host = host;
          }
      
          public void rent(){
              host.rent();
          }
      
          public void seeHouse(){
              System.out.println("看房子");
          }
      }
      
    • 客户端访问代理角色

      public class Client {
      
          public static void main(String[] args) {
              Host host = new Host();
      
              Proxy proxy = new Proxy(host);
      
              proxy.rent();
          }
      }
      

    代理模式的好处

    • 可以使真实角色的操作更加纯粹,不用关注一些公共的业务
    • 公共也就交给代理角色,实现业务的分工
    • 公共业务发生拓展的时候,方便集中管理

    缺点:

    • 一个真实角色就会产生一个代理角色,代码量会翻倍,开发效率变低

    8.2 动态代理

    • 动态代理和静态代理角色一样
    • 动态代理的代理类是动态生成的,非直接写的
    • 动态代理分为两大类:基于接口的动态代理、基于类的动态代理
      • 基于接口:JDK 动态代理
      • 基于类:cglib
      • java字节码:javasist

    Proxy & InvocationHandler

    proxy 生成动态代理实例

    InvocationHandler 调用处理程序并返回结果

    InvocationHandler

    image-20200621111410915

    动态代理的好处:

    • 静态代理的他都有
    • 一个动态代理类代理是一个接口,一般就是对应一个业务
    • 一个动态代理可以代理多个类,只要是实现了一个接口

    9.AOP

    9.1 什么是AOP

    AOP (Aspect Oriented Programming) : 面向切面编程

    通过预编译方式和运行期动态代理实现程序功能统一维护的技术。AOP是 OOP 的延续,是Spring 框架中的一个重要内容,是函数式编程 的一种衍生范型。

    利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,并提供开发效率。

    image-20200621152746897

    9.2 AOP在Spring中的作用

    提供声明式事务,允许用户自定义切面

    image-20200621152839514

    image-20200621152941351

    9.3Spring 实现AOP

    导入 Maven 包

    <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjweaver</artifactId>
        <version>1.9.5</version>
    </dependency>
    

    方式一:Spring API 接口

        <aop:config>
    ​        <!-- 切入点 expression:表达式 -->
    ​        <aop:pointcut id="pointcut" expression="execution(* pers.vincent.service.UserServiceImp.*(..))"/>
    
    ​        <aop:advisor advice-ref="log" pointcut-ref="pointcut" />
    ​        <aop:advisor advice-ref="afterlog" pointcut-ref="pointcut" />
    ​    </aop:config>
    

    方式二:自定义类实现

    10.整合Mybatis

    步骤:

    1. 导入JAR包
      • junit
      • mybatis
      • mysql 数据库连接
      • spring 相关的
      • aop
      • spring-mybatis
    2. 编写配置文件
    3. 测试

    spring-database.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
            https://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/aop
            https://www.springframework.org/schema/aop/spring-aop.xsd">
    
        <!-- DataSoure: 使用Spring 的数据源替换 Mybatis 的配置 -->
        <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/smbms?useUnicode=true&amp;characterEncoding=UTF8"/>
            <property name="username" value="root" />
            <property name="password" value="root" />
        </bean>
    
        <!-- sqlsessionFactory -->
        <bean id="sqlsessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
            <property name="dataSource" ref="dataSource" />
            <property name="configuration" value="classpath:mybatis-config.xml"/>
            <property name="mapperLocations" value="classpath:pers/vincent/mapper/*.xml" />
        </bean>
    
        <!-- SqlSessionTemplate 就是 SqlSession -->
        <bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
            <!-- 只能使用构造器注入sqlsessionFactory, 因为它没有set方法 -->
            <constructor-arg index="0" ref="sqlsessionFactory" />
        </bean>
    
    
    </beans>
    
    • 编写数据源
    • sqlSessionFactory
    • sqlSessionTemplate
    • 需要添加实现类

    11.事务

    11.1 事务的 ACID 原则

    • 原子性:事务是最小执行单位
    • 持久性:事务一旦提交,无论系统发生什么,结果都不会被影响,被持久化到存储器中
    • 一致性
    • 隔离性:多个业务可能操作一个资源,防止数据损坏

    11.2 Spring 中的事务管理

    • 声明式事务:AOP (推荐事务)
      • 在配置文件中配置
        1. 基于XML的声明式事务
        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"
           xmlns:tx="http://www.springframework.org/schema/tx"
           xsi:schemaLocation="http://www.springframework.org/schema/beans
            https://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/context
            https://www.springframework.org/schema/context/spring-context.xsd
            http://www.springframework.org/schema/aop
            https://www.springframework.org/schema/aop/spring-aop.xsd
            http://www.springframework.org/schema/tx
            https://www.springframework.org/schema/tx/spring-tx.xsd">
    
        <!-- DataSoure: 使用Spring 的数据源替换 Mybatis 的配置 -->
        <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/smbms?useUnicode=true&amp;characterEncoding=UTF8"/>
            <property name="username" value="root" />
            <property name="password" value="root" />
        </bean>
    
        <!-- sqlsessionFactory -->
        <bean id="sqlsessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
            <property name="dataSource" ref="dataSource" />
            <property name="configuration" value="classpath:mybatis-config.xml"/>
            <property name="mapperLocations" value="classpath:pers/vincent/mapper/*.xml" />
        </bean>
    
        <!-- SqlSessionTemplate 就是 SqlSession -->
        <bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
            <!-- 只能使用构造器注入sqlsessionFactory, 因为它没有set方法 -->
            <constructor-arg index="0" ref="sqlsessionFactory" />
        </bean>
    
        <!-- 配置声明式事务 -->
        <bean id="transactionManager" class="org.springframework.jdbc.datasource.">
                                             
        </bean>
    
        <!-- 结合 AOP 实现事务的织入 -->
        <!-- 配置事务的通知 -->
        <tx:advice id="txAdvice" transaction-manager="transactionManager">
            <!-- 给哪些方法配置事务 -->
            <!-- 配置事务的传播特性: propagation-->
            <tx:attributes>
                <tx:method name="*" propagation="REQUIRED"/>
            </tx:attributes>
        </tx:advice>
    
        <!-- 配置事务切入 -->
        <aop:config>
            <aop:pointcut id="pointcut" expression="execution(* pers.vincent.mapper.*.*(..))"/>
            <aop:advisor advice-ref="txAdvice" pointcut-ref="pointcut"/>
        </aop:config>
    
    </beans>
    
    • 编程式事务:(不推荐使用)

      • 在代码里硬编码

    为什么需要事务?

    • 如果不配置事务,可能存在数据提交不一致的情况
    • 事务在开发过程中十分重要,涉及到数据的一致性和完整性

    11.3 Spring 事务中的隔离级别

    TransactionDefinition 接口定义了五个表示隔离级别的常量

    • TransactionDefinition.ISOLATION_DEFAULT: 使用后端数据库默认的隔离级别。

      MySQL 默认采用的REPEATABLE_READ;Oracle 默认采用 READ_COMMITTED

    • TransactionDefinition.ISOLATION_READ_UNCOMMITTED: 最低的隔离级别,允许读取尚未提交的数据变更,可能会导致脏读、幻读或不可重复读

    • TransactionDefinition.ISOLATION_READ_COMMITTED: 允许读取并发事务已经提交的数据,可以阻止脏读,但是幻读或不可重复读仍可能发生

    • TransactionDefinition.ISOLATION_REPEATABLE_READ: 对同一个字段的多次读取结果都是一致的,除非数据是被本身事务自己所修改,可以组织脏读和不可重复读,但幻读仍有可能发生。

    • TransactionDefinition.ISOLATION_SERIALIZABLE: 最高的隔离级别,完全服从ACID的隔离级别。所有的事务依次逐个执行,这样事务之间就完全不可能产生干扰,也就是说,该级别可以防止脏读,不可重复读以及幻读。但是这将严重影响程序的性能。通常情况下也不会用到该级别。

    12. 相关问题

    @RestController 和 @Controller

    @RestController

    • 相当于:@Controller + @ResponseBody

    • RESTful Web 服务

    • 返回 JSON 和 XML 形式数据:对象数据直接以 JSON 和 XML 形式写入 HTTP 响应(Response)

    • 对应 前后端分离

    @Controller

    • 单独使用不加 @ResponseBody 的话,一般使用再要返回一个视图的情况,传统的 SpringMVC 应用,前后端不分离

    Spring IOC 和 Spring AOP

    Spring IOC

    • 控制反转:是一种思想,将原本在程序中手动创建对象的控制权交由 Spring 管理。
    • IoC 容器是 Spring 用来实现 IoC 的载体,IoC 容器实际上就是 Map, Map 中存放的是各种对象。
    • 将对象之间的相互依赖关系交给 IoC 容器来管理,并由 IoC 容器完成对象的注入。
    • 初始化过程:
      • 配置XML文件
      • 读取Resource
      • 解析 BeanDefinition
      • 注册 BeanFactory

    Spring AOP

    • 面向切面编程:将业务模块需要共同调用的逻辑或责任(例如事务管理、日志管理、权限控制等)封装起来,便于减少系统的代码重复,降低模块间的耦合度,并有利于未来的可拓展性和可维护性
    • 基于动态代理

    Spring AOP 和 AspectJ AOP

    • Spring AOP 是基于动态代理,属于运行时增强
      • 以集成 AspectJ, AspectJ 算的上是 Java 生态系统中最完整的 AOP 框架
    • AspectJ AOP 是基于字节码操作,属于编译时增强

    Spring Bean

    1.Spring 中的单例 bean 的线程安全问题了解吗?

    主要是因为当多个线程操作同一个对象的时候,对这个对象的非静态成员变量的写操作会存在线程安全问题。

    解决方法:

    在类中定义一个 ThreadLocal 成员变量,将需要的可变成员变量保存在 ThreadLocal 中

    @Component 和 @Bean 的区别是什么?

    • 作用对象不同:@Component 注解作用于类,而@Bean注解作用于方法
    • @Component 通常是通过类路径扫描来自动侦测以及自动装配到Spring容器中;@Bean 注解通常是我们在标有该注解的方法中定义产生这个 bean, @Bean 告诉了Spring这是某个类的示例,当我们需要用他的时候还给我。

    将一个类声明为 Spring 的 bean 的注解有哪些??

    • @Autowired: 自动装配bean
    • @Component: 可标注任意类为 Spring 组件
    • @Service: 用于服务层
    • @Resposity: 对应持久层即 Dao 层,主要用于数据库操作
    • @Controller: 对应控制层

    Spring Bean 的生命周期

    Spring 框架中用到了哪些设计模式?

    • 工厂设计模式:Spring 使用工厂模式通过 BeanFactory、ApplcationContext 创建 Bean 对象
    • 代理设计模式:Spring AOP 功能实现
    • 单例设计模式:Spring 中的Bean默认都是单例的
    • 包装器设计模式:项目需连接多个数据库,而且不同的客户在每次访问中根据需要会去访问不同的数据库。
    • 观察者模式:Spring 事件驱动模型就是观察者模式很经典的应用
    • 适配器模式:Spring AOP 的增加或通知使用到了适配器模式;SpringMVC 中的也是用到适配器模式 Controller

    @Transactional(rollbackFor = Exception.class) 注解

    Exception 分为 RuntimeException 和 非运营时异常。事务管理至关重要,即使出现异常情况,它也可以保证数据的一致性。

    @Transactional 注解作用于类上时,该类的所有 public 方法都将具有该类型的事务属性,同时,我们也可以在方法级别使用该标注来覆盖类级别的定义。如果类和方法上都加了这个注解,那么这个类里面的方法抛出异常,就会回滚,数据库里面的数据也会回滚。

    @Transactional 不配置 rollbackFor 属性,那么只会遇到 RuntimeException 时才会回滚;配置 rollbackFor = Exception.class 时,那么在非运行时异常时也会进行回滚。

    相关文章:https://developer.ibm.com/zh/articles/j-master-spring-transactional-use/

  • 相关阅读:
    concrete maths ch4 number theory
    Aho-Corasick algorithm
    Finding repetitions
    Suffix Automaton
    Z-function and its calculation
    mongodb安装与启动
    centos redis 集群搭建
    nginx实现热部署(平滑升级)
    nacos集群部署安装
    springboot+zookeeper+dubbo整合
  • 原文地址:https://www.cnblogs.com/blackBlog/p/13451738.html
Copyright © 2020-2023  润新知