Spring AOP源码分析

Spring源码分析之AOP Spring AOP原理 Spring AOP源码。Spring AOP源码详解 阅读详情

Spring AOP源码分析

看下Spring核心的代理类

AbstractAutoProxyCreator  这是Spring核心的一个代理类,他的子类:

 

接口: BeanFactoryAware 的作用

初始化之前执行一个方法:

 

@Override
    public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) {
        Object cacheKey = getCacheKey(beanClass, beanName);

        if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) {
            if (this.advisedBeans.containsKey(cacheKey)) {
                return null;
            }
            if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
                this.advisedBeans.put(cacheKey, Boolean.FALSE);
                return null;
            }
        }

        // Create proxy here if we have a custom TargetSource.
        // Suppresses unnecessary default instantiation of the target bean:
        // The TargetSource will handle target instances in a custom fashion.
        TargetSource targetSource = getCustomTargetSource(beanClass, beanName); //通过BeanClass和BeanName找到目标来源
        if (targetSource != null) {
            if (StringUtils.hasLength(beanName)) { 
                this.targetSourcedBeans.add(beanName);
            }
            Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
            Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);  //创建一个代理对象
            this.proxyTypes.put(cacheKey, proxy.getClass());
            return proxy;
        }

        return null;
    }
createProxy(beanClass, beanName, specificInterceptors, targetSource); 点击进入
这是做代理的:
protected Object createProxy(Class<?> beanClass, @Nullable String beanName,
            @Nullable Object[] specificInterceptors, TargetSource targetSource) {

        if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
            AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
        }

        ProxyFactory proxyFactory = new ProxyFactory();
        proxyFactory.copyFrom(this);

        if (!proxyFactory.isProxyTargetClass()) {
            if (shouldProxyTargetClass(beanClass, beanName)) {
                proxyFactory.setProxyTargetClass(true);
            }
            else {
                evaluateProxyInterfaces(beanClass, proxyFactory);
            }
        }

        Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);  //切入点的管理
        proxyFactory.addAdvisors(advisors);
        proxyFactory.setTargetSource(targetSource);
        customizeProxyFactory(proxyFactory);

        proxyFactory.setFrozen(this.freezeProxy);
        if (advisorsPreFiltered()) {  
            proxyFactory.setPreFiltered(true);
        }

        return proxyFactory.getProxy(getProxyClassLoader());
    }

进入方法:  return proxyFactory.getProxy(getProxyClassLoader());

public Object getProxy(@Nullable ClassLoader classLoader) {
        return createAopProxy().getProxy(classLoader);
    }

查看:两个代理方式

看下jdk的动态代理:

    @Override
    public Object getProxy(@Nullable ClassLoader classLoader) {
        if (logger.isTraceEnabled()) {
            logger.trace("Creating JDK dynamic proxy: " + this.advised.getTargetSource());
        }
        Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true); //通过反射生成代理类
        findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
        return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
    }

cglib:这个是不需要反射的哦 通过字节码

@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 (ClassUtils.isCglibProxyClass(rootClass)) {       //进行代理
                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);

            // Configure CGLIB 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 ClassLoaderAwareUndeclaredThrowableStrategy(classLoader));

            Callback[] callbacks = getCallbacks(rootClass);
            Class<?>[] types = new Class<?>[callbacks.length];
            for (int x = 0; x < types.length; x++) {
                types[x] = callbacks[x].getClass();
            }
            // fixedInterceptorMap only populated at this point, after getCallbacks call above
            enhancer.setCallbackFilter(new ProxyCallbackFilter(
                    this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset));
            enhancer.setCallbackTypes(types);

            // Generate the proxy class and create a proxy instance.
            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);
        }
    }
protected Object createProxyClassAndInstance(Enhancer enhancer, Callback[] callbacks) {
        enhancer.setInterceptDuringConstruction(false);
        enhancer.setCallbacks(callbacks);
        return (this.constructorArgs != null && this.constructorArgTypes != null ?
                enhancer.create(this.constructorArgTypes, this.constructorArgs) :   //查看此方法
                enhancer.create());  
    }

