Spring AOP---深入剖析AOP注解实现原理

9 篇文章 28 订阅
订阅专栏

前言

阅读本文之前建议先掌握的前置知识:

  • @Import注解的使用和实现原理
  • Bean的生命周期

1.概述

Spring AOP有常用的两种方式,一种是使用XML的方式,另一种是使用注解的方式。本文将详细的分析注解方式的实现原理。将会从如下几个点展开。

  • Spring如何集成AspectJ AOP
  • AOP通知链如何形成
  • 何时进行AOP动态代理以及动态代理的方式
  • 通知链的调用过程

用于调试的代码如下:

代码远程仓库地址:https://gitee.com/gongsenlin/aoptest/tree/master

//启动类
package hdu.gongsenlin.aoptest;

import hdu.gongsenlin.aoptest.service.UserService;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class AoptestApplication {

    public static void main(String[] args) {
        AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(Appconfig.class);
        // jdk
//        MyService a = (MyService) ac.getBean("userService");
//        a.query();
        //cglib
        UserService a = ac.getBean(UserService.class);
        a.query();
    }

}
//配置类
package hdu.gongsenlin.aoptest;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.stereotype.Component;

/**
 * @author gongsenlin
 * @version 1.0
 * @date 2021-4-22 19:59
 */
@Configuration
@ComponentScan("hdu.gongsenlin.aoptest")
@EnableAspectJAutoProxy
public class Appconfig {
}

//切面类1
package hdu.gongsenlin.aoptest.aop;

import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
import org.springframework.core.Ordered;

/**
 * @author gongsenlin
 * @version 1.0
 * @date 2021-4-22 20:00
 */
@Aspect
@Component
public class Aop{


    @Pointcut("execution(* hdu.gongsenlin.aoptest.service..*.*(..))")
    private void pointcut(){}

    @Pointcut("execution(* hdu.gongsenlin.aoptest.controller..*.*(..))")
    private void pointcut2(){}

    @Before("pointcut()")
    public void beforeAdvice(){
        System.out.println("前置增强1");
    }

    @Before("pointcut()")
    public void abeforeAdvice(){
        System.out.println("前置增强2");
    }

    @After("pointcut()")
    public void afterAdvice(){
        System.out.println("后置增强1");
    }

    @After("pointcut2()")
    public void afterAdvice2(){
        System.out.println("后置增强2");
    }

}

//业务类
package hdu.gongsenlin.aoptest.service;

import org.springframework.stereotype.Component;

/**
 * @author gongsenlin
 * @version 1.0
 * @date 2021-4-22 19:59
 */
@Component
public class UserService implements MyService {

    @Override
    public void query(){
        System.out.println("query do");
    }

    @Override
    public void f() {

    }
}

public interface MyService {

    void f();

    void query();
}

2.Spring如何集成AspectJ AOP

主要是@EnableAspectJAutoProxy注解的作用。

该注解是一个复合注解,如下所示:
在这里插入图片描述
@Import注解可以注入一个类到Spring容器当中,在之前的博客中详细介绍过该注解的作用,博客地址如下:

《Spring中@Import注解的使用和实现原理》

ConfigurationClassPostProcessor解析启动时候的配置类Appconfig

由于Appconfig的注解中包含了@Import注解,那么会将@Import注解中的类 先缓存到Appconfig配置类的importBeanDefinitionRegistrars集合中。
在这里插入图片描述
ConfigurationClassPostProcessor扫描完了所有的类,执行加载和注册beanDefinition的时候

此时如果该类中包含了ImportBeanDefinitionRegistrar

那么会调用该类的registerBeanDefinitions方法进行注册beanDefinition。

也就来到了AspectJAutoProxyRegistrar中的registerBeanDefinitions方法。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

该方法的作用就是将AnnotationAwareAspectJAutoProxyCreator注册到容器当中,这个类是Spring AOP的关键。

此时Spring中就有了Aspect AOP的功能

Spring是需要手动添加@EnableAspectJAutoProxy注解进行集成的,而SpringBoot中使用自动装配的技术,可以不手动加这个注解就实现集成。

