手写Spring事务框架

Spring事务基于AOP环绕通知和异常通知

编程事务 声明事务

Spring事务底层使用编程事务+AOP进行包装的   = 声明事务

AOP应用场景:  事务 权限 参数验证

什么是AOP技术

AOP技术应用场景

面向切面编程  解决代码复用问题

AOP编程核心点: 在方法之前或者之后处理事情

AOP底层实现原理:代理设计模式

Spring事务基于AOP的环绕通知

为什么用AOP: 复用 解耦

AOP:

静态代需要生成目标代理对象

动态代理不需要生成目标代理对象

动态代理分为:JDK动态代理  CGLIB动态代理

JDK需要接口  动态代理需子类实现

CGLIB是基于ASM字节码包装的一个类库

ASM: 字节码技术

使用字节码技术可以创建类

静态代理 如果几千个类需要代理 就得写几千个代理对象

动态代理是没有代理类这一层的  虚拟生成一个动态代理对象 (一般使用字节码技术 反射技术)

Spring核心知识

Spring是一个开源框架,Spring是于2003年兴起的一个轻量级的Java开发框架,由Rod Johnson在其著作Expert One-On-One J2EE Development and Design中阐述的部分理念和原型衍生而来。它是为了解决企业应用开发的复杂性而创建的。框架的主要优势之一就是其分层架构,分层架构允许使用者选择使用哪一个组件,同时为J2EE应用程序开发提供集成的框架。Spring使用基本的JavaBean来完成以前只可能由EJB完成的事情。然而,Spring的用途不仅限于服务器端的开发。从简单性、可测试性和松耦合的角度而言,任何Java应用都可以从Spring中受益。Spring的核心是控制反转(IoC)和面向切面(AOP)。简单来说,Spring是一个分层的JavaSE/EEfull-stack(一站式)轻量级开源框架。
为什么说Spring是一个一站式的轻量级开源框架呢?EE开发可分成三层架构,针对JavaEE的三层结构,每一层Spring都提供了不同的解决技术。
? WEB层:SpringMVC
? 业务层:Spring的IoC
? 持久层:Spring的JDBCTemplate(Spring的JDBC模板,ORM模板用于整合其他的持久层框架)
从上面的简要介绍中,我们要知道Spring的核心有两部分:
? IoC:控制反转。
举例来说,在之前的操作中,比方说有一个类,我们想要调用类里面的方法(不是静态方法),就要创建类的对象,使用对象调用方法实现。对于Spring来说,Spring创建对象的过程,不是在代码里面实现的,而是交给Spring来进行配置实现的。
AOP:面向切面编程。

SpringAOP原理

AOP编程技术

什么是AOP编程

AOP: Aspect Oriented Programming 面向切面编程。

  面向切面编程(也叫面向方面):Aspect Oriented Programming(AOP),是目前软件开发中的一个热点。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。

  AOP是OOP的延续,是(Aspect Oriented Programming)的缩写,意思是面向切面(方面)编程。

  主要的功能是:日志记录,性能统计,安全控制,事务处理,异常处理等等。

  主要的意图是:将日志记录,性能统计,安全控制,事务处理,异常处理等代码从业务逻辑代码中划分出来,通过对这些行为的分离,我们希望可以将它们独立到非指导业务逻辑的方法中,进而改
 变这些行为的时候不影响业务逻辑的代码。

  可以通过预编译方式和运行期动态代理实现在不修改源代码的情况下给程序动态统一添加功能的一种技术。AOP实际是GoF设计模式的延续,设计模式孜孜不倦追求的是调用者和被调用者之间的解耦,AOP可以说也是这种目标的一种实现。

假设把应用程序想成一个立体结构的话,OOP的利刃是纵向切入系统,把系统划分为很多个模块(如:用户模块,文章模块等等),而AOP的利刃是横向切入系统,提取各个模块可能都要重复操作的部分(如:权限检查,日志记录等等)。由此可见,AOP是OOP的一个有效补充。