点进去查看:

public Object create(Class[] argumentTypes, Object[] arguments) {
        classOnly = false;
        if (argumentTypes == null || arguments == null || argumentTypes.length != arguments.length) {
            throw new IllegalArgumentException("Arguments must be non-null and of equal length");
        }
        this.argumentTypes = argumentTypes;
        this.arguments = arguments;
        return createHelper();  //创建Helper  点进去就是代理
    }

 

 查看:

    private Object createHelper() {
        preValidate();
        Object key = KEY_FACTORY.newInstance((superclass != null) ? superclass.getName() : null,
                ReflectUtils.getNames(interfaces),
                filter == ALL_ZERO ? null : new WeakCacheKey<CallbackFilter>(filter),
                callbackTypes,
                useFactory,
                interceptDuringConstruction,
                serialVersionUID);
        this.currentKey = key;
        Object result = super.create(key);
        return result;
    }

 

看下CglibAopProxy:

  

 

适配器,有好多中。我们可以通过debug去获取查看。

也可以参考这个博客:https://www.cnblogs.com/lulu638/p/4474698.html

 

 

posted @ 2019-04-20 01:45 toov5 阅读(...) 评论(...) 编辑 收藏

Spring的aop源码分析 Spring的aop源码解析 阅读详情

相关推荐

Spring AOP实现流程、源码分析

前言 AOP字面意思解释就是面向切面编程,面向切面编程是一种编程模型,我们知道JAVA是面向对象的也就是OOP,OOP这种面向对象的编程适用于定义纵向的关系,但是并不适用定义横向的关系。那么应对这种OOP的存在的这些不利,AOP面向切面的编程模型作为面向对象的一种补充,用于将那些与业务无关,但却对多个对象产生影响的公共行为和逻辑,抽取并封装为一个可重用的模块,这个模块被命名为“切面”(Aspect),减少系统中的重复代码,降低了模块间的耦合度,同时提高了系统的可维护性。可用于权限认证、日志、事务处理。 AO

程序员劝退师的博客 1032

动态代理详解之JDK与CGLib

针对 Java 常用的两种代理方式进行解析,从 Java 源码的角度看实现过程(个人总结,不足之处,万望海涵)

Blank_JK的博客 1059

spring aop源码分析

什么是AOP 面试中经常被问到什么是AOP,其实AOP是一种技术实现,或者说是一种实现标准,实现AOP的技术有多种,但是通常所说的AOP,大家会不自觉的想到spring aop,因为spring aop被问了很多次。本文想从源码的执行流程上来简单说说AOP的实现原理。 AOP底层技术实现 aop的底层技术其实就是大家熟知的代理,spring aop中的代理主要有两种,cglib代理和JDK动态代理...

congge 988

解决 Unexpected AOP exception; nested exception is java.lang.IllegalStateException: Unable to load..错误

错误日志: nested exception is org.springframework.aop.framework.AopConfigException: Unexpected AOP exception; nested exception is java.lang.IllegalStateException: Unable to load cache item at org.springframework.beans.factory.support.AbstractAutowireCapableB

BUG粉碎机 1万+

营销反作弊之 异常行为分析模型(一),附带python代码

通过对用户行为进行深入的分析,识别出与常规模式不符的异常行为,可以有效检测并阻止虚假广告点击、刷单、点击欺诈等欺诈行为。本文将详细探讨营销反欺诈中异常行为分析的方法,介绍如何通过数据采集、清洗、行为建模与异常检测,准确识别潜在的欺诈行为,并提供 Python 实现代码示例。**监督学习 (Supervised Learning):**在标注数据的帮助下,训练机器学习模型使其能预测未知数据的结果。营销反欺诈异常行为分析的整体流程涉及多个环节,确保通过对用户行为的深入分析,及时识别潜在的欺诈行为。

viviwiky的博客 1230

微信小程序使用ucharts折线图,有负数显示0刻度线

