Spring学习笔记


Spring提供了JavaEE每一层的解决方案,Spring是Java EE的全栈式框架。

Spring的优势

Spring除了不能帮助我们系统业务逻辑,其余的部分都能帮助我们简化开发。
  • Spring低浸入、低耦合地根据配置文件创建及组装对象间的关系。
  • Spring面向切面编程,日志记录、性能统计、安全控制。
  • 强大的声明式事务管理。
  • 提供了与第三方优秀框架的整合(Hibernate、JPA),自己也有一套JDBC模板方便访问数据库。
  • 提供了与第三方Web(Struts1/2、JSF)整合,自己也有一套SpringMVC。
  • 方便的与Java Mail、任务调度、缓存框架技术整合,降低开发难度。

Spring框架架构

Core Container(核心容器)包含Beans、Core、Context、SpELl模块。
Data Access、Integration层包含JDBC、ORM、JMS、OXM、Transactions模块。
Web层包含Web、WebSocket、Servlet、Porlet模块
AOP提供符合AOP联盟标准的面向切面实现。
Test支持使用TestNG和Junit组件测试。
Spring 框架图

一、IOC

IOC容器
原理:
 1. 通过Resource对象加载配置文件
 2. 解析配置文件,得到指定名称的Bean
 3. 解析Bean元素,id为bean的名称,class反射得到实例
 4. getBean返回实例对象

DI:依赖注入(注入依赖)
IOC容器是如何知道哪些是它应该管理的对象呢?
这时候需要配置文件,IOC容器通过读取配置文件的配置元数据。
元数据的配置的三种方式:

  • xml
  • Annotation 注解
  • Java-base Java代码
    使用BeanFactory有延迟初始化类的特性,从哪可以看出呢?
    Spring先创建容器,等到客户端获取某个对象的时候再去创建对象。

实例:在这里插入图片描述
使用ApplicationContext没有延迟,在初始化容器的时候就开始创建bean.–推荐使用
在这里插入图片描述

实例化方式
  • 构造器实例化–推荐(保证无参数构造器)
  • 静态工厂实例化
  • 实例工厂方法
  • 实现FactoryBean接口实现
bean作用域
  • singleton单例(默认)–常用
  • prototype多例(struts2的action)
  • request web开发中将bean放入request
  • session web开发中将bean放入session
  • globalSession Porlet环境下,分布式系统存在session(单点登录)
  • application 将单个bean定义的作用域限定为ServletContext的生命周期。 仅在可感知网络的ApplicationContext上下文中有效。
  • websock 将单个bean定义的作用域限定为ServletContext的生命周期。 仅在可感知网络的websock 上下文中有效。
bean的生命周期
  1. 启动Spring容器
  2. 通过Bean对象的构造器创建Bean
  3. 注入属性
  4. 调用初始化方法init-method
  5. 我们使用
  6. 调用销毁方法destroy-method
  7. Spring容器销毁
DI

注入依赖。注入bean的属性值。

方式一:setter方法注入
方式二:构造器注入
XML配置(了解)

在这里插入图片描述

  • byName
  • 通过构造器
<bean class="com.itxin.spring.xml.Person" autowire="constructor"/>

setter注入

  • 对于变量
    属性注入
  • 对于对象
    对象
  • 对于集合
    在这里插入图片描述
    构造器注入
    bean元素继承
    placeholder (连接池常用)
    在这里插入图片描述
注解

@Autowired Spring官方提供,字段或者setter方法上,spring3.0之前需要手动配置解析器 找不到依赖(注入null)可配置不报错
@Resource JavaEE规范,作用跟Autowire相同,找不到依赖报错
@value 注入简单类型,常量,不能掉{}
@Component 用在类名上,默认bean的id类名首字母小写。需要配置IOC注解解析器。

Java代码配置

二、AOP

先来说说代理模式
静态代理:在程序运行前就已经存在代理类的字节码文件。
动态代理:动态代理类在程序运行前由JVM通过反射动态生成,不存在字节码文件。
如何实现动态代理?

  1. JDK动态代理
    在这里插入图片描述
  2. CGLIB动态代理
package com.itxin.spring.proxy;

import static org.springframework.test.web.client.match.MockRestRequestMatchers.method;

import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

import org.springframework.cglib.proxy.Enhancer;

import lombok.Setter;

/**
 * CGLIB动态代理
 * 
 * @author Administrator
 *
 */
public class EmployeeAdviceCGLIB implements org.springframework.cglib.proxy.InvocationHandler {

	@Setter
	private Object obj;

	/**
	 * 具体的增强细节
	 */
	@Override
	public Object invoke(Object arg0, Method method, Object[] arg2) throws Throwable {
		return null;
	}

	/**
	 * 创建代理对象
	 * 
	 * @param <T>真实对象类型
	 * @return
	 */
	public <T> T getProxyObject() {
		Enhancer enhancer = new Enhancer();
		enhancer.setSuperclass(obj.getClass());// 继承要增强的那个类
		enhancer.setCallback(this);

		return (T) enhancer.create();// 创建代理对象
	}

}

两者之间的区别?
JDK动态代理必须提供接口
CGLIB原理:自己的真实对像的代理类实现真实类,把原来需要增强的方法覆盖重写实现增强。所以它不需要接口。