在org/springframework/boot/spring-boot-autoconfigure/2.1.7.RELEASE/spring-boot-autoconfigure-2.1.7.RELEASE.jar!/META-INF/spring.factories中,添加了AopAutoConfiguration,AopAutoConfiguration中加上了@EnableAspectJAutoProxy注解。

有了AopAutoConfiguration配置类,后续的解析配置类的逻辑就和Spring是一样的了。

SpringBoot如何实现自动注入,可以参考博客 《SpringBoot自动装配原理分析和实现自定义启动器》
在这里插入图片描述
在这里插入图片描述

3.AOP通知链如何生成

了解Bean的生命周期的读者,一定清楚BeanPostProcessor接口的postProcessAfterInitialization方法。

AspectJAwareAdvisorAutoProxyCreator实现了BeanPostProcessor该接口,所以在每个Bean的生命周期中,都会执行AspectJAwareAdvisorAutoProxyCreator的postProcessAfterInitialization方法。
在这里插入图片描述
在这里插入图片描述
来到父类中AbstractAutoProxyCreator中的postProcessAfterInitialization。只有当earlyProxyReferences集合中不存在cacheKey的时候,才会执行wrapIfNecessary方法。该集合的作用在之前的博客中也说明了。

SpringAOP对象生成的时机有两个,一个是提前AOP,提前AOP的对象会被放入到earlyProxyReferences集合当中,若没有提前AOP那么会在Bean的生命周期的最后执行postProcessAfterInitialization的时候进行AOP动态代理。这一部分知识不清楚的读者可以阅读博客 《Spring IOC—AOP代理对象生成的时机》。

没有进行AOP的对象会执行wrapIfNecessary方法,该方法中会去寻找通知链,若存在匹配的通知链,那么会进行AOP动态代理。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
调用findCandidateAdvisors方法 得到所有的候选通知

然后调用findAdvisorsThatCanApply方法进行过滤,判断是否可以作用于当前Bean的增强处理。
在这里插入图片描述
调用父类的findCandidateAdvisors方法是加载使用XML方式配置的AOP声明,此处不讨论。

下面会调用aspectJAdvisorsBuilder的buildAspectJAdvisors方法去加载注解方式配置的AOP声明。
在这里插入图片描述
在这里插入图片描述
第一次进来的时候,此时缓存还是为空的,那么会进第一个if,从容器中拿到所有的beanName。

遍历BeanName,得到其对应的对象类型,调用 this.advisorFactory.isAspect(beanType)判断该类是否是切面类,也就是判断是否加了@Aspect注解。

在这里插入图片描述
是切面类的话,判断切面类的PerClause是否是Singleton,正常来说是的,接着构建用于生成通知链的工厂对象。然后基于该工厂对象生产通知链,调用this.advisorFactory.getAdvisors(factory)方法
在这里插入图片描述
getAdvisorMethods 获得类中所有的方法(包含父类的方法),pointCut方法除外。

遍历这些方法,判断是否是通知,构建通知并添加到通知链当中。

解析切面类中的成员变量,判断是否加了@DeclareParents注解,构建DeclareParentsAdvisor。

每个advisors中都包含了PointCut切点相关的内容。

测试代码得到的通知链结果如下:
在这里插入图片描述
回到BeanFactoryAspectJAdvisorsBuilder中的buildAspectJAdvisors方法。
在这里插入图片描述
如果这个切面bean是一个单例,那么将得到的通知链放入advisorsCache缓存当中,beanName作为key,通知链作为value。如果切面bean不是单例的,那么将用于构建通知链的工厂放入aspectFactoryCache缓存当中,beanName作为key,构建通知链的工厂作为value。

之后再访问BeanFactoryAspectJAdvisorsBuilder中的buildAspectJAdvisors方法的时候,直接根据beanName拿到对应的缓存即可。

目前拿到的通知链是还没有经历过匹配筛选的,方法来到AbstractAdvisorAutoProxyCreator中的findEligibleAdvisors方法
在这里插入图片描述
findCandidateAdvisors()方法返回的是候选的通知链,下面需要对里面的通知进行筛选,可以匹配上切点定义的通知才可以作用到当前的Bean上。

