前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Spring框架基础

Spring框架基础

原创
作者头像
熙攘
发布2022-03-26 21:26:15
4520
发布2022-03-26 21:26:15
举报
文章被收录于专栏:熙攘专栏

Spring概念

Sping是分层的Java SE/EE 应用 Full-stack 轻量级开源框架,以Ioc(Inverse Of Control:反转控制)和AOP(Aspect Oriented Programming:面向切面编程)为内核,提供了展现层SpringMVC和持久层Spring JDBC以及业务层事务管理等众多的企业级应用技术,还能整合开源世界众多著名的第三方框架和类库,逐渐成为使用最多的Java EE企业应用开源框架。

Spring体系结构

核心容器(Core Container),数据访问/集成(Data Access/Integration)层,Web层,AOP(Aspect Oriented Programming)模块,植入(Instrumentation)模块,消息传输(Messaging),测试(Test)模块。

IOC概念与背景

1.程序的耦合

耦合:程序间的依赖关系,包括类之间的依赖与方法间的依赖

解耦:

1.使用反射来创建对象,而避免使用new关键字

2.通过读取配置文件来获取要创建的对象全限定类名

普通程序中的耦合举例:(耦合现象严重)

持久层dao接口:提供保存账户方法

持久层dao实现类:实现保存账户的方法

业务层service接口:提供保存账户方法

业务层service实现类:创建持久层实现类的对象,由该对象实现保存账户的方法

模拟表现层client:在main函数中创建业务层实现类的对象,由该对象调用业务层实现类中的保存账户方法

2.解耦的思想

思想概述:

把三层(dao,service,client)的对象都使用配置文件配置起来。

当启动服务器应用加载的时候,让一个工厂类中的方法通过读取配置文件,把这些对象创建出来并保存到一个map容器中。

在接下来的使用的时候,直接使用创建好的对象即可。

创建Bean对象的工厂:

baen在计算机英语中,是可重用组件的含义

javabean是用java语言编写的可重用组件。

3.正式介绍Ioc

全称为:inverse of control

是Spring框架的重要特征。把创建对象的权力交给框架。常见的方式有:依赖注入,依赖查找。

意义:削减耦合。

AOP

AOP(Aspect Oriented Programming),即面向切面编程,可以说是OOP(Object Oriented Programming,面向对象编程)的补充和完善。OOP引入封装、继承、多态等概念来建立一种对象层次结构,用于模拟公共行为的一个集合。不过OOP允许开发者定义纵向的关系,但并不适合定义横向的关系,例如日志功能。日志代码往往横向地散布在所有对象层次中,而与它对应的对象的核心功能毫无关系对于其他类型的代码,如安全性、异常处理和透明的持续性也都是如此,这种散布在各处的无关的代码被称为横切(cross cutting),在OOP设计中,它导致了大量代码的重复,而不利于各个模块的重用。

AOP技术恰恰相反,它利用一种称为"横切"的技术,剖解开封装的对象内部,并将那些影响了多个类的公共行为封装到一个可重用模块,并将其命名为"Aspect",即切面。所谓"切面",简单说就是那些与业务无关,却为业务模块所共同调用的逻辑或责任封装起来,便于减少系统的重复代码,降低模块之间的耦合度,并有利于未来的可操作性和可维护性。

使用"横切"技术,AOP把软件系统分为两个部分:核心关注点横切关注点。业务处理的主要流程是核心关注点,与之关系不大的部分是横切关注点。横切关注点的一个特点是,他们经常发生在核心关注点的多处,而各处基本相似,比如权限认证、日志、事物。AOP的作用在于分离系统中的各种关注点,将核心关注点和横切关注点分离开来。

4.ioc的常用注解
对象生命周期(作用范围)注解
  • @Scope 生命周期(作用范围)注解,取值singleton(默认值,单实例)和 prototype(多实例)
    • 单实例:整个IOC容器只会存在一个实例
    • 多实例:每次都创建一个新的实例对象
初始化方法和销毁方法注解
  • @PostConstruct 相当于 init-method 实例创建时调用方法
  • @PreDestroy 相当于 destroy-method 实例销毁时调用方法
    • 单例下IOC容器销毁,调用方法
    • 多例下java虚拟机负责销毁