注意:AOP不是一种技术,实际上是编程思想。凡是符合AOP思想的技术,都可以看成是AOP的实现。

Aop  aspect object programming  面向切面编程

功能: 让关注点代码与业务代码分离!

关注点

关注点,重复代码就叫做关注点;

切面

关注点形成的类,就叫切面(类)!

面向切面编程,就是指 对很多功能都有的重复的代码抽取,再在运行的时候网业务方法上动态植入“切面类代码”。

切入点

执行目标对象方法,动态植入切面代码。

可以通过切入点表达式,指定拦截哪些类的哪些方法; 给指定的类在运行的时候植入切面类代码。

AOP底层实现原理

代理设计模式

什么是代理模式

通过代理控制对象的访问,可以详细访问某个对象的方法,在这个方法调用处理,或调用后处理。既(AOP微实现)  ,AOP核心技术面向切面编程。

代理模式应用场景

SpringAOP、事物原理、日志打印、权限控制、远程调用、安全代理 可以隐蔽真实角色

代理的分类

静态代理(静态定义代理类)

动态代理(动态生成代理类)

Jdk自带动态代理

Cglib 、javaassist(字节码操作库)

静态代理
什么是静态代理

由程序员创建或工具生成代理类的源码,再编译代理类。所谓静态也就是在程序运行前就已经存在代理类的字节码文件,代理类和委托类的关系在运行前就确定了。

静态代理代码
public interface IUserDao {
    void save();
}
public class UserDao implements IUserDao {
    public void save() {
        System.out.println("已经保存数据...");
    }
}
代理类
public class UserDaoProxy implements IUserDao {
    private IUserDao target;

    public UserDaoProxy(IUserDao iuserDao) {
        this.target = iuserDao;
    }

    public void save() {
        System.out.println("开启事物...");
        target.save();
        System.out.println("关闭事物...");
    }

}
动态代理
什么是动态代理

1.代理对象,不需要实现接口

2.代理对象的生成,是利用JDK的API,动态的在内存中构建代理对象(需要我们指定创建代理对象/目标对象实现的接口的类型)

3.动态代理也叫做:JDK代理,接口代理

JDK动态代理

1)原理:是根据类加载器和接口创建代理类(此代理类是接口的实现类,所以必须使用接口 面向接口生成代理,位于java.lang.reflect包下)

2)实现方式:

1. 通过实现InvocationHandler接口创建自己的调用处理器 IvocationHandler handler = new InvocationHandlerImpl(…);

2. 通过为Proxy类指定ClassLoader对象和一组interface创建动态代理类Class clazz = Proxy.getProxyClass(classLoader,new Class[]{…});

3. 通过反射机制获取动态代理类的构造函数,其参数类型是调用处理器接口类型Constructor constructor = clazz.getConstructor(new Class[]{InvocationHandler.class});

4. 通过构造函数创建代理类实例,此时需将调用处理器对象作为参数被传入Interface Proxy = (Interface)constructor.newInstance(new Object[] (handler));

缺点:jdk动态代理,必须是面向接口,目标业务类必须实现接口

// 每次生成动态代理类对象时,实现了InvocationHandler接口的调用处理器对象
public class InvocationHandlerImpl implements InvocationHandler {
    private Object target;// 这其实业务实现类对象,用来调用具体的业务方法
    // 通过构造函数传入目标对象
    public InvocationHandlerImpl(Object target) {
        this.target = target;
    }

    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        Object result = null;
        System.out.println("调用开始处理");
        result = method.invoke(target, args);
        System.out.println("调用结束处理");
        return result;
    }

    public static void main(String[] args) throws NoSuchMethodException, SecurityException, InstantiationException,
            IllegalAccessException, IllegalArgumentException, InvocationTargetException {
        // 被代理对象
        IUserDao userDao = new UserDao();
        InvocationHandlerImpl invocationHandlerImpl = new InvocationHandlerImpl(userDao);
        ClassLoader loader = userDao.getClass().getClassLoader();
        Class<?>[] interfaces = userDao.getClass().getInterfaces();
        // 主要装载器、一组接口及调用处理动态代理实例
        IUserDao newProxyInstance = (IUserDao) Proxy.newProxyInstance(loader, interfaces, invocationHandlerImpl);
        newProxyInstance.save();
    }

}
CGLIB动态代理