调用findAdvisorsThatCanApply方法进行通知链的匹配,匹配规则就根据切点中的execution表达式
在这里插入图片描述
候选通知原本有4个,筛选后,满足条件的仅有3个。其中afterAdvice2方法描述的通知所对应的切点表达式和当前加载的bean匹配不上。
在这里插入图片描述
筛选完之后,在调用extendAdvisors 添加一个ExposeInvocationInterceptor拦截器,用于再通知链的任意一环得到MethodInvocation对象。具体的作用下面会说明。

最后对通知进行排序,至此就得到了用于增强的通知链。

以上就是通知链的构建过程。简单来说就是遍历所有的类,判断类上是否加了@Aspect注解,对加了该注解的类再判断其拥有的所有方法,对于加了通知注解的方法构建出Advisor通知对象放入候选通知链当中。接着基于当前加载的Bean筛选通知,添加ExposeInvocationInterceptor拦截器,最后对通知链进行排序,得到最终的通知链。测试代码得到的最终通知链结果如下:
在这里插入图片描述

4.何时进行AOP动态代理以及动态代理的方式

上一节中得到了用于增强的通知链后,代码定位到AbstractAutoProxyCreator中的wrapIfNecessary方法
在这里插入图片描述
第一个红色框框得到的结果是完整的通知链,第二个红色框框就是进行动态代理的地方了。下面来看看createProxy做了些什么。
在这里插入图片描述
构建ProxyFactory代理工厂,判断使用JDK动态代理还是使用CGLib动态代理

设置代理工厂的一些属性,例如通知链,被代理对象等。

然后调用工厂的getProxy方法得到代理对象。
在这里插入图片描述
基于工厂属性的设置,调用createAopProxy()得到不同的对象。
在这里插入图片描述
AOP的代理方式有两种,一种是Cglib代理,使用ObjenesisCglibAopProxy来创建代理对象,另一种是JDK动态代理,使用JdkDynamicAopProxy来创建代理对象。

都是调用其getProxy方法。

  • 使用ObjenesisCglibAopProxy创建代理对象

    ObjenesisCglibAopProxy继承自CglibAopProxy,getProxy方法来自父类,如下
    在这里插入图片描述
    构建Enhancer对象,设置属性。我们比较关心的通知链也被设置在Enhancer对象当中。
    在这里插入图片描述
    最后调用createProxyClassAndInstance得到基于Cglib动态代理的对象。

  • 使用JdkDynamicAopProxy创建代理对象

    此时修改一下测试代码中的UserService,让它实现一个接口。这样就会走JDK的动态代理。重新调试

    getProxy代码如下: ​在这里插入图片描述
    这就是比较熟悉的JDK动态代理的方式了。JdkDynamicAopProxy本身也实现了InvocationHandler。所以这里newProxyInstance第三个参数传入的是自身。下一节再来看具体的调用链的执行过程。

5.通知链的调用过程