1.aop增强和ioc依赖注入和注解实现

代码语言:javascript
复制
1.1:异常抛出增强
代码语言:javascript
复制
  <aop:config>
    <aop:aspect ref="增强方法所有的Bean">
      <aop:after method="增强处理方法" pointcut-ref="切入点id" throwing="e"/>
    </aop:aspect>
  </aop:config>

1.2:环绕增强

代码语言:javascript
复制
  <aop:config>
    <aop:aspect ref="增强方法所有的Bean">
      <aop:around method="增强处理方法" pointcut-ref="切入点id" />
    </aop:aspect>
  </aop:config>

1.3:构造注入

代码语言:javascript
复制
<bean id="唯一标识" class="类的全路径">
  <constructor-arg name="参数名称" ref="依赖对象"/>
</bean>

注:有多个参数可以配置多个constructor-arg标签,除了name属性区别多个参数外,还可以使用constructor-arg标签中的index属性指定参数的索引,从0开始,constructor-arg提供了type属性,用以标识参数的类型

1.4:p空间注入

代码语言:javascript
复制
<bean id="唯一标识" class="全路径" p:"属性1"="注入的值1" p:"属性2"="注入的值2"/>
<bean id="唯一标识" class="全路径" p:dao-ref="注入的Bean"/>
1.bean管理类常用的4个注解

(作用相同,推荐使用在不同分层上)

  • @Component 普通的类
  • @Controller 表现层(用于标注控制器类)
  • @Service 业务层
  • @Repository 持久层(用于标注DAO类)
2.依赖注入常用的注解
  • @Value 注入普通类型
  • @Autowired 默认按类型进行自动装配(引用类型) **注:**使用@Autowired注解进行Bean注入时,如果找不到Bean会报异常,如果依赖非必须为避免报异常,把required属性设置为false
  • @Qualififier 和@Autowired一起使用,使用名称注入
  • @Resource 使用name属性,按名称注入

注:@Resource注解可以通过type参数指定要注入的Bean的具体类型

3.aop的注解

@AfterThrowing 抛出增强(目标方法发生异常,执行)

@Before 前置增强(目标方法执行之前,执行注解标注的内容)

@AfterReturning 后置增强(目标方法正常执行完毕后,执行)

@Around 环绕增强(目标方法执行前后,分别执行一些代码)

@After 最终增强 (无论如何都会执行,多用于释放资源)

@Aspect 定义切面 (作用是把当前类标识为一个切面供容器读取)

@Pointcut 定义一个表达式

4.aop所需要依赖的jar包
代码语言:javascript
复制
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.9.7</version>
        </dependency>
         <dependency>
            <groupId>aopalliance</groupId>
            <artifactId>aopalliance</artifactId>
            <version>1.0</version>
        </dependency>
5.配置切面
代码语言:javascript
复制
<aop:config>
    <!--定义切面-->
    <!--execution属性为该切入点的表达式,execution是切入点指示符,它的括号中是一个切入点表达式,切入点表达式支持模糊匹配,-->
     <!--publie void *(entity.user):“*”表示匹配所有的方法名-->
    <aop:pointcut id="SupplierMethod" expression="execution(* com.wei.Service.*.*(..))"/>
    <!--把事务属性定义到切面里-->
    <aop:advisor advice-ref="txAdvice" pointcut-ref="SupplierMethod"/>
</aop:config>

Spring框架整合Mybatis框架

1.整合所需要的jar包
代码语言:javascript
复制
        <dependency>
            <groupId>commons-dbcp</groupId>
            <artifactId>commons-dbcp</artifactId>
            <version>1.4</version>
        </dependency>
         <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>5.3.9</version>
        </dependency>
         <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-spring</artifactId>
            <version>2.0.6</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
1.1:创建接口及Mybatis映射文件

映射文件只需要配置类型别名和一些设置即可

代码语言:javascript
复制
  <typeAliases>
      <!--类型别名-->
        <typeAlias type="com.wei.pojo.TSysUser" alias="tSysUser"/>
    </typeAliases>
