Spring进阶(spring的入门程序详细过程)

  本篇文章为你整理了Spring进阶(spring的入门程序详细过程)的详细内容,包含有spring进阶推荐书籍 spring的入门程序详细过程 spring入门经典 spring integration入门 Spring进阶,希望能帮助你了解 Spring进阶。

   Java 全栈知识体系 ❁导航 ♥面试 ✿导读 JavaJavaJava 面向对象和基础 Java 面向对象基础 Java 基础知识体系 Java进阶 - 集合框架 Java 集合框架详解 Java进阶 - 并发框架 Java 并发知识体系 Java 并发理论基础 Java 并发线程基础 J.U.C 知识体系与详解 Java进阶 - IO框架 Java IO/NIO/AIO详解 Java进阶 - 新版本特性 Java 8 特性详解 Java 8 以上版本特性体系 Java 8 升Java 11特性必读 Java 11 升Java 17特性必读 Java进阶 - JVM相关 Java 类加载机制 Java 字节码和增强技术 JVM 内存结构详解 JVM 垃圾回收机制 Java 调试排错相关 算法算法算法基础和思想 数据结构基础 常见排序算法 算法思想 一些领域算法 安全算法 字符串匹配算法 分布式系统算法 海量数据处理 负载均衡算法 推荐算法 数据挖掘算法 ID生成算法 其它算法相关 头脑风暴 数据库数据库数据库基础和原理 数据库原理 SQL语言 SQL 数据库 MySQL 详解 NoSQL 数据库 Redis 详解 MongoDB 详解 ElasticSearch 详解 开发开发开发 - 常用开发基础 常用类库详解 正则表达式详解 CRON表达式详解 网络协议和工具详解 安全相关详解 开发 - 质量保障 单元测试详解 统一风格详解 质量管理详解 开发 - 代码重构 代码重构相关 SpringSpringSpring Framework(v5.3) Spring框架知识体系 Spring框架组成 控制反转(IOC) 面向切面编程(AOP) SpringMVC SpringBoot系列(v2.5) SpringBoot知识体系 SpringBoot入门 SpringBoot接口设计和实现 SpringBoot集成MySQL SpringBoot集成ShardingJDBC SpringBoot集成Redis SpringBoot集成Postgre SpringBoot集成ElasticSearch SpringBoot集成Socket SpringBoot定时任务 SpringBoot后端视图 SpringBoot监控 SpringBoot进阶 框架中间件框架中间件Web 容器 Tomcat 源码详解 ORM 框架 MyBatis 源码详解 分表分库框架 ShardingSphere 详解 架构架构架构基础和技术点 架构知识体系 从角色视角看架构 从分层视角看架构 从演化视角看架构 从模式视角看架构 高并发之缓存 高并发之限流 高并发之降级和熔断 高可用之负载均衡 高可用之容灾备份 分布式系统 分布式理论和一致性算法 全局唯一ID实现方案 分布式锁及实现方案 分布式事务及实现方案 分布式任务及实现方案 分布式会话及实现方案 微服务系统 微服务系统和设计 系统设计之商业业务平台 秒杀抽奖相关设计 电商交易相关设计 仓储物流相关设计 拉新投放相关设计 其它综合相关设计 系统设计之数据仓库平台 数据库架构相关设计 数据同步相关设计 数据仓库相关设计 数据治理相关设计 工具部署工具部署 开发工具 Git详解 Linux Docker 项目 方法论方法论开发理论 开发原则(SOLID) 分布式理论(CAP) 分布式理论(BASE) 事务理论(ACID) 微服务理论(康威定律) 开源协议 常见开源协议详解 知识共享许可协议 国产开源木兰协议 代码规范 阿里巴巴 Java开发手册 Google Java 编程风格指南 Twitter Java代码规范 开发流程 软件生命周期与传统模型 结合测试演化的过程模型 敏捷开发项目管理理论 敏捷之极限编程(XP) 敏捷之Scrum Kanban 敏捷实践之测试驱动开发 设计模式 设计模式详解 系统认证 CMMI 认证 等级保护认证 ISO27001认证 产品团队产品团队技术之外 技术之外应该思考什么 个人相关 个人成长和认知 产品相关 产品设计和思考 团队相关 管对管理和成长 其它相关 其它软实力等 关于 ❁导航 ♥面试 ✿导读 JavaJavaJava 面向对象和基础 Java 面向对象基础 Java 基础知识体系 Java进阶 - 集合框架 Java 集合框架详解 Java进阶 - 并发框架 Java 并发知识体系 Java 并发理论基础 Java 并发线程基础 J.U.C 知识体系与详解 Java进阶 - IO框架 Java IO/NIO/AIO详解 Java进阶 - 新版本特性 Java 8 特性详解 Java 8 以上版本特性体系 Java 8 升Java 11特性必读 Java 11 升Java 17特性必读 Java进阶 - JVM相关 Java 类加载机制 Java 字节码和增强技术 JVM 内存结构详解 JVM 垃圾回收机制 Java 调试排错相关 算法算法算法基础和思想 数据结构基础 常见排序算法 算法思想 一些领域算法 安全算法 字符串匹配算法 分布式系统算法 海量数据处理 负载均衡算法 推荐算法 数据挖掘算法 ID生成算法 其它算法相关 头脑风暴 数据库数据库数据库基础和原理 数据库原理 SQL语言 SQL 数据库 MySQL 详解 NoSQL 数据库 Redis 详解 MongoDB 详解 ElasticSearch 详解 开发开发开发 - 常用开发基础 常用类库详解 正则表达式详解 CRON表达式详解 网络协议和工具详解 安全相关详解 开发 - 质量保障 单元测试详解 统一风格详解 质量管理详解 开发 - 代码重构 代码重构相关 SpringSpringSpring Framework(v5.3) Spring框架知识体系 Spring框架组成 控制反转(IOC) 面向切面编程(AOP) SpringMVC SpringBoot系列(v2.5) SpringBoot知识体系 SpringBoot入门 SpringBoot接口设计和实现 SpringBoot集成MySQL SpringBoot集成ShardingJDBC SpringBoot集成Redis SpringBoot集成Postgre SpringBoot集成ElasticSearch SpringBoot集成Socket SpringBoot定时任务 SpringBoot后端视图 SpringBoot监控 SpringBoot进阶 框架中间件框架中间件Web 容器 Tomcat 源码详解 ORM 框架 MyBatis 源码详解 分表分库框架 ShardingSphere 详解 架构架构架构基础和技术点 架构知识体系 从角色视角看架构 从分层视角看架构 从演化视角看架构 从模式视角看架构 高并发之缓存 高并发之限流 高并发之降级和熔断 高可用之负载均衡 高可用之容灾备份 分布式系统 分布式理论和一致性算法 全局唯一ID实现方案 分布式锁及实现方案 分布式事务及实现方案 分布式任务及实现方案 分布式会话及实现方案 微服务系统 微服务系统和设计 系统设计之商业业务平台 秒杀抽奖相关设计 电商交易相关设计 仓储物流相关设计 拉新投放相关设计 其它综合相关设计 系统设计之数据仓库平台 数据库架构相关设计 数据同步相关设计 数据仓库相关设计 数据治理相关设计 工具部署工具部署 开发工具 Git详解 Linux Docker 项目 方法论方法论开发理论 开发原则(SOLID) 分布式理论(CAP) 分布式理论(BASE) 事务理论(ACID) 微服务理论(康威定律) 开源协议 常见开源协议详解 知识共享许可协议 国产开源木兰协议 代码规范 阿里巴巴 Java开发手册 Google Java 编程风格指南 Twitter Java代码规范 开发流程 软件生命周期与传统模型 结合测试演化的过程模型 敏捷开发项目管理理论 敏捷之极限编程(XP) 敏捷之Scrum Kanban 敏捷实践之测试驱动开发 设计模式 设计模式详解 系统认证 CMMI 认证 等级保护认证 ISO27001认证 产品团队产品团队技术之外 技术之外应该思考什么 个人相关 个人成长和认知 产品相关 产品设计和思考 团队相关 管对管理和成长 其它相关 其它软实力等 关于 Spring Framework 5基础

   ♥Spring框架知识体系详解♥ Spring基础 - Spring和Spring框架组成 Spring基础 - Spring简单例子引入Spring要点 Spring基础 - Spring核心之控制反转(IOC) Spring基础 - Spring核心之面向切面编程(AOP) Spring基础 - SpringMVC请求流程和案例 Spring进阶- Spring IOC实现原理详解之IOC体系结构设计 Spring进阶- Spring IOC实现原理详解之IOC初始化流程 Spring进阶- Spring IOC实现原理详解之Bean实例化(生命周期,循环依赖等) Spring进阶 - Spring AOP实现原理详解之AOP切面的实现 Spring进阶 - Spring AOP实现原理详解之AOP代理的创建 Spring进阶 - Spring AOP实现原理详解之Cglib代理实现 Spring进阶 - Spring AOP实现原理详解之JDK代理实现 Spring进阶 - SpringMVC实现原理之DispatcherServlet的初始化过程 Spring进阶 - SpringMVC实现原理之DispatcherServlet处理请求的过程 SpringBoot 2.5.x系列

   ♥SpringBoot 知识体系详解♥ ▶SpringBoot入门 - SpringBoot简介 SpringBoot入门 - SpringBoot HelloWorld SpringBoot入门 - 对Hello world进行MVC分层 SpringBoot入门 - 添加内存数据库H2 SpringBoot入门 - 定制自己的Banner SpringBoot入门 - 添加Logback日志 SpringBoot入门 - 配置热部署devtools工具 SpringBoot入门 - 开发中还有哪些常用注解 ▶SpringBoot接口 - 如何统一接口封装 SpringBoot接口 - 如何对参数进行校验 SpringBoot接口 - 如何参数校验国际化 SpringBoot接口 - 如何统一异常处理 SpringBoot接口 - 如何提供多个版本接口 SpringBoot接口 - 如何生成接口文档之Swagger技术栈 SpringBoot接口 - 如何生成接口文档之集成Smart-Doc SpringBoot接口 - 如何访问外部接口 SpringBoot接口 - 如何保证接口幂等 SpringBoot接口 - 如何对接口进行签名 SpringBoot接口 - 如何实现接口限流之单实例 SpringBoot接口 - 如何实现接口限流之分布式 ▶SpringBoot集成MySQL - 基于JPA的封装 SpringBoot集成MySQL - MyBatis XML方式 SpringBoot集成MySQL - MyBatis 注解方式 SpringBoot集成MySQL - MyBatis PageHelper分页 SpringBoot集成MySQL - MyBatis 多个数据源 SpringBoot集成MySQL - MyBatis-Plus方式 SpringBoot集成MySQL - MyBatis-Plus代码自动生成 SpringBoot集成MySQL - MyBatis-Plus基于字段隔离的多租户 ▶SpringBoot集成ShardingJDBC - Sharding-JDBC简介和基于MyBatis的单库分表 SpringBoot集成ShardingJDBC - 基于JPA的单库分表 SpringBoot集成ShardingJDBC - 基于JPA的读写分离 SpringBoot集成ShardingJDBC - 基于JPA的DB隔离多租户方案 ▶SpringBoot集成连接池 - 数据库连接池和默认连接池HikariCP SpringBoot集成连接池 - 集成数据库Druid连接池 ▶SpringBoot数据库管理 - 用Liquibase对数据库管理和迁移 SpringBoot数据库管理 - 用flyway对数据库管理和迁移 ▶SpringBoot集成PostgreSQL - 基于JPA封装基础数据操作 SpringBoot集成PostgreSQL - 基于MyBatis-Plus方式 SpringBoot集成PostgreSQL - NoSQL特性JSONB的封装 ▶SpringBoot集成Redis - 基于RedisTemplate+Jedis的数据操作 SpringBoot集成Redis - 基于RedisTemplate+Lettuce数据操作 SpringBoot集成Redis - 基于RedisTemplate+Lettuce数据类封装 SpringBoot集成Redis - Redis分布式锁的实现之Jedis(setNXPX+Lua) ▶SpringBoot集成MongoDB - 基于MongoTemplate的数据操作 ▶SpringBoot集成ElasticSearch - 基于ElasticSearchTemplate的数据操作 ▶SpringBoot集成Socket - 基础的Websocket实现 SpringBoot集成Socket - 用Netty实现socket ▶SpringBoot定时任务 - Timer实现方式 SpringBoot定时任务 - ScheduleExecutorService实现方式 SpringBoot定时任务 - Netty HashedWheelTimer方式 SpringBoot定时任务 - Spring Schedule实现方式 SpringBoot定时任务 - 基础quartz实现方式 SpringBoot定时任务 - 分布式quartz cluster方式 SpringBoot定时任务 - 分布式elastic-job方式 SpringBoot定时任务 - 分布式xxl-job方式 ▶SpringBoot集成文件 - 基础的文件上传和下载 SpringBoot集成文件 - 大文件的上传(异步,分片,断点续传和秒传) SpringBoot集成文件 - 集成POI之Excel导入导出 SpringBoot集成文件 - 集成EasyExcel之Excel导入导出 SpringBoot集成文件 - 集成EasyPOI之Excel导入导出 SpringBoot集成文件 - 集成POI之Word导出 SpringBoot集成文件 - 集成POI-tl之基于模板的Word导出 SpringBoot集成文件 - 集成itextpdf之导出PDF ▶SpringBoot后端视图 - 基于Thymeleaf视图解析 ▶SpringBoot集成JavaFX2 - JavaFX 2.0应用 ▶SpringBoot应用部署 - 打包成jar部署 SpringBoot应用部署 - 使用第三方JAR包 SpringBoot应用部署 - 打包成war部署 SpringBoot应用部署 - 替换tomcat为Jetty容器 SpringBoot应用部署 - 替换tomcat为Undertow容器 SpringBoot应用部署 - 在linux环境将jar制作成service SpringBoot应用部署 - docker镜像打包,运行和管理 SpringBoot应用部署 - 使用Docker Compose对容器编排管理 ▶SpringBoot监控 - 集成actuator监控工具 SpringBoot监控 - 集成springboot admin监控工具 ▶SpringBoot进阶 - 实现自动装配原理 SpringBoot进阶 - 自定义starter SpringBoot进阶 - 嵌入web容器Tomcat原理 SpringBoot进阶 - 健康检查Actuator原理 # Spring进阶 - Spring AOP实现原理详解之Cglib代理实现我们在前文中已经介绍了SpringAOP的切面实现和创建动态代理的过程,那么动态代理是如何工作的呢?本文主要介绍Cglib动态代理的案例和SpringAOP实现的原理。@pdai

  Spring进阶 - Spring AOP实现原理详解之Cglib代理实现引入动态代理要解决什么问题?什么是代理?什么是动态代理?什么是Cglib? SpringAOP和Cglib是什么关系?Cglib代理的案例pom包依赖定义实体被代理的类cglib代理使用代理简单测试Cglib代理的流程SpringAOP中Cglib代理的实现示例源码# 引入我们在前文中已经介绍了SpringAOP的切面实现和创建动态代理的过程,那么动态代理是如何工作的呢?本文主要介绍Cglib动态代理的案例和SpringAOP实现的原理。

  要了解动态代理是如何工作的,首先需要了解

  什么是代理模式?什么是动态代理?什么是Cglib?SpringAOP和Cglib是什么关系?# 动态代理要解决什么问题?# 什么是代理?代理模式(Proxy pattern): 为另一个对象提供一个替身或占位符以控制对这个对象的访问

  举个简单的例子:

  我(client)如果要买(doOperation)房,可以找中介(proxy)买房,中介直接和卖方(target)买房。中介和卖方都实现买卖(doOperation)的操作。中介就是代理(proxy)。

  # 什么是动态代理?动态代理就是,在程序运行期,创建目标对象的代理对象,并对目标对象中的方法进行功能性增强的一种技术。

  在生成代理对象的过程中,目标对象不变,代理对象中的方法是目标对象方法的增强方法。可以理解为运行期间,对象中方法的动态拦截,在拦截方法的前后执行功能操作。

  # 什么是Cglib? SpringAOP和Cglib是什么关系?Cglib是一个强大的、高性能的代码生成包,它广泛被许多AOP框架使用,为他们提供方法的拦截。

  最底层是字节码,字节码相关的知识请参考 JVM基础 - 类字节码详解ASM是操作字节码的工具cglib基于ASM字节码工具操作字节码(即动态生成代理,对方法进行增强)SpringAOP基于cglib进行封装,实现cglib方式的动态代理# Cglib代理的案例这里我们写一个使用cglib的简单例子。@pdai

  # pom包依赖引入cglib的依赖包

  

 ?xml version= 1.0 encoding= UTF-8 ? 

 

   project xmlns= http://maven.apache.org/POM/4.0.0

   xmlns:xsi= http://www.w3.org/2001/XMLSchema-instance

   xsi:schemaLocation= http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd

   parent

   artifactId tech-pdai-spring-demos /artifactId

   groupId tech.pdai /groupId

   version 1.0-SNAPSHOT /version

   /parent

   modelVersion 4.0.0 /modelVersion

   artifactId 007-spring-framework-demo-aop-proxy-cglib /artifactId

   properties

   maven.compiler.source 8 /maven.compiler.source

   maven.compiler.target 8 /maven.compiler.target

   /properties

   dependencies

   !-- https://mvnrepository.com/artifact/cglib/cglib --

   dependency

   groupId cglib /groupId

   artifactId cglib /artifactId

   version 3.3.0 /version

   /dependency

   /dependencies

   /project

  