通过java自带的工具HSDB,可以查看动态生成的类的源代码。

  • JDK动态代理生成的类
    在这里插入图片描述
    在这里插入图片描述
    query方法内调用了父类中的InvocationHandler的invoke,也就是调用了JdkDynamicAopProxy中的invoke方法。JdkDynamicAopProxy实现了InvocationHandler接口。

    invoke方法如下:
    在这里插入图片描述
    在这里插入图片描述

  1. SpringAOP不会对equals和hashCode方法进行增强,除非这两个方法是定义在接口中的。
  2. 这两个还没有理解,清楚的读者可以分享一下,感谢!在这里插入图片描述
  3. 判断是否暴露代理对象,默认是false可以设置为true,如果暴露的话,那么在同一个线程中的任意地方都可以通过AopContext获取该代理对象。
  4. 获取方法对应的通知链,此时的通知链应该说是拦截器链,对于原来的Advisor都装饰成了MethodInterceptor。如果为空,那么直接反射调用目标方法,如果不为空,那么会构建一个MethodInvocation对象,调用该对象的proceed()方法执行拦截器链以及目标方法的调用过程。
  • CGLib生成的代理类如下:
    在这里插入图片描述
    在这里插入图片描述
    query方法内调用CGLIB C A L L B A C K 0 的 i n t e r c e p t 方 法 , C G L I B CALLBACK_0的intercept方法,CGLIB CALLBACK0interceptCGLIBCALLBACK_0如下
    在这里插入图片描述
    也就是调用了DynamicAdvisedInterceptor的Intercept
    在这里插入图片描述
    和jdk的动态代理类似,最后都会构建一个MethodInvocation 然后调用它的proceed()方法。
    在这里插入图片描述
    无论是JDK还是CGLib的方式,都会调用MethodInvocation的proceed方法,首先回来代码会来到ReflectiveMethodInvocation中的proceed。该类中维护了一个索引currentInterceptorIndex,用来表示当前访问的是第几个拦截器。
    第一个if是判断所有的拦截器是否都已经访问完,如果是的话,则反射调用目标方法。
    基于currentInterceptorIndex索引拿到当前的拦截器 判断拦截器的类型选择调用拦截器的invoke方法。
    首先来看一下现在的拦截器链的组成
    在这里插入图片描述
    第一个是用于暴露MethodInvocation用的,将MethodInvocation放入ThreadLocal中,同一线程的任何地方都可以得到。
    ExposeInvocationInterceptor的invoke方法如下:
    在这里插入图片描述
    暴露MethodInvocation然后调用MethodInvocation的proceed(),也就又回到了
    在这里插入图片描述
    此时的索引比刚才多了1,拿到了第二个拦截器
    第二个拦截器是MethodBeforeAdviceInterceptor,里面包含了MethodBeforeAdvice前置通知。之所以这样做,是起到了适配器的作用,外部调用都是通过invoke方法即可。
    invoke方法如下:
    在这里插入图片描述
    在这里插入图片描述
    内部调用了前置通知的before方法,完成前置通知的逻辑。
    接着还是调用MethodInvocation的proceed方法。
    currentInterceptorIndex索引下标拿到第三个,第三个也是前置通知,这里就不看了。第四个是后置通知
    在这里插入图片描述
    后置通知的话,先执行MethodInvocation的proceed方法,然后再进行该通知的逻辑。
    遍历完所有的后置通知,就会执行目标的方法,然后再回过来执行finally代码块中的后置通知的逻辑。

6.后续

下一篇博客将探究SpringAOP使用时的注意事项。

例如:同一个切面类中的多个同类型的通知的排列顺序,不同切面类中的同类型的通知的排列顺序等。