原理:利用asm开源包,对代理对象类的class文件加载进来,通过修改其字节码生成子类来处理。

什么是CGLIB动态代理

使用cglib[Code Generation Library]实现动态代理,并不要求委托类必须实现接口,底层采用asm字节码生成框架生成代理类的字节码

CGLIB动态代理相关代码

public class CglibProxy implements MethodInterceptor {
    private Object targetObject;
    // 这里的目标类型为Object,则可以接受任意一种参数作为被代理类,实现了动态代理
    public Object getInstance(Object target) {
        // 设置需要创建子类的类
        this.targetObject = target;
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(target.getClass());
        enhancer.setCallback(this);
        return enhancer.create();
    }

    public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
        System.out.println("开启事物");
        Object result = proxy.invoke(targetObject, args);
        System.out.println("关闭事物");
        // 返回代理对象
        return result;
    }
    public static void main(String[] args) {
        CglibProxy cglibProxy = new CglibProxy();
        UserDao userDao = (UserDao) cglibProxy.getInstance(new UserDao());
        userDao.save();
    }
}

CGLIB动态代理与JDK动态区别

java动态代理是利用反射机制生成一个实现代理接口的匿名类,在调用具体方法前调用InvokeHandler来处理。

而cglib动态代理是利用asm开源包,对代理对象类的class文件加载进来,通过修改其字节码生成子类来处理。

Spring中。

1、如果目标对象实现了接口,默认情况下会采用JDK的动态代理实现AOP

2、如果目标对象实现了接口,可以强制使用CGLIB实现AOP

3、如果目标对象没有实现了接口,必须采用CGLIB库,spring会自动在JDK动态代理和CGLIB之间转换

JDK动态代理只能对实现了接口的类生成代理,而不能针对类 。

CGLIB是针对类实现代理,主要是对指定的类生成一个子类,覆盖其中的方法 。

因为是继承,所以该类或方法最好不要声明成final ,final可以阻止继承和多态。

AOP编程使用

注解版本实现AOP

原文地址:https://www.cnblogs.com/toov5/p/10363576.html

时间: 2024-07-30 10:25:17

手写Spring事务框架的相关文章

手写 Spring 事务、IOC、DI 和 MVC

Spring AOP 原理 什么是 AOP? AOP 即面向切面编程,利用 AOP 可以对业务进行解耦,提高重用性,提高开发效率 应用场景:日志记录,性能统计,安全控制,事务处理,异常处理 AOP 底层实现原理是采用代理实现的 Spring 事务 基本特性: 原子性 隔离性 一致性 持久性 事务控制分类: 编程式事务:手动控制事务操作 声明式事务:通过 AOP 控制事务 编程式事务实现 使用编程事务实现手动事务 @Component @Scope("prototype") public

从零开始手写 spring ioc 框架,深入学习 spring 源码

IoC Ioc 是一款 spring ioc 核心功能简化实现版本,便于学习和理解原理. 创作目的 使用 spring 很长时间,对于 spring 使用非常频繁,实际上对于源码一直没有静下心来学习过. 但是 spring 源码存在一个问题,那就是过于抽象,导致学习起来成本上升. 所以本项目由渐入深,只实现 spring 的核心功能,便于自己和他人学习 spring 的核心原理. spring 的核心 Spring 的核心就是 spring-beans,后面的一切 spring-boot,spr

手写Spring框架,加深对Spring工作机制的理解!