当数据有负数和正数的时候默认不会显示0刻度线,不方便看出正负对比。

欢迎来到我的博客!在这里,我将分享我在前端开发方面的知识和经验。让我们一起探索前端开发的无限可能! 1581

spring源码系列---AOP

@EnableAspectJAutoProxy 开启aop @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Import(AspectJAutoProxyRegistrar.class) public @interface EnableAspectJAutoProxy { /** * Indicate whether subclass-based (CGLIB) proxies are to b

性格的大表哥 287

Exposure Fusion

MertensTMO原理详解: 文章:2007年Exposure Fusion 论文链接:http://ntp-0.cs.ucl.ac.uk/staff/j.kautz/publications/exposure_fusion.pdf 论文代码:C版本:https://github.com/JawThrow/ExposureFusion python版本:https://github.com/lzocro/Exposure-Fusion matlab版本:https://github.com/Mericam

大长腿不解释 1652

JAVA静态/动态代理实现

全文介绍了JAVA动态代理的相关内容,如有错误敬请指正。一.从常规编码方式说起二.代理模式介绍 一.从常规编码方式说起 在介绍动态代理之前,让我们先回顾一下一种常见的编码方式: 1.首先定义一个接口,接口定义一个code方法 public interface DevelopService { //编码 void code(String content); } 2.编写实现类 public class DevelopServiceImpl implements DevelopService

lizihaoaa的博客 261

window部署open claw(使用wsl-Ubuntu-docker部署)

本文详细介绍了在Windows 11系统下通过WSL2+Docker部署OpenClaw的完整流程。首先需要满足硬件配置要求并开启虚拟化功能,然后依次完成WSL2安装配置、Docker Desktop安装、OpenClaw镜像拉取等步骤。重点说明了端口映射、socat转发配置及openclaw.json文件修改方法。最后通过验证WSL2内网IP和端口访问服务。该方案具有最佳兼容性,能有效避免Windows环境下的依赖冲突问题。

Kmoyic的博客 2763

HBase骚操作之数据加载方式BulkLoad

本文研究了一种HBase BulkLoad的入库方式,该方式利用HBase的数据信息按照特定格式存储在hdfs内这一原理,直接在HDFS中生成持久化的HFile数据格式文件,然后上传至合适位置,即完成巨量数据快速入库的办法。该方式配合MapReduce完成,高效便捷,而且不占用Region资源,增添负载,在大数据量写入时能极大的提高写入效率,并降低对Hbase节点的写入压力。HBase BulkLoad对于异构数据源的合并及大量数据一次性导入具有重要指导意义,相比HBase Put操作在性能上具有较高的优势

石榴姐yyds 7789

Spring Aop初始化源码分析

1 工程简介 1.1 pom <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.tar

qq_34125999的博客 4613

【在 WSL2 GUI 中使用 pulseaudio 播放声音】

最近在搞一个Linux项目,由于WSL2中需要用到声音外放,无奈只能潜心研究。后来就使用了一种折中的方式替代,那就是pulseaudio。目前来讲WSL2对硬件外设的支持还是不太友好,关于USB的支持我之前在其他文章中已经论述过了,这里不讨论。1、Windows11别忘记打开声音2、可能有一定延迟,因为是通过网络传输的。3、效果的话只能见仁见智了,如果不能满足要求就安装一个实实在在的Ubuntu吧!

jiexijihe945的博客 4531

Spring框架AOP源码分析

Spring框架AOP源码分析 1.写在前面 做java开发的不可能不适用spring框架,我们都知道spring框架的两个基础功能就是Ioc和aop,相比来说Ioc会应用的更广泛一些,但aop同样重要,今天就来详细分析一下spring的aop的实现原理,会深入spring源码级别,对于spring不太熟悉的同学来说可能有点难,没有办法,分析源码就是这样,需要对框架有一定的应用经验并且比较熟悉原理,毕竟一个成熟的框架,特别是像spring这样的java技术栈统治级的框架。如果想学习spring的基本功能推荐

ChirsPaul3的博客 338

【WorkBuddy专栏39】零基础也能做小程序——WorkBuddy微信小程序开发完全指南

【WorkBuddy专栏39】零基础也能做小程序——WorkBuddy微信小程序开发完全指南

AI人人懂 3160

〔重庆理工大学〕计算机组成原理课设报告--16位单周期CPU设计

本课程设计的实验平台为Altera Quartus II 软件和Altera Cyclone V Starter 工具箱。(1)Cyclone V是Altera FPGAs家族的一类,它面向低功耗应用。Cyclone V GX 5CGXFC5C6F27C7N 芯片有不同的转换器,按钮,LED灯,七段显示器,HDMI接口,SD卡读卡器以及其他链接等。Cyclone V GX 5CGXFC5C6F27C7N是Starter工具箱的重要组件。(2)测试台包含在测设备(DUT)和用于仿真的模拟输入。

Pretty Boy Fox的博客 1066

最详细的Spring Aop源码分析

转载自: https://javadoop.com/post/spring-aop-source 之前写过 IOC 的源码分析,那篇文章真的有点长,看完需要点耐心。很多读者希望能写一写 Spring AOP 的源码分析文章,这样读者看完 IOC + AOP 也就对 Spring 会有比较深的理解了。今天终于成文了,可能很多读者早就不再等待了,不过主要为了后来者吧。 本文不会像 IOC 源码分析...

qq_33285543的博客 389

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

Spring AOP介绍及源码分析

Spring AOP介绍及源码分析   spring4.0源码分析━━━(AOP实现)

wanxiaotao12-126-com 152

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

Spring AOP 原理源码分析

目录准备工作从@EnableAspectJAutoProxy看起AnnotationAwareAspectJAutoProxyCreator创建过程AnnotationAwareAspectJAutoProxyCreator的执行时机创建AOP代理获取拦截器链小结 准备工作 在这里我先简单记录下如何实现一个aop: AOP:【动态代理】 指在程序运行期间动态的将某段代码切入到指定方法指定位置进行运行的编程方式; 1、导入aop模块;Spring AOP:(spring-aspe

BOOM0BOOM的博客 282

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

spring中AOP源码分析

spring中aop动态代理源码分析

m0_37938849的博客 280

spring (四)AOP源码分析 五种通知的执行顺序

之前面的时候被问到有没有了解AOP的增强,当时我一脸懵逼 ,什么是增强?后来查了下,增强也就时通知。 通知的执行顺序 1、首先是目标方法没有异常的情况: 环绕通知、前置通知、目标方法、环绕通知,后置通知、返回通知 2、目标方法有异常的顺序: 环绕通知、前置通知、目标方法、后置通知、异常通知 所以各通知执行时机为 @Around:环绕通知:前置通知之前执行proceed方法之前的部分 @Before:前置通知,目标方法之前执行 @Around:环绕通知:目标方法执行之后执行proceed方法之后的部分 @Af

Ethan_199402的博客 3715

Spring AOP 源码分析

AOP 面向切面编程,全称 Aspect Oriented Programming ,它是 OOP 的补充,OOP关注的是对象,而AOP的核心是切面(Aspect)。AOP可以在不修改功能代码的本身的前提下,使用运行时代理的技术对已有代码逻辑增强。AOP可以实现组件化,可插拔式的功能扩展,通过简单配置功能增强到指定的切入点。

程序猿进阶 2872

Spring AOP(六)【源码分析】Spring中CgLib动态代理的实现

CgLib中AOP的实现是基于org.springframework.cglib.proxy包中Enhancer和MethodInterceptor(是CgLib包中的)两个接口来实现的。创建增强器Enhancer,并配置其callback为自定义的MethodInterceptor,然后创建代理。其中的代理逻辑与jdk相似,都是通过链式拦截器实现。

sun_tantan的博客 1037
上一篇: Spring Boot
下一篇: SpringBoot基础的使用
Art&Code
博客等级 码龄7年 77粉丝 554原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值