AOP如何实现及实现原理
weixin_34224941的博客
11-23 5043
概述: 最近在开发中遇到了一个刚好可以用AOP实现的例子,就顺便研究了AOP实现原理,把学习到的东西进行一个总结。文章中用到的编程语言为kotlin,需要的可以在IDEA中直接转为java。 这篇文章将会按照如下目录展开: AOP简介 代码中实现举例 AOP实现原理 部分源码解析 1. AOP简介 相信大家或多或少的了解过AOP,都知道它是面向切面编程,在网上搜索可以找到很多的解释。这里我用...
Spring AOP实现原理
冷漠的小猿
12-18 575
前言 在以前的项目中,很少去关注Spring AOP实现原理,只是简单了解了一下什么是AOP具体怎么用,本篇将不介绍其使用方法,主要其实如何实现的(即实现原理是什么)。 AOP的原理 AOP 指的是面向切面编程,就是在不改变源码的基础上横向扩展一些功能,主要应用场景有事务管理、日志、缓存等等。其实现的关键在于AOP框架自动创建的AOP代理,如图所示↓↓ 下面我们就以最经典的转账操作进行事务管理...
spring注解实现原理
03-23
NULL 博文链接:https://zxf-noimp.iteye.com/blog/1071765
Spring AOP + 注解实现统一注解功能
08-27
本文我们通过Spring AOPJava的自定义注解来实现日志的插入功能,非常不错,具有一定的参考借鉴价值,需要的朋友一起看看吧
spring-aop-annotation-log-all
07-28
这里zip压缩包囊括了学习Spring过程中用到的所有的jar包; 有: commons-logging-1.2.jar spring-beans-4.0.4.RELEASE.jar spring-context-4.0.4.RELEASE.jar spring-core-4.0.4.RELEASE.jar spring-expression-4.0.4.RELEASE.jar spring-aop-4.0.4.RELEASE.jar com.springsource.net.sf.cglib-2.2.0.jar com.springsource.org.aopalliance-1.0.0.jar com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar spring-aspects-4.1.2.RELEASE.jar spring-web-4.1.2.RELEASE.jar //aop注解需要 对于Spring环境的插件,你们可以到Eclipase中的help>Eclipse marketplace...去搜索安装
Spring——AOP原理及流程详解
共勉
11-28 7926
基于5.3.9 版本的Spring源码,对AOP原理及流程详解,AOP是在Bean生成流程中什么位置介入处理的?各个通知方法又是怎么组装的?AOP真的只是动态代理这么简单吗?
Spring注解怎么实现的一些基本原理
11-07
这是对Spring注解是怎么实现的一个大概基本原理,条件是采取的理想状态,所以代码中还有缺陷的话请谅解,如果有需要的朋友可以放心下载,里面有详细的解释和流程。相信你能看懂
SpringAOP实现原理
m0_57229961的博客
01-27 9309
本学习笔记将尽可能的将AOP的知识讲解的通俗易懂,先从一个典型的问题出发,引入AOP这个概念,介绍AOP的基本概念,再到Spring中的AOP的实现方案,最后进行一个简单的总结归纳。本学习笔记中不考虑cglib、也不会太关注Spring AOP如何使用,而是尽可能的简单的说清楚AOP的工作原理。 笔记中贴出的源代码均是Spring 5.1.7-RELEASE 版本 问题提出 如下代码块,现在需要统计这个方法执行的耗时情况 public void runTask() { doSome
Spring重要注解介绍以及原理
qq_47075878的博客
05-09 938
*** 4)、自定义组件想要使用Spring容器底层的一些组件(ApplicationContext,BeanFactory,xxx);* 自定义组件实现xxxAware;在创建对象的时候,会调用接口(Aware)规定的方法注入相关组件;* 把Spring底层一些组件注入到自定义的bean中;* xxxAware:功能使用xxxProcessor来处理的;* 例: ApplicationContextAware ==> ApplicationContextAwareProcessor;
Spring 中常用注解原理剖析
good7ob的博客
05-29 1847
Spring 框架作为 Java 领域广泛使用的企业级框架,凭借其简洁优雅的编程方式,以及丰富的功能和生态,一直备受开发者们的喜爱。当接收到一个 HTTP 请求时,Spring 容器会根据请求的 URL 和请求方法,找到对应的处理方法,并执行相应的业务逻辑。可重用性强:通过注解,可以将相同的元数据应用于不同的类、方法或字段,提高了代码的可重用性。注解解析:通过反射机制,在运行时读取注解的信息,并根据注解的定义来执行相应的逻辑。在 Java 编程中,注解是一种元数据,用于向编译器和运行时环境提供额外的信息。
Spring注解原理的详细剖析与实现
DDDDeng_的博客
07-07 617
一、注解的基本概念和原理及其简单实用 注解(Annotation)提供了一种安全的类似注释的机制,为我们在代码中添加信息提供了一种形式化得方法,使我们可以在稍后某个时刻方便的使用这些数据(通过解析注解来使用这些数据),用来将任何的信息或者元数据与程序元素(类、方法、成员变量等)进行关联。其实就是更加直观更加明了的说明,这些说明信息与程序业务逻辑没有关系,并且是供指定的工具或框架使用的。Annotation像一种修饰符一样,应用于包、类型、构造方法、方法、成员变量、参数及本地变量的申明语句中。 Annotat
SpringBoot下的SpringAOP-day04-源代码
03-09
SpringBoot下的Spring——DAY04——动态代理总结、AOP、自定义注解进行拦截、动态获取注解参数、通知方法 1.动态代理总结 1.1 JDK动态代理特点 1.2 CGlib动态代理 1.2.1 CGLib特点说明 1.3 动态代理的作用 2 Spring...
spring-aop-4.2.4.RELEASE
04-05
spring-aop-4.2.4.RELEASE,spring注解包,代码里面特殊标记,使用注解可以完成功能,相当于语法糖操作
Spring Aop之AspectJ注解配置实现日志管理的方法
08-28
Spring Aop之AspectJ注解配置实现日志管理的方法 Spring Aop是基于AspectJ实现的面向切面编程(AOP),它提供了一个灵活的方式来实现日志管理。通过使用AspectJ注解,可以轻松地实现日志记录、性能监控、安全检查...
Spring注解驱动开发第33讲——AOP原理总结
李阿昀的博客
12-25 2490
往期精选 Spring注解驱动开发第25讲——你敢信?面试官竟然让我现场搭建一个AOP测试环境! Spring注解驱动开发第26讲——总有人让我给他讲讲@EnableAspectJAutoProxy注解 Spring注解驱动开发第27讲——为AnnotationAwareAspectJAutoProxyCreator组件里面和后置处理器以及Aware接口有关的方法打上断点 Spring注解驱动开发第28讲——为你呕心沥血分析创建和注册AnnotationAwareAspectJAutoProxyCreat
SpringSpring AOP 初识及实现原理解析
xyk:的博客
08-05 2304
AOP(Aspect Oriented Programming):面向切面编程,它是⼀种思想,它是对某⼀类事情的集中处理。在我们想要对某一件事情进行集中处理,就可以使用到AOP,它提供一种将程序中的横切关注点模块化的方式。在 AOP 中,我们将这些横切关注点称为“切面”,它们独立于业务逻辑模块,但是可以在程序运行的不同阶段被织入到业务逻辑中。简单来说,AOP 就是对某一件事进行集中处理的思想方式~使用@Aspect@Component // 随着框架的启动而启动。
使用Aop实现自定义注解 - 原理篇
Mr.hu
07-31 5534
自定义注解的实现 本次我们将使用Spring boot 和AOP 实现自定义注解,主要功能是自动打日志。 元注解注解的作用就是负责注解其他注解Java5.0定义了4个标准的meta-annotation类型,它们被用来提供对其它 annotation类型作说明。Java5.0定义的元注解: 1.@Target,说明了Annotation所修饰的对象范围     2.@Retention,定义了该Annotation生命周期(编译/运行)     3.@Documented,是一个标记注解,没有成员
Spring中@Import注解的使用和实现原理(超详细!!!)
热门推荐
gongsenlin341的博客
01-27 2万+
文章目录1. 概述2. 初识@Imprt注解3. @Import注解的使用3.1 普通类注入Spring容器的方式3.2 实现了ImportSelector接口的类注入Spring容器的方式3.3 实现了ImportBeanDefinitionRegistrar接口的类注入Spring容器的方式4. 源码分析4.1 解析@Import注解的时机4.2 3种不同类型的类如何通过@Import注解注入到Spring容器当中源码解析5. 后续 1. 概述 @Import 是 Spring 基于 Java 注解配置
spring-aop-4.3.4jar包
最新发布
11-19
spring-aop-4.3.4.jar是Spring框架中的一个核心jar包,用于实现面向切面编程(AOP)。AOP是一种程序设计思想,通过在程序运行期间动态地将代码织入到现有的类和方法中,来实现一些跨越多个组件的功能,如日志记录、...

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
写文章