在我们的日常工作中,经常会用到Spring.Spring Boot.Spring Cloud.Struts.Mybatis.Hibernate等开源框架,有了这些框架的诞生,平时的开发工作量也是变得越来越轻松,我们用 Spring Boot 分分钟可以新建一个Web项目. 记得自己刚开始工作的时候还是在用Servlet写Web项目,自己写数据库连接池,用原生JDBC操作数据库,好了不发散了.回到这篇文章的主题,今天通过手写Spring框架,帮大家深入了解一下Spring的工作机制,文中涉及的代码

我是这样手写Spring的,麻雀虽小,五脏俱全

人见人爱的Spring已然不仅仅只是一个框架了.如今,Spring已然成为了一个生态.但深入了解Spring的却寥寥无几.这里,我带大家一起来看看,我是如何手写Spring的.我将结合对Spring十多年的研究经验,用不到400行代码来描述Spring IOC.DI.MVC的精华设计思想,并保证基本功能完整.首先,我们先来介绍一下Spring的三个阶段,配置阶段.初始化阶段和运行阶段(如图):配置阶段:主要是完成application.xml配置和Annotation配置.初始化阶段:主要是加载

一个老程序员是如何手写Spring MVC的

人见人爱的Spring已然不仅仅只是一个框架了.如今,Spring已然成为了一个生态.但深入了解Spring的却寥寥无几.这里,我带大家一起来看看,我是如何手写Spring的.我将结合对Spring十多年的研究经验,用不到400行代码来描述SpringIOC.DI.MVC的精华设计思想,并保证基本功能完整. 首先,我们先来介绍一下Spring的三个阶段,配置阶段.初始化阶段和运行阶段(如图): 配置阶段:主要是完成application.xml配置和Annotation配置. 初始化阶段:主要是

记录一次阿里架构师全程手写Spring MVC 原

人见人爱的Spring已然不仅仅只是一个框架了.如今,Spring已然成为了一个生态.但深入了解Spring的却寥寥无几.这里,我带大家一起来看看,我是如何手写Spring的.我将结合对Spring十多年的研究经验,用不到400行代码来描述SpringIOC.DI.MVC的精华设计思想,并保证基本功能完整. 首先,我们先来介绍一下Spring的三个阶段,配置阶段.初始化阶段和运行阶段(如图): 配置阶段:主要是完成application.xml配置和Annotation配置. 初始化阶段:主要是

自己手写WEB程序框架并运行

1.新建文件夹,起名MyWeb 2.文件夹下,新建两个文件夹 WEB-INF, META-INF,,还可以新建一些jsp,html文件 ,如 index.html 3在WEB-INF中必须存在一个文件WEB.xml, 还包含两个文件夹 lib, classes 4 在WEB.xml中写入最简单的<web-app> ....  </web-app>,,,,,编辑一下index.html 下面是要运行了 1,cmd 2,切换到MyWeb的文件夹,jar 命令查看一下各个参数的含义 3,

手写 Spring

手写 Spring 不多说,简历装 X 必备.不过练好还是需要求一定的思维能力. 一.整体思路 思路要熟练背下来 1)配置阶段 配置 web.xml: XDispatchServlet 设定 init-param: contextConfigLocation = classpath:application.xml 设定 url-pattern: /* 配置 Annotation: @XController @XService @XAutowired @XRequestMapping 2)初始化阶

spring事物(1)-----手写spring的事物框架

一,区别声明式事物和编程式事物 所谓编程式事务指的是通过编码方式实现事务,即类似于JDBC编程实现事务管理.管理使用TransactionTemplate或者直接使用底层的PlatformTransactionManager.对于编程式事务管理,spring推荐使用TransactionTemplate. 声明式事物其实就是编程式事物+spring的AOP代理,在里面我们是见不到手动的begin commit  和rollback的. 管理建立在AOP之上的.其本质是对方法前后进行拦截,然后在目