术语翻译解释
Jionpoint连接点被拦截到需要增强的方法
Pointcut切入点哪些包中的哪些类中的哪些方法(连接点的集合)
Advice增强当拦截到Jionpoint后,在方法执行的什么时期。(前置增强、后置增强、异常增强、最终增强、环绕增强)
Aspect切面Pointcut+Advice,去哪些地方+在什么时候+做什么增强
Target目标对象被代理的目标对象
Weaving织入把Advice加到Target之后,创建出Proxy对象的过程
Proxy代理类一个类被AOP织入增强后,产生的代理类

Pointcut表达式
通配符*:表示一个单词,匹配任意部分
通配符…:全限定名中的和方法参数,分别表示子包和0-n个参数

<!-- 对com.itxin.spring.service包中,所有以Service结尾的方法增强+ -->
execution(* com.itxin.spring.service.*Service.*(..))

使用注解方式配置切面

@Component
@Aspect
public class TxAdvice {

	@Pointcut("execution(* com.itxin.spring.service.*Service.*(..))")
	public void txAdvice() {

	}
}

注意使用注解方式需要配置AOP的解析器。

三、DAO

JdbcTemplate是 JDBC 核心包中的中心 class。它处理资源的创建和释放,帮助您避免 common 错误,例如忘记关闭连接。它执行核心 JDBC 工作流的基本任务(例如语句创建和执行),留下 application code 以提供 SQL 并提取结果。 JdbcTemplate class:

运行 SQL 查询

更新 statements 和存储过程 calls

对ResultSet实例执行迭代并提取返回的参数值。

捕获 JDBC exceptions 并将它们转换为org.springframework.dao包中定义的通用的,更具信息性的 exception 层次结构。 (见一致的 Exception 层次结构 .)

当您为 code 使用JdbcTemplate时,您只需要实现回调接口,为它们提供明确定义的 contract。给定JdbcTemplate class 提供的Connection,PreparedStatementCreator回调接口创建一个预准备语句,提供 SQL 和任何必要的参数。 CallableStatementCreator接口的 true 也是如此,它创建了可调用的 statements。 RowCallbackHandler接口从ResultSet的每一行中提取值。

您可以通过使用DataSource reference 直接实例化在 DAO implementation 中使用JdbcTemplate,也可以在 Spring IoC 容器中对其进行配置,并将其作为 bean reference 提供给 DAO。

@Repository (1)
public class JdbcCorporateEventDao implements CorporateEventDao {

    private JdbcTemplate jdbcTemplate;

    @Autowired (2)
    public void setDataSource(DataSource dataSource) {
        this.jdbcTemplate = new JdbcTemplate(dataSource); (3)
    }

    // JDBC-backed implementations of the methods on the CorporateEventDao follow...
}
事务引出

转账案列:转账操作,转入+转出,以前程序这样正常执行

  • 开启事务
  • 转入
  • 提交事务

转出正常操作

  • 开启事务
  • 转出
  • 提交事务
    如果在这两个操作之前出现异常,钱就莫名少了,需要把这两个操作绑定在一起。也就是说,这两个操作根本就不在同一个事务中。

事务

概念:事务是一系列操作组成的工作单元,该工作单元的操作是不可分割的,要么所有操作都做,要么都不做。
名词解释
Atomicity原子性事务是不可分割的最小单元。事务内的操作要么都做,要么都不做。
Consistency一致性数据完整性约束没有被破坏。
Isolation隔离性多个事务处于并发访问同一个数据库资源时,事务之间相互影响程度。
Durability持久性事务一旦执行成功,改变不可逆

数据并发导致的五类问题

问题类型原因+效果
第一类丢失更新两个事务更新相同数据,如果一个事务提交,另一个事务回滚,第一个事务的更新将被回滚。
脏读第二个事务查询到第一个事务未提交的更新数据,第二个事务根据该数据执行,但第一个事务回滚,第二个事务操作脏数据。
虚读一个事务查询到了另一个事务已经提交的新数据,导致多次查询年数据不一致。
不可重复读一个事务查询到另一个事务已经修改的数据,导致多次查询数据不一样。
第二类丢失更新多个事务同时读取相同数据,并完成各自的事务提交,导致最后一个事务提交会覆盖前面所有事务的修改。

隔离级别

Spring提供的事务管理

事务的传播规则

  • 情况一:需要遵从当前事务

REQUIRED:必须存在一个事务,如果当前存在一个事务,则加入到该事务中,否则,新建一个事务;----使用较多
SUPPORTS:支持当前事务。如果当前存在事务,则使用改事务,否则,以非事务形式运行。
MANDAT:强制的,必须存在事务,如果当前存在事务,使用,否则,非法的事务状态异常(IllegalTranactionStatusExcetion)

  • 情况二:不存在当前事务的
    REQUIRES_NEW:不管当前是否存在事务,必须是一个新的事务。–使用较多。
    NOT_SUPPORTD:以非事务方式执行,如果当前存在事务,把当前事务挂起(暂停)
    NEVER:不支持事务,如果当前存在事务,抛出异常。
    • 情况三:寄生事务(外部事物、内部事务、嵌套事务)
      NESTED: 寄生事务:如果当前存在事务,则在内部事务执行
      不存在事务,则创建一个新的事务。寄生事务可以通过数据库savePoint来实现,寄生事务可以回滚,但是他的回滚不影响外部事务,但是外部事物的回滚会影响寄生事务。
      寄生事务并不是所有事务管理器都支持,hibernate默认不支持,需要手动开启。jdbc和mybatis的事务管理器DateSourceTransaction默认支持。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值