热门文章

  • Spring中@Import注解的使用和实现原理(超详细!!!) 28812
  • 【图解】HashMap1.7 头插法造成死循环的原因 15570
  • Spring IOC---AOP代理对象生成的时机 9460
  • Spring IOC---invokeBeanFactoryPostProcessors源码分析 6295
  • mybatis原理分析(五)---参数处理 6134

分类专栏

  • Dubbo 3篇
  • Spring源码解析 9篇
  • Redis 3篇
  • Java面试笔记 4篇
  • Netty原理分析 6篇
  • 聊天系统 1篇
  • mybatis 原理分析 9篇
  • SpringMVC源码解析 4篇
  • 开发中遇到的坑 2篇
  • JDK源码解析 36篇
  • LeetCode刷题笔记 38篇
  • Java并发编程 8篇

最新评论

  • mybatis原理分析(四)---StatementHandler

    五月天的尾巴: 写的挺好,值得学习

  • Spring中@Import注解的使用和实现原理(超详细!!!)

    YCH98: 包扫描没注入把?你又没有给他注册为Bean,加上包扫描只是为了告诉import的类在哪里

  • Spring IOC---AOP代理对象生成的时机

    怡心摸鱼人: 这个思路实在太清晰了

  • Spring中@Import注解的使用和实现原理(超详细!!!)

    学不会java·: 为什么要进行包扫描啊,import里面的value={xxx.class} 其中xxx.class不是会被注入吗,用包扫描不是又注入了一次?

  • 【图解】HashMap1.7 头插法造成死循环的原因

    weixin_44932098: 很清晰