# 定义实体User

 

  

package tech.pdai.springframework.entity;

 

   * @author pdai

  public class User {

   * user s name.

   private String name;

   * user s age.

   private int age;

   * init.

   * @param name name

   * @param age age

   public User(String name, int age) {

   this.name = name;

   this.age = age;

   public String getName() {

   return name;

   public void setName(String name) {

   this.name = name;

   public int getAge() {

   return age;

   public void setAge(int age) {

   this.age = age;

   @Override

   public String toString() {

   return User{ +

   name= + name + \ +

   , age= + age +

  

# 被代理的类即目标类, 对被代理的类中的方法进行增强

 

  

package tech.pdai.springframework.service;

 

  import java.util.Collections;

  import java.util.List;

  import tech.pdai.springframework.entity.User;

   * @author pdai

  public class UserServiceImpl {

   * find user list.

   * @return user list

   public List User findUserList() {

   return Collections.singletonList(new User( pdai , 18));

   * add user

   public void addUser() {

   // do something

  

# cglib代理cglib代理类,需要实现MethodInterceptor接口,并指定代理目标类target

 

  

package tech.pdai.springframework.proxy;

 

  import java.lang.reflect.Method;

  import net.sf.cglib.proxy.Enhancer;

  import net.sf.cglib.proxy.MethodInterceptor;

  import net.sf.cglib.proxy.MethodProxy;

   * This class is for proxy demo.

   * @author pdai

  public class UserLogProxy implements MethodInterceptor {

   * 业务类对象,供代理方法中进行真正的业务方法调用

   private Object target;

   public Object getUserLogProxy(Object target) {

   //给业务对象赋值

   this.target = target;

   //创建加强器,用来创建动态代理类

   Enhancer enhancer = new Enhancer();

   //为加强器指定要代理的业务类(即:为下面生成的代理类指定父类)

   enhancer.setSuperclass(this.target.getClass());

   //设置回调:对于代理类上所有方法的调用,都会调用CallBack,而Callback则需要实现intercept()方法进行拦

   enhancer.setCallback(this);

   // 创建动态代理类对象并返回

   return enhancer.create();

   // 实现回调方法

   @Override

   public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {

   // log - before method

   System.out.println( [before] execute method: + method.getName());

   // call method

   Object result = proxy.invokeSuper(obj, args);

   // log - after method

   System.out.println( [after] execute method: + method.getName() + , return value: + result);

   return null;

  

# 使用代理启动类中指定代理目标并执行。

 

  

package tech.pdai.springframework;

 

  import tech.pdai.springframework.proxy.UserLogProxy;

  import tech.pdai.springframework.service.UserServiceImpl;

   * Cglib proxy demo.

   * @author pdai

  public class ProxyDemo {

   * main interface.

   * @param args args

   public static void main(String[] args) {

   // proxy

   UserServiceImpl userService = (UserServiceImpl) new UserLogProxy().getUserLogProxy(new UserServiceImpl());

   // call methods

   userService.findUserList();

   userService.addUser();

  

# 简单测试我们启动上述类main 函数,执行的结果如下:

 

  

[before] execute method: findUserList

 

  [after] execute method: findUserList, return value: [User{name= pdai , age=18}]

  [before] execute method: addUser

  [after] execute method: addUser, return value: null

  

# Cglib代理的流程我们把上述Demo的主要流程画出来,你便能很快理解

 

  更多细节:

  在上图中,我们可以通过在Enhancer中配置更多的参数来控制代理的行为,比如如果只希望增强这个类中的一个方法(而不是所有方法),那就增加callbackFilter来对目标类中方法进行过滤;Enhancer可以有更多的参数类配置其行为,不过我们在学习上述主要的流程就够了。final方法为什么不能被代理?很显然final方法没法被子类覆盖,当然不能代理了。Mockito为什么不能mock静态方法?因为mockito也是基于cglib动态代理来实现的,static方法也不能被子类覆盖,所以显然不能mock。但PowerMock可以mock静态方法,因为它直接在bytecode上工作,更多可以看Mockito单元测试。(pdai: 通了没?是不是so easy...)# SpringAOP中Cglib代理的实现SpringAOP封装了cglib,通过其进行动态代理的创建。

  我们看下CglibAopProxy的getProxy方法

  

@Override

 

  public Object getProxy() {

   return getProxy(null);

  @Override

  public Object getProxy(@Nullable ClassLoader classLoader) {

   if (logger.isTraceEnabled()) {

   logger.trace( Creating CGLIB proxy: + this.advised.getTargetSource());

   try {

   Class ? rootClass = this.advised.getTargetClass();

   Assert.state(rootClass != null, Target class must be available for creating a CGLIB proxy );

   // 上面流程图中的目标类

   Class ? proxySuperClass = rootClass;

   if (rootClass.getName().contains(ClassUtils.CGLIB_CLASS_SEPARATOR)) {

   proxySuperClass = rootClass.getSuperclass();

   Class ? [] additionalInterfaces = rootClass.getInterfaces();

   for (Class ? additionalInterface : additionalInterfaces) {

   this.advised.addInterface(additionalInterface);

   // Validate the class, writing log messages as necessary.

   validateClassIfNecessary(proxySuperClass, classLoader);

   // 重点看这里,就是上图的enhancer,设置各种参数来构建

   Enhancer enhancer = createEnhancer();

   if (classLoader != null) {

   enhancer.setClassLoader(classLoader);

   if (classLoader instanceof SmartClassLoader

   ((SmartClassLoader) classLoader).isClassReloadable(proxySuperClass)) {

   enhancer.setUseCache(false);

   enhancer.setSuperclass(proxySuperClass);

   enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised));

   enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);

   enhancer.setStrategy(new ClassLoaderAwareGeneratorStrategy(classLoader));

   // 设置callback回调接口,即方法的增强点

   Callback[] callbacks = getCallbacks(rootClass);

   Class ? [] types = new Class ? [callbacks.length];

   for (int x = 0; x types.length; x++) {

   types[x] = callbacks[x].getClass();

   // 上节说到的filter

   enhancer.setCallbackFilter(new ProxyCallbackFilter(

   this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset));

   enhancer.setCallbackTypes(types);

   // 重点:创建proxy和其实例

   return createProxyClassAndInstance(enhancer, callbacks);

   catch (CodeGenerationException IllegalArgumentException ex) {

   throw new AopConfigException( Could not generate CGLIB subclass of + this.advised.getTargetClass() +

   : Common causes of this problem include using a final class or a non-visible class ,

   ex);

   catch (Throwable ex) {

   // TargetSource.getTarget() failed

   throw new AopConfigException( Unexpected AOP exception , ex);

  

获取callback的方法如下,提几个理解的要点吧,具体读者在学习的时候建议把我的例子跑一下,然后打一个断点进行理解。

 

  rootClass: 即目标代理类advised: 包含上文中我们获取到的advisor增强器的集合exposeProxy: 在xml配置文件中配置的,背景就是如果在事务A中使用了代理,事务A调用了目标类的的方法a,在方法a中又调用目标类的方法b,方法a,b同时都是要被增强的方法,如果不配置exposeProxy属性,方法b的增强将会失效,如果配置exposeProxy,方法b在方法a的执行中也会被增强了DynamicAdvisedInterceptor: 拦截器将advised(包含上文中我们获取到的advisor增强器)构建配置的AOP的callback(第一个callback)targetInterceptor: xml配置的optimize属性使用的(第二个callback)最后连同其它5个默认的Interceptor 返回作为cglib的拦截器链,之后通过CallbackFilter的accpet方法返回的索引从这个集合中返回对应的拦截增强器执行增强操作。

private Callback[] getCallbacks(Class ? rootClass) throws Exception {

 

   // Parameters used for optimization choices...

   boolean exposeProxy = this.advised.isExposeProxy();

   boolean isFrozen = this.advised.isFrozen();

   boolean isStatic = this.advised.getTargetSource().isStatic();

   // Choose an aop interceptor (used for AOP calls).

   Callback aopInterceptor = new DynamicAdvisedInterceptor(this.advised);

   // Choose a straight to target interceptor. (used for calls that are

   // unadvised but can return this). May be required to expose the proxy.

   Callback targetInterceptor;

   if (exposeProxy) {

   targetInterceptor = (isStatic ?

   new StaticUnadvisedExposedInterceptor(this.advised.getTargetSource().getTarget()) :

   new DynamicUnadvisedExposedInterceptor(this.advised.getTargetSource()));

   else {

   targetInterceptor = (isStatic ?

   new StaticUnadvisedInterceptor(this.advised.getTargetSource().getTarget()) :

   new DynamicUnadvisedInterceptor(this.advised.getTargetSource()));

   // Choose a direct to target dispatcher (used for

   // unadvised calls to static targets that cannot return this).

   Callback targetDispatcher = (isStatic ?

   new StaticDispatcher(this.advised.getTargetSource().getTarget()) : new SerializableNoOp());

   Callback[] mainCallbacks = new Callback[] {

   aopInterceptor, //

   targetInterceptor, // invoke target without considering advice, if optimized

   new SerializableNoOp(), // no override for methods mapped to this

   targetDispatcher, this.advisedDispatcher,

   new EqualsInterceptor(this.advised),

   new HashCodeInterceptor(this.advised)

   Callback[] callbacks;

   // If the target is a static one and the advice chain is frozen,

   // then we can make some optimizations by sending the AOP calls

   // direct to the target using the fixed chain for that method.

   if (isStatic isFrozen) {

   Method[] methods = rootClass.getMethods();

   Callback[] fixedCallbacks = new Callback[methods.length];

   this.fixedInterceptorMap = CollectionUtils.newHashMap(methods.length);

   // TODO: small memory optimization here (can skip creation for methods with no advice)

   for (int x = 0; x methods.length; x++) {

   Method method = methods[x];

   List Object chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, rootClass);

   fixedCallbacks[x] = new FixedChainStaticTargetInterceptor(

   chain, this.advised.getTargetSource().getTarget(), this.advised.getTargetClass());

   this.fixedInterceptorMap.put(method, x);

   // Now copy both the callbacks from mainCallbacks

   // and fixedCallbacks into the callbacks array.

   callbacks = new Callback[mainCallbacks.length + fixedCallbacks.length];

   System.arraycopy(mainCallbacks, 0, callbacks, 0, mainCallbacks.length);

   System.arraycopy(fixedCallbacks, 0, callbacks, mainCallbacks.length, fixedCallbacks.length);

   this.fixedInterceptorOffset = mainCallbacks.length;

   else {

   callbacks = mainCallbacks;

   return callbacks;

  

可以结合调试,方便理解

 

  # 示例源码https://github.com/realpdai/tech-pdai-spring-demos

   我要纠错 Spring进阶 - Spring AOP实现原理详解之AOP代理的创建 Spring进阶 - Spring AOP实现原理详解之JDK代理实现

  苏ICP备19053722号 pdai copyright © 2017-present Spring进阶 - Spring AOP实现原理详解之Cglib代理实现 引入 动态代理要解决什么问题? 什么是Cglib? SpringAOP和Cglib是什么关系? Cglib代理的案例 pom包依赖 定义实体 被代理的类 cglib代理 使用代理 简单测试 Cglib代理的流程 SpringAOP中Cglib代理的实现 示例源码 【双11】腾讯云服务器Java全栈读者专享
2核2G,4M,40GB, 50元/1年 查看2核4G,6M,60GB, 100元/1年 查看4核8G,10M,100GB, 300元/1年 查看目录Spring进阶 - Spring AOP实现原理详解之Cglib代理实现 引入 动态代理要解决什么问题? 什么是Cglib? SpringAOP和Cglib是什么关系? Cglib代理的案例 pom包依赖 定义实体 被代理的类 cglib代理 使用代理 简单测试 Cglib代理的流程 SpringAOP中Cglib代理的实现 示例源码 手机看微信扫一扫
可以手机看或分享至朋友圈
全屏看左栏交流圈添加pdai微信进《Java全栈知识体系》学习交流圈「无任何套路」 PS:添加时请备注Java全栈,谢谢! 下资料扫描公众号,回复“资料”下载10GB+书籍资料「无任何套路」公众号: Java全栈知识体系
支持我鼓励/支持/赞赏我
1. 不靠它生存但仍希望得到你的鼓励;
2. 时刻警醒自己保持技术人的初心,恒心,简单,利他;
(点击右侧❤️可以查看赞赏榜单和用途)
面试
上一篇
下一篇站点图 关于我 关于站点 最近更新记录问题反馈常用搜索百度 Google Bing Github 搜代码 技术社区CSDN OSChina 知否 掘金 Linux公社 IBM 开发者 StackOverflow Java相关面向对象基础语法基础集合框架并发基础并发关键字JUC并发框架IO框架Java8 特性JVM基础调试排错更多资源算法相关数组与线性表树详解图详解内部排序算法思想安全算法大数据处理分布式算法负载均衡算法推荐算法头脑风暴数据库相关数据库原理SQL语言MySQL相关MongoDBElasticSearch开发基础相关常用类库单元测试正则表达式网络协议安全相关常见重构技巧架构相关架构基础架构视角架构演进架构模式和要素高并发之缓存高并发之限流高并发之降级负载均衡容灾备份架构安全秒杀系统设计架构案例工具和部署工具集合IDE相关GitMavenLinuxDocker方法论SOLIDCAPBASE开源协议代码规范设计模式产品和团队产品相关团队相关其它分享

  以上就是Spring进阶(spring的入门程序详细过程)的详细内容,想要了解更多 Spring进阶的内容,请持续关注盛行IT软件开发工作室。

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: