<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          盤(pán)點(diǎn) AOP : AOP 代理類(lèi)的創(chuàng)建

          共 20592字,需瀏覽 42分鐘

           ·

          2021-07-08 15:27

          一 .前言

          上一篇聊過(guò)了 AOP 的初始化 , 了解了 AOP 是如何通過(guò) PostProcess 完成 AOP 代理類(lèi)的創(chuàng)建 ,

          二 . AOP  創(chuàng)建起點(diǎn)

          AOP 創(chuàng)建的

          // 在 AbstractAutoProxyCreator # wrapIfNecessary 中 , 發(fā)起了 createProxy 流程用于創(chuàng)建代理類(lèi)
          createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean))

          下面來(lái)看一下該邏輯中主要做了什么 :
          復(fù)制代碼

          2.1  AbstractAutoProxyCreator  創(chuàng)建  Proxy 代理類(lèi)

          C- AbstractAutoProxyCreator
          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);
          }

          // 構(gòu)建一個(gè) ProxyFactory
          ProxyFactory proxyFactory = new ProxyFactory();
          proxyFactory.copyFrom(this);

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

          // 構(gòu)建通知者
          Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
          proxyFactory.addAdvisors(advisors);
          proxyFactory.setTargetSource(targetSource);
          customizeProxyFactory(proxyFactory);

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

          // 獲取代理對(duì)象 -> 2.3 Aop 對(duì)象創(chuàng)建詳情
          // org.springframework.aop.framework.ProxyFactory
          return proxyFactory.getProxy(getProxyClassLoader());
          }
          復(fù)制代碼

          [PIC]  :  specificInterceptors 對(duì)象內(nèi)容

          [Pro] AutoProxyUtils 的作用

          C- AutoProxyUtils : 自動(dòng)代理的工具類(lèi)
          M- shouldProxyTargetClass : 確定是否應(yīng)該用目標(biāo)類(lèi)而不是接口代理給定bean
          M- determineTargetClass : 確定指定bean的原始目標(biāo)類(lèi),否則返回到常規(guī)的getType查找
          M- exposeTargetClass : 公開(kāi)指定bean的給定目標(biāo)類(lèi)
          M- isOriginalInstance : 根據(jù) ORIGINAL_INSTANCE_SUFFIX 確定給定bean名是否指示“原始實(shí)例”

          static void exposeTargetClass(
          ConfigurableListableBeanFactory beanFactory, @Nullable String beanName, Class<?> targetClass)
          {

          if (beanName != null && beanFactory.containsBeanDefinition(beanName)) {
          // ORIGINAL_TARGET_CLASS_ATTRIBUTE => org.springframework.aop.framework.autoproxy.AutoProxyUtils.originalTargetClass
          beanFactory.getMergedBeanDefinition(beanName).setAttribute(ORIGINAL_TARGET_CLASS_ATTRIBUTE, targetClass);
          }
          }

          // PS : 這里設(shè)置了 Attribute 屬性 , 后面專(zhuān)門(mén)看一下該屬性會(huì)在什么情況下使用 >>>



          復(fù)制代碼

          [Pro] ProxyFactory 的作用


          用于編程使用的AOP代理的工廠(chǎng) , 該類(lèi)提供了在定制用戶(hù)代碼中獲取和配置AOP代理實(shí)例的簡(jiǎn)單方法
          C- ProxyFactory
          MC- ProxyFactory() : 創(chuàng)建一個(gè) ProxyFactory
          MC- ProxyFactory(Object target) : 創(chuàng)建時(shí)通過(guò) target 設(shè)置 Target 和 Interfaces 屬性
          MC- ProxyFactory(Class<?>... proxyInterfaces) : 沒(méi)有目標(biāo),只有接口且必須添加攔截器
          MC- ProxyFactory(Class<?> proxyInterface, Interceptor interceptor) : 用于為單個(gè)攔截器創(chuàng)建代理的便利方法
          MC- ProxyFactory(Class<?> proxyInterface, TargetSource targetSource) :為指定的TargetSource創(chuàng)建一個(gè)ProxyFactory,使代理實(shí)現(xiàn)指定的接口
          M- getProxy() : 根據(jù)這個(gè)工廠(chǎng)的設(shè)置創(chuàng)建一個(gè)新的代理 , 可反復(fù)調(diào)用
          M- getProxy(@Nullable ClassLoader classLoader) :
          M- getProxy(Class<T> proxyInterface, Interceptor interceptor)
          M- getProxy(Class<T> proxyInterface, TargetSource targetSource)
          M- getProxy(TargetSource targetSource)

          P- proxyInterface :
          P- Interceptor :
          P- TargetSource :

          復(fù)制代碼

          [Pro] Advisor 作用

          保存AOP通知(在連接點(diǎn)上要采取的動(dòng)作)的基本接口和決定通知(如切入點(diǎn))適用性的過(guò)濾器 , Advisor接口允許支持不同類(lèi)型的通知,比如 Before Advice 和 After Advice

          C- Advisor : 通知器
          M- getAdvice()
          M- isPerInstance()

          // 這里說(shuō)一說(shuō) Advisor 是什么時(shí)候調(diào)用的 >>>
          復(fù)制代碼

          2.2 buildAdvisors 創(chuàng)建通知對(duì)象

          C- AbstractAutoProxyCreator
          protected Advisor[] buildAdvisors(@Nullable String beanName, @Nullable Object[] specificInterceptors) {
          // 2-2-1 : 將指定的攔截器名稱(chēng)解析為Advisor對(duì)象
          Advisor[] commonInterceptors = resolveInterceptorNames();

          List<Object> allInterceptors = new ArrayList<>();
          if (specificInterceptors != null) {
          allInterceptors.addAll(Arrays.asList(specificInterceptors));
          if (commonInterceptors.length > 0) {
          if (this.applyCommonInterceptorsFirst) {
          allInterceptors.addAll(0, Arrays.asList(commonInterceptors));
          } else {
          allInterceptors.addAll(Arrays.asList(commonInterceptors));
          }
          }
          }

          Advisor[] advisors = new Advisor[allInterceptors.size()];
          for (int i = 0; i < allInterceptors.size(); i++) {
          // 2-2-2 : 將指定的攔截器名稱(chēng)解析為Advisor對(duì)象
          advisors[i] = this.advisorAdapterRegistry.wrap(allInterceptors.get(i));
          }
          return advisors;
          }


          // 2-2-1 : 將指定的攔截器名稱(chēng)解析為Advisor對(duì)象
          private Advisor[] resolveInterceptorNames() {
          BeanFactory bf = this.beanFactory;
          ConfigurableBeanFactory cbf = (bf instanceof ConfigurableBeanFactory ? (ConfigurableBeanFactory) bf : null);
          List<Advisor> advisors = new ArrayList<>();
          // 獲取通用 interceptor 對(duì)象 , 該對(duì)象可以 setInterceptorNames 設(shè)置
          for (String beanName : this.interceptorNames) {
          if (cbf == null || !cbf.isCurrentlyInCreation(beanName)) {
          Object next = bf.getBean(beanName);
          advisors.add(this.advisorAdapterRegistry.wrap(next));
          }
          }
          return advisors.toArray(new Advisor[0]);
          }


          // 2-2-2 : 將指定的攔截器名稱(chēng)解析為Advisor對(duì)象
          C- DefaultAdvisorAdapterRegistry
          public Advisor wrap(Object adviceObject) throws UnknownAdviceTypeException
          {
          if (adviceObject instanceof Advisor) {
          return (Advisor) adviceObject;
          }
          if (!(adviceObject instanceof Advice)) {
          throw new UnknownAdviceTypeException(adviceObject);
          }
          Advice advice = (Advice) adviceObject;
          if (advice instanceof MethodInterceptor) {
          // So well-known it doesn't even need an adapter.
          return new DefaultPointcutAdvisor(advice);
          }
          for (AdvisorAdapter adapter : this.adapters) {
          // Check that it is supported.
          if (adapter.supportsAdvice(advice)) {
          return new DefaultPointcutAdvisor(advice);
          }
          }
          throw new UnknownAdviceTypeException(advice);
          }


          復(fù)制代碼

          三 . Aop 代理類(lèi)的創(chuàng)建流程

          上一節(jié)通過(guò) CreateProxy 發(fā)起了代理的創(chuàng)建 , 此節(jié)來(lái)說(shuō)一下 ProxyFactory 的創(chuàng)建流程

          Step 1 : 獲取代理類(lèi)主流程 => ProxyFactory

          // 類(lèi)結(jié)構(gòu) ===================
          C- ProxyFactory
          E- ProxyCreatorSupport

          public Object getProxy(@Nullable ClassLoader classLoader)
          {
          // createAopProxy() => org.springframework.aop.framework.ObjenesisCglibAopProxy
          return createAopProxy().getProxy(classLoader);
          }

          // ProxyCreatorSupport 是 ProxyFactory 的父類(lèi) , createAopProxy 會(huì)調(diào)用該類(lèi)方法
          protected final synchronized AopProxy createAopProxy() {
          if (!this.active) {
          // 激活代理配置
          activate();
          }
          // getAopProxyFactory() => org.springframework.aop.framework.DefaultAopProxyFactory
          return getAopProxyFactory().createAopProxy(this);
          }



          復(fù)制代碼

          Step 2 :  AOP 代理工廠(chǎng)的選擇

          // Aop 基于 Proxy 代理 , 主要接口為 AopProxy , 而 AopProxy 的創(chuàng)建接口類(lèi)為 AopProxyFactory , 
          public interface AopProxyFactory {

          /**
          * 為給定的AOP配置創(chuàng)建一個(gè)AopProxy
          */

          AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException;

          }

          // Aop 代理工廠(chǎng)默認(rèn)為 DefaultAopProxyFactory
          public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
          // config.isOptimize() : 返回代理是否應(yīng)該執(zhí)行主動(dòng)優(yōu)化
          // config.isProxyTargetClass() : 返回是否直接代理目標(biāo)類(lèi)以及任何接口
          // hasNoUserSuppliedProxyInterfaces(config) : 確定所提供的AdvisedSupport是否只指定了SpringProxy接口(或者根本沒(méi)有指定代理接口)
          if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
          Class<?> targetClass = config.getTargetClass();
          if (targetClass == null) {
          throw new AopConfigException("TargetSource cannot determine target class: " +
          "Either an interface or a target is required for proxy creation.");
          }
          if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
          return new JdkDynamicAopProxy(config);
          }
          return new ObjenesisCglibAopProxy(config);
          } else {
          return new JdkDynamicAopProxy(config);
          }
          }


          // PS : Spring 類(lèi)默認(rèn)會(huì)使用 JdkDynamicAopProxy , 自行定制的 AOP 類(lèi)通常使用 CglibAopProxy

          可以通過(guò)以下幾種方式配置 :


          // 方式一 : 構(gòu)建 Bean 時(shí)可以通過(guò)配置切換 , 例如 :
          @Configuration(proxyBeanMethods = false)
          @ConditionalOnClass(ExecutableValidator.class)
          @ConditionalOnResource(resources = "classpath:META-INF/services/javax.validation.spi.ValidationProvider")
          @Import(PrimaryDefaultValidatorPostProcessor.class)
          public class ValidationAutoConfiguration {

          @Bean
          @ConditionalOnMissingBean
          public static MethodValidationPostProcessor methodValidationPostProcessor(Environment environment,
          @Lazy Validator validator)
          {
          MethodValidationPostProcessor processor = new MethodValidationPostProcessor();
          // 設(shè)置代理目標(biāo)對(duì)象
          boolean proxyTargetClass = environment.getProperty("spring.aop.proxy-target-class", Boolean.class, true);
          processor.setProxyTargetClass(proxyTargetClass);
          processor.setValidator(validator);
          return processor;
          }
          }

          // 方式二 : 配置 AOP 代理方式
          1. 通過(guò) EnableAspectJAutoProxy 配置
          2. 通過(guò)屬性 spring.aop.proxy-target-class 進(jìn)行配置



          復(fù)制代碼

          Step 3-1 : CglibAopProxy  創(chuàng)建代理類(lèi)


          C- CglibAopProxy
          public Object getProxy(@Nullable ClassLoader classLoader)
          {

          try {
          Class<?> rootClass = this.advised.getTargetClass();

          Class<?> proxySuperClass = rootClass;
          // String CGLIB_CLASS_SEPARATOR = "$$";
          // 包含 $$
          if (rootClass.getName().contains(ClassUtils.CGLIB_CLASS_SEPARATOR)) {
          proxySuperClass = rootClass.getSuperclass();
          Class<?>[] additionalInterfaces = rootClass.getInterfaces();
          for (Class<?> additionalInterface : additionalInterfaces) {
          this.advised.addInterface(additionalInterface);
          }
          }

          // 檢查是否已經(jīng)驗(yàn)證了所提供的Class,如果沒(méi)有,則驗(yàn)證它
          validateClassIfNecessary(proxySuperClass, classLoader);

          // 配置 CGLIB 增強(qiáng) -> RPO31001
          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[] 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);

          // 生成代理類(lèi)并創(chuàng)建代理實(shí)例
          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);
          // 通過(guò)是否存在構(gòu)造參數(shù)分別創(chuàng)建
          return (this.constructorArgs != null && this.constructorArgTypes != null ?
          enhancer.create(this.constructorArgTypes, this.constructorArgs) :
          enhancer.create());
          }

          // RPO31001 補(bǔ)充 : Enhancer 的作用

          通常我們常見(jiàn)的代理方式是通過(guò) Proxy 類(lèi) , 而 Enhancer 也是一個(gè)方法代理類(lèi) , Proxy是基于接口的方式進(jìn)行代理,Enhancer是基于繼承的方式代理





          復(fù)制代碼

          Step 3-2 : JdkDynamicAopProxy

          // JdkDynamicAopProxy 構(gòu)建代理類(lèi)
          public Object getProxy(@Nullable ClassLoader classLoader) {
          Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);
          findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
          // 創(chuàng)建代理類(lèi)
          return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
          }
          復(fù)制代碼

          AopProxy 代理體系

          Spring 中的代理類(lèi)通常有 2個(gè)類(lèi) : CglibAopProxy / JdkDynamicAopProxy

          // [Pro] : 如何切換 AopProxy 代理類(lèi)型

          復(fù)制代碼

          四 . 要點(diǎn)深入

          4.1 ORIGINAL_TARGET_CLASS_ATTRIBUTE 屬性的使用

          // Step 1 : AbstractApplicationContext # refresh
          public void refresh() throws BeansException, IllegalStateException {
          synchronized (this.startupShutdownMonitor) {
          try {
          //.................

          // 實(shí)例化所有剩余的(非lazy-init)單例
          finishBeanFactoryInitialization(beanFactory);

          // Last step: publish corresponding event.
          finishRefresh();
          }
          //........
          }
          }

          // PS : 可以看到 , 在主流程倒數(shù)第二步中 ,

          // EventListenerMethodProcessor : 對(duì)標(biāo)注了 @EventListener 的方法進(jìn)行解析, 然后轉(zhuǎn)換為一個(gè) ApplicationListener
          // Step 2: C- EventListenerMethodProcessor # afterSingletonsInstantiated
          public void afterSingletonsInstantiated() {
          ConfigurableListableBeanFactory beanFactory = this.beanFactory;
          String[] beanNames = beanFactory.getBeanNamesForType(Object.class);
          for (String beanName : beanNames) {
          if (!ScopedProxyUtils.isScopedTarget(beanName)) {
          Class<?> type = null;
          try {
          // 確定指定bean的原始目標(biāo)類(lèi)
          // Step 2-1 : 獲取 originalTargetClass
          // beanName -> org.springframework.context.annotation.internalConfigurationAnnotationProcessor
          // type -> org.springframework.context.annotation.ConfigurationClassPostProcessor
          type = AutoProxyUtils.determineTargetClass(beanFactory, beanName);
          }
          catch (Throwable ex) {
          //...............
          }
          if (type != null) {
          if (ScopedObject.class.isAssignableFrom(type)) {
          try {

          Class<?> targetClass = AutoProxyUtils.determineTargetClass(
          beanFactory, ScopedProxyUtils.getTargetBeanName(beanName));
          if (targetClass != null) {
          type = targetClass;
          }
          }
          catch (Throwable ex) {
          //...............
          }
          }
          try {
          // Step 2-3 : 獲取 originalTargetClass
          processBean(beanName, type);
          }
          catch (Throwable ex) {
          //...............
          }
          }
          }
          }
          }

          // Step 2-1 : 從 BeanDefinition 中獲取屬性 originalTargetClass
          String ORIGINAL_TARGET_CLASS_ATTRIBUTE = Conventions.getQualifiedAttributeName(AutoProxyUtils.class, "originalTargetClass");
          BeanDefinition bd = beanFactory.getMergedBeanDefinition(beanName);
          Class<?> targetClass = (Class<?>) bd.getAttribute(ORIGINAL_TARGET_CLASS_ATTRIBUTE);

          // Step 2-2 : 查找原始目標(biāo)類(lèi) , 可以看到 , 通常查詢(xún)的類(lèi)都是 internalXXX 開(kāi)頭的類(lèi) , 該類(lèi)為 beanDefinitionNames 中創(chuàng)建
          public static Class<?> determineTargetClass(
          ConfigurableListableBeanFactory beanFactory, @Nullable String beanName) {

          if (beanName == null) {
          return null;
          }
          if (beanFactory.containsBeanDefinition(beanName)) {
          BeanDefinition bd = beanFactory.getMergedBeanDefinition(beanName);
          Class<?> targetClass = (Class<?>) bd.getAttribute(ORIGINAL_TARGET_CLASS_ATTRIBUTE);
          if (targetClass != null) {
          return targetClass;
          }
          }
          return beanFactory.getType(beanName);
          }


          // Step 2-3 : 該方法省略 , 主要是 EventListener 注解的處理 , 和主流程無(wú)關(guān)
          private void processBean(final String beanName, final Class<?> targetType)


          復(fù)制代碼

          4.2  AOP Cglib 配置流程

          通常基礎(chǔ)的AOP 代理是通過(guò)

          org.springframework.boot.autoconfigure.aop.AopAutoConfiguration$AspectJAutoProxyingConfiguration$CglibAutoProxyConfiguration

          public void registerBeanDefinitions(
          AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry)
          {

          AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);

          // h
          AnnotationAttributes enableAspectJAutoProxy =
          AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);
          //
          if (enableAspectJAutoProxy != null) {
          if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {
          AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
          }
          if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {
          AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
          }
          }
          }


          public static void forceAutoProxyCreatorToUseClassProxying(BeanDefinitionRegistry registry) {
          // AUTO_PROXY_CREATOR_BEAN_NAME => org.springframework.aop.config.internalAutoProxyCreator
          if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {
          BeanDefinition definition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);
          definition.getPropertyValues().add("proxyTargetClass", Boolean.TRUE);
          }
          }


          復(fù)制代碼

          補(bǔ)充一 :  EnableAspectJAutoProxy

          public @interface EnableAspectJAutoProxy {

          /**
          * Indicate whether subclass-based (CGLIB) proxies are to be created as opposed
          * to standard Java interface-based proxies. The default is {@code false}.
          */

          boolean proxyTargetClass() default false;

          /**
          * Indicate that the proxy should be exposed by the AOP framework as a {@code ThreadLocal}
          * for retrieval via the {@link org.springframework.aop.framework.AopContext} class.
          * Off by default, i.e. no guarantees that {@code AopContext} access will work.
          * @since 4.3.1
          */

          boolean exposeProxy() default false;

          }
          復(fù)制代碼

          補(bǔ)充二 :  AopAutoConfiguration 自動(dòng)配置類(lèi)

          @Configuration(proxyBeanMethods = false)
          @ConditionalOnProperty(prefix = "spring.aop", name = "auto", havingValue = "true", matchIfMissing = true)
          public class AopAutoConfiguration {

          @Configuration(proxyBeanMethods = false)
          @ConditionalOnClass(Advice.class)
          static class AspectJAutoProxyingConfiguration {

          @Configuration(proxyBeanMethods = false)
          @EnableAspectJAutoProxy(proxyTargetClass = false)
          @ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "false",
          matchIfMissing = false)

          static class JdkDynamicAutoProxyConfiguration {

          }

          @Configuration(proxyBeanMethods = false)
          @EnableAspectJAutoProxy(proxyTargetClass = true)
          @ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "true",
          matchIfMissing = true)

          static class CglibAutoProxyConfiguration {

          }

          }

          @Configuration(proxyBeanMethods = false)
          @ConditionalOnMissingClass("org.aspectj.weaver.Advice")
          @ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "true",
          matchIfMissing = true)

          static class ClassProxyingConfiguration {

          ClassProxyingConfiguration(BeanFactory beanFactory) {
          if (beanFactory instanceof BeanDefinitionRegistry) {
          BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
          AopConfigUtils.registerAutoProxyCreatorIfNecessary(registry);
          AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
          }
          }

          }

          }
          復(fù)制代碼

          補(bǔ)充三 : org.springframework.aop.config.internalAutoProxyCreator 的作用

          C- AopConfigUtils # String AUTO_PROXY_CREATOR_BEAN_NAME = "org.springframework.aop.config.internalAutoProxyCreator"
          ?- 內(nèi)部管理的自動(dòng)代理創(chuàng)建器的bean名

          復(fù)制代碼

          總結(jié)

          講道理 , 這篇文章其實(shí)沒(méi)寫(xiě)好 , 很多地方現(xiàn)在都沒(méi)弄清楚 , 精力有限無(wú)法在細(xì)致深入 , 總得來(lái)說(shuō)算是一個(gè)半成品吧 , 后面時(shí)間充裕了 , 再來(lái)深入看一下

          核心概念 :

          • AbstractAutoProxyCreator  # createProxy 發(fā)起代理類(lèi)的創(chuàng)建

          • AutoProxyUtils 為工具類(lèi) , 用于原類(lèi)和代理的一些常見(jiàn)操作處理

          • 通過(guò) AopProxyFactory  創(chuàng)建代理類(lèi) , 有2種 : ObjenesisCglibAopProxy /  JdkDynamicAopProxy


          作者:AntBlack
          鏈接:https://juejin.cn/post/6980187257856589855
          來(lái)源:掘金
          著作權(quán)歸作者所有。商業(yè)轉(zhuǎn)載請(qǐng)聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請(qǐng)注明出處。



          瀏覽 72
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  国产黄色片在线观看 | 国产色情 免费 | 黄片视频网站入口 | 久久久久久69精品 | 激情综合五月天 |