您愿意向朋友推荐“博客详情页”吗?

  • 强烈不推荐
  • 不推荐
  • 一般般
  • 推荐
  • 强烈推荐
提交

最新文章

  • Dubbo 服务引用原理解析
  • Dubbo服务暴露原理解析,带你手撕源码
  • 5种Dubbo负载均衡算法(看这一篇就够了)
2021年26篇
2020年97篇

目录

目录

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值

深圳SEO优化公司惠州网站开发坂田模板制作广州百度竞价包年推广大浪至尊标王大运网站设计模板南澳百姓网标王大芬企业网站建设宝安网站推广系统罗湖网站推广工具坂田百度seo同乐模板制作石岩网站排名优化大鹏网站设计模板布吉网站开发南澳SEO按天收费吉祥SEO按效果付费盐田模板推广福永推广网站民治关键词按天收费盐田企业网站制作南联如何制作网站南澳百度标王南山网站改版塘坑企业网站改版宝安企业网站建设大运建网站坪山企业网站改版坪地百搜词包坑梓网络推广福永网站seo优化歼20紧急升空逼退外机英媒称团队夜以继日筹划王妃复出草木蔓发 春山在望成都发生巨响 当地回应60岁老人炒菠菜未焯水致肾病恶化男子涉嫌走私被判11年却一天牢没坐劳斯莱斯右转逼停直行车网传落水者说“没让你救”系谣言广东通报13岁男孩性侵女童不予立案贵州小伙回应在美国卖三蹦子火了淀粉肠小王子日销售额涨超10倍有个姐真把千机伞做出来了近3万元金手镯仅含足金十克呼北高速交通事故已致14人死亡杨洋拄拐现身医院国产伟哥去年销售近13亿男子给前妻转账 现任妻子起诉要回新基金只募集到26元还是员工自购男孩疑遭霸凌 家长讨说法被踢出群充个话费竟沦为间接洗钱工具新的一天从800个哈欠开始单亲妈妈陷入热恋 14岁儿子报警#春分立蛋大挑战#中国投资客涌入日本东京买房两大学生合买彩票中奖一人不认账新加坡主帅:唯一目标击败中国队月嫂回应掌掴婴儿是在赶虫子19岁小伙救下5人后溺亡 多方发声清明节放假3天调休1天张家界的山上“长”满了韩国人?开封王婆为何火了主播靠辱骂母亲走红被批捕封号代拍被何赛飞拿着魔杖追着打阿根廷将发行1万与2万面值的纸币库克现身上海为江西彩礼“减负”的“试婚人”因自嘲式简历走红的教授更新简介殡仪馆花卉高于市场价3倍还重复用网友称在豆瓣酱里吃出老鼠头315晚会后胖东来又人满为患了网友建议重庆地铁不准乘客携带菜筐特朗普谈“凯特王妃P图照”罗斯否认插足凯特王妃婚姻青海通报栏杆断裂小学生跌落住进ICU恒大被罚41.75亿到底怎么缴湖南一县政协主席疑涉刑案被控制茶百道就改标签日期致歉王树国3次鞠躬告别西交大师生张立群任西安交通大学校长杨倩无缘巴黎奥运

深圳SEO优化公司 XML地图 TXT地图 虚拟主机 SEO 网站制作 网站优化