2.使用Spring配置文件配置数据源
2.1:引入properties文件
代码语言:javascript
复制
   <!--引入properties文件-->
    <bean class="org.springframework.context.support.PropertySourcesPlaceholderConfigurer">
       <property name="location" value="classpath:dataSoure.properties"/>
    </bean>
2.2:配置数据源
代码语言:javascript
复制
 <!--配置数据源-->
    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
        <property name="driverClassName" value="${mysql.driver}"/>
        <property name="url" value="${mysql.url}"/>
        <property name="username" value="${mysql.username}"/>
        <property name="password" value="${mysql.password}"/>
    </bean>
3.通过Spring配置文件配置SqlSessionFactory

要使用Spring-MyBatis一起使用,需要在 Spring 应用上下文中定义至少两样东西:一个 SqlSessionFactory 和至少一个数据映射器类。

在 MyBatis-Spring 中,可使用 SqlSessionFactoryBean来创建 SqlSessionFactory。 要配置这个工厂 bean,只需要把下面代码放在 Spring 的 XML 配置文件中

3.1:配置SQLSessionFactory
代码语言:javascript
复制
  <!--配置SQLSessionFactory-->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <!--引用数据源组件-->
        <property name="dataSource" ref="dataSource"/>
        <!--引用mybatis配置文件中的配置-->
        <property name="configLocation" value="classpath:config.xml"/>
        <!--配置SQL映射文件信息-->
        <property name="mapperLocations">
            <list>
                <value>classpath:Mapper/*.xml</value>
            </list>
        </property>
    </bean>
代码语言:javascript
复制
 <!--获取SqlSession,SqlSessionTemplate就是Sqlsession-->
    <bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
        <constructor-arg index="0" ref="sqlSessionFactory"/>
    </bean>
​
sqlsession.getmapper("这里给一个接口class)

注意:SqlSessionTemplate类实现了SqlSession接口,SqlSessionTemplate比SqlSession更加强大简介,能更好与SPring服务融合并简化部分流程化的工作,可以保证和当前Spring事务相关联,自动管理会话的生命周期,包括必要的事务关闭,提交和回滚操作。SqlSessionTemplate只能构造注入

3.2:使用MapperFactoryBean注入映射器

假设你定义了一个如下的 mapper 接口:

那么可以通过 MapperFactoryBean 将接口加入到 Spring 中:

代码语言:javascript
复制
<bean id="userMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">
  <property name="mapperInterface" value="org.mybatis.spring.sample.mapper.UserMapper" />
  <property name="sqlSessionFactory" ref="sqlSessionFactory" />
</bean>

需要注意的特点是:

  1. mapperInterface属性指定的映射器其值必须是一个接口类型,而不是具体的实现类。在这个示例中,通过注解来指定 SQL 语句,但是也可以使用 MyBatis 映射器的 XML 配置文件。
  2. MapperFactoryBean是SqlSessionDaoSupport的子类,使用时需要通过sqlSessionFactory()方法注入sqlSessionFactory实例以创建SqlSessionTemplate实例
  3. 如果映射器对应的SQL映射文件已映射器的类路径相同,该映射文件可以自动被MapperFactoryBean解析,
  4. Sql映射文件中的命名空间和映射器接口的名称需相同,映射元素的id和映射器接口的方法名称应相同

配置好之后,你就可以像 Spring 中普通的 bean 注入方法那样,将映射器注入到你的业务或服务对象中。MapperFactoryBean 将会负责 SqlSession 的创建和关闭。 如果使用了 Spring 的事务功能,那么当事务完成时,session 将会被提交或回滚。最终任何异常都会被转换成 Spring 的 DataAccessException 异常。

3.3:使用MapperScannerConfigurer注入映射器
  • MapperScannerConfigurer将递归扫描基准包(包括各层子包)下所有接口。
  • MapperScannerConfigurer会为所有由它创建的映射器实现类开启自动装配。也就是说,这些实现类都会自动注入SqlSessionFactory实例
  • basePackage可以配置多个包,使用逗号隔开
  • 此处使用的是sqlSessionFactoryBeanName
代码语言:javascript
复制
    <!--配置DAO-->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
         <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
        <property name="basePackage" value="com.wei.Mapper"/>
    </bean>
​
    <!--配置扫描注解定义的业务bean-->
    <context:comppnent-scan base-package="cn.cvs.service"/>
4.使用SqlSessionDaoSupport简化编码

通过继承SqlSessionDaoSupport类获取getSqlSession()实例处理数据,SqlSessionDaoSupport类中提供了setSqlSessionFactory()方法用来注入SqlSessionFactory并创建SqlSessionTemplate实例,同时,还提供了getSession()方法并将创建好的SqlSessionTemplate实例返回,而Spring配置文件中也无需再配置SqlSessionTemplate,只需通过该DAO对象的setSqlSessionFactory()方法为其注入SqlSessionFactory即可

代码语言:javascript
复制
<!--SupplierMapperimpl实现类继承了SqlSessionDaoSupport类-->
 <bean id="supplierMapper" class="com.wei.Mapper.impl.SupplierMapperimpl">
     <property name="sqlSessionFactory" ref="sqlSessionFactory"/>
 </bean>

声明式事务和注解实现声明式事务

首先定义好接口和配置Mapper映射SQL,并实现接口,在spring容器导入tx命名空间和aop空间

配置DataSourceTransactionManager时,要为其注入事先定好的数据源组件

1.配置声明事务
代码语言:javascript
复制
 <!--配置声明事务-->
    <!--定义事务管理器-->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>
    <!--设置事务属性 transaction-manager属性需引用一个事务管理器Bean-->
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
        <tx:attributes>
            <!--<tx:attributes>里可以有多个tx:attributes,name属性是必须的,用于指定相匹配的方法,可使用通配符对方法进行设置-->
            <tx:method name="*add"/>
            <!--事务的属性说明:-->
            <!--propagation;REQUIRED默认值表示如果存在一个事务,则支持当前事务:如果当前没有事务,则开启一个新事务-->
        </tx:attributes>
    </tx:advice>
2.事务的属性说明

属性

说明

timeout

设置一个事务所允许执行的最长时长(单位:秒),如果超过该时长且事务还没有完成,则自动回滚事务且出现org.springframework.transaction.TransactionTimedOutException异常

readOnly

事务只读,指对事务性资源进行只读操作,不能修改。

rollbackFor

指定对哪些异常回滚事务。默认情况下,如果没有抛出任何异常,或者抛出了检查时异常,依然提交事务。而rollbackFor可以控制事务在抛出某些检查时异常时回滚事务。

propagation

指定事务传播行为,一个事务方法被另一个事务方法调用时,必须指定事务应该如何传播。

isolation

指定事务隔离级别。

3.注解实现声明式事务

在业务类添加@Transactional注解即可为该类的所有业务统一添加事务处理。

属性

类型

说明

propagation

枚举型:Propagation

可选的传播性设置。使用举例:@Transactional(propagation=Propagation.REQUIRES_NEW)

isolation

枚举型:Isolation

可选的隔离性级别。使用举例:@Transactional(isolation=Isolation.READ_COMMITTED)

timeout

int型(以秒为单位)

事务超时。使用举例:@Transactional(timeout=10)

readOnly

布尔型

是否为只读型事务。使用举例:@Transactional(readOnly=true)

rollbackFor

一组Class类的实例,必须是Throwable的子类

一组异常类,遇到时必须进行回滚。使用举例:**@Transactional(rollbackFor={SQLException.class} ),多个异常可用英文逗号隔开**

rollbackForClassName

一组Class类的实例,必须是Throwable的子类**

一组异常类名,遇到时必须进行回滚。使用举例:**@Transactional(rollbackForClassName={"SQLException"} ),多个异常可用英文逗号隔开**

noRollbackFor

一组**Class类的实例,必须是Throwable的子类**

一组异常类,遇到时必须不回滚

noRollbackForClassName

一组**Class类的实例,必须是Throwable的子类**

一组异常类名,遇到时必须不回滚

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Spring概念
    • Spring体系结构
      • IOC概念与背景
        • 1.aop增强和ioc依赖注入和注解实现
          • Spring框架整合Mybatis框架
            • 声明式事务和注解实现声明式事务
            相关产品与服务
            容器服务
            腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档