外企口头常说AOP_外企高频词汇汇总60个

2025-01-1805:25:34创业资讯1

解析与初始化 AOP 部分

`aop`部分的解析器由`AopNamespaceHandler`注册,其`init`方法开始了配置解析的过程。

```

AopNamespaceHandler 注册了 aop 部分的解析器,其 init 方法开始了解析过程。

此标签用于配置 pointcut、advisor、aspect 等实例:

ConfigBeanDefinitionParser.parse 方法负责解析配置:

解析过程主要分为以下几个部分。

aop:config 的两个属性分别代表是否为被代理者生成 CGLIB 子类(默认为 false,只为接口生成代理子类)以及是否将代理 bean 给用户。这两个属性分别影响代理的生成方式和用户对代理的访问。

属性读取是解析过程中的重要一环,虽然具体细节不再详述,但基本流程就是读取并处理配置文件中的属性。

pointcut 的解析会生成一个 BeanDefinition 并将其 id、expression 等属性保存在 BeanDefinition 中。请注意以下几点:

  • BeanDefinition 的 ID 来源于 id 属性,如果没有指定,则会自动生成。
  • BeanDefinition 的类是 AspectJExpressionPointcut。
  • BeanDefinition 的作用域为 prototype。

AspectJExpressionPointcut 的类图展示了其属性和相关依赖。

advisor 是 Spring 独有的概念,来自于早期的 aop 概念实现。Spring 官方的说法是 aop-schema-advisors。advisor 必须实现 org.aopalliance.aop.Advice 的子接口,例如 org.aopalliance.intercept.MethodInterceptor 等。

最常用的用途是与事务一起使用。解析的套路与上述类似,只不过此时的 beanClass 是 DefaultBeanFactoryPointcutAdvisor,其类图也需查看理解。

对于 pointcut 和 pointcut-ref 的处理有所不同,前者 Spring 会创建一个 AspectJExpressionPointcut 类型的 BeanDefinition,而后者则会生成一个 RuntimeBeanReference 对象指向原 pointcut 的引用。

aop:declare-parents 子标签决定了代理子类应该实现哪些接口。

其他如 aop:before、aop:after 等标签是最核心的配置,它们最终被解析为不同类型的 BeanDefinition,并注册到 Spring 容器中。

Spring 通过 AutoProxyCreator 类及其子类来自动生成代理类。关键在于 AspectJAwareAdvisorAutoProxyCreator 这个类,它在 ConfigBeanDefinitionParser 的 configureAutoProxyCreator 方法中注册。其类图展示了代理创建的逻辑和关键步骤。

Bean 的创建过程中会调用 AbstractAutoProxyCreator 的 createBean 方法,这个方法在 Bean 实例创建之前被调用,并执行代理相关的逻辑。

AbstractAutoProxyCreator 的 postProcessBeforeInstantiation 和 postProcessAfterInitialization 方法是代理创建的关键步骤。它们会检查当前 Bean 是否需要代理,以及如何代理。这个过程涉及到很多细节,如基础类的检测、跳过类的检测、Advisor 的应用等。

Spring 的动态代理技术包括 JDK 动态代理和 CGLIB 代理两种方式。如果指定了使用 CGLIB(proxy-target-class 设为 true),则会使用 CGLIB 方式创建代理子类;如果没有指定或为 false,则会检测被代理类是否实现了自己的接口,如果实现了,那么就采用 JDK 动态代理的方式。

最后是关于 scoped proxy 的部分,它允许在一个 bean 的作用域内动态地引入其他 bean,使得在一个 bean 的生命周期内可以始终获取到最新的引用对象。

在BeanFactory的内部,有一个名为scopes的LinkedHashMap对象,其类型为。当我们调用scope.get方法时,实际上是在调用我们的OneSocpe的get方法,整个过程中并没有使用到ObjectFactory。

每当我们调用一次getBean方法时,就会创建一个新的Student实例并返回。这就像是每一次的请求都触发了Student的全新诞生。

进一步探讨,从上述描述中我们得知SimpleBean内部对学生(student)的引用其实是一个由CGLIB创建的代理子类的对象。那么问题来了,当我们对这个代理对象调用相关的方法,如getName时,它是如何导致Student的重新创建或getBean被调用的呢?

为了更好地理解这一点,我们首先需要掌握CGLIB的两个核心概念。

Callback是Cglib中所有自定义逻辑(增强)的共同接口。这个接口定义了在代理对象的方法被调用时应当执行的逻辑。

关于CGLib的Enhancer机制。Enhancer允许我们指定一个Callback数组,而accept方法的返回值是一个int值,这个值实际上代表了Callback数组中的索引,这样我们就可以精确地指定哪些方法调用时应该执行哪些回调逻辑,甚至可以选择不执行任何回调。

在CGLib中,DynamicAdvisedInterceptor通常被用作回调逻辑。其intercept方法的源代码揭示了其工作机制。在intercept方法中,target代表了被代理的对象。当我们对代理对象进行操作时,如调用其方法,实际上最终都会转发到这个target对象上。

TargetSource的概念在前文中已经提及,它默认的实现是SimpleBeanTargetSource。当一切准备就绪,真相也就水落石出了。

  • 版权说明:
  • 本文内容由互联网用户自发贡献,本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 295052769@qq.com 举报,一经查实,本站将立刻删除。