Spring AOP 源码解析

简介: 基于Spring Boot 的AOP启动的源码解析,分析在Spring Boot 容器启动时,AOP的过程

基本概念

AOP 是面向切面|面向方面编程的简称,Aspect-Oriented Programming。 Aspect 是一种模块化机制,是用来描述分散在对象,类,函数中的横切关注点。从关注点分离出横切关注点是面向切面的程序设计的核心概念。分离关注点使解决特定领域问题的代码从业务逻辑中独立出来,业务逻辑的代码中不在含有针对特定领域问题的代码调用,业务逻辑和特定领域的问题的关系通过切面来封装,维护,这样原本分散在整个程序中的变动就可以很好的管理起来了。

基础: 待增强对象或者目标对象

切面: 包含对基础的增强应用

配置: 可以看成一种编织,通过在AOP体系中提供这个配置环境,将基础和切面结合起来,从而完成切面对目标对象的编织实现

Advice(通知): 定义在连接点做什么,为切面增强提供织入接口。在Spring AOP 中,它主要描述Spring AOP 围绕方法调用而注入的切面行为。

Pointcut(切点):决定Advice通知应该作用于哪个连接点,也就是说通过Pointcut来定义需要增强的方法集合。

Advisor(通知器):完成对目标方法的切面增强设计(advice)和关注点的设计以后,需要一个对象把它们结合起来,完成这个作用的就是Advisor(通知器)。通过Advisor ,可以定义应该使用那个通知并在哪个关注点使用它。

源码分析

### 启动过程
在Sprint Boot 启动类上加入 注解 @EnableAspectJAutoProxy(proxyTargetClass = true) ,注解源码为:

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import({AspectJAutoProxyRegistrar.class})
public @interface EnableAspectJAutoProxy {
    boolean proxyTargetClass() default false;

    boolean exposeProxy() default false;
}

​ 该注解使用 @Import 注解引入 AspectJAutoProxyRegistrar , 跟踪 AspectJAutoProxyRegistrar 类:

class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {

    /**
     * Register, escalate, and configure the AspectJ auto proxy creator based on the value
     * of the @{@link EnableAspectJAutoProxy#proxyTargetClass()} attribute on the importing
     * {@code @Configuration} class.
     */
    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata , 
                                                                        BeanDefinitionRegistry registry) {
        /* 
        往容器中注入AnnotationAwareAspectJAutoProxyCreator类,bean名称为 org.springframework.aop.config.internalAutoProxyCreator
        */
        AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
        /*
            读取主配置类的 EnableAspectJAutoProxy的注解的属性
        */
        AnnotationAttributes enableAspectJAutoProxy =
                AnnotationConfigUtils.attributesFor(importingClassMetadata,     
                                            EnableAspectJAutoProxy.class);
        if (enableAspectJAutoProxy != null) {
            if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {
                AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
            }
            if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {
                AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
            }
        }
    }
}

通过源码发现,AspectJAutoProxyRegistrar 类 实现了ImportBeanDefinitionRegistrar 接口,在容器启动的时候会调用所有实现ImportBeanDefinitionRegistrar的 bean 的registerBeanDefinitions 方法。在方法内部:
1.调用 org.springframework.aop.config.AopConfigUtils#registerAspectJAnnotationAutoProxyCreatorIfNecessary(org.springframework.beans.factory.support.BeanDefinitionRegistry)

a. 在`registerAspectJAnnotationAutoProxyCreatorIfNecessary` 方法内部:

  public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry) {
    return registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry, (Object)null);
}
  
  1. 最终调用 org.springframework.aop.config.AopConfigUtils#registerOrEscalateApcAsRequired 方法, 参数cls 为 AnnotationAwareAspectJAutoProxyCreator.class
private static BeanDefinition registerOrEscalateApcAsRequired(Class<?> cls, BeanDefinitionRegistry registry, @Nullable Object source) {
  Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
  if (registry.containsBeanDefinition(
    "org.springframework.aop.config.internalAutoProxyCreator")) {
      BeanDefinition apcDefinition = registry.getBeanDefinition(
        "org.springframework.aop.config.internalAutoProxyCreator");
      if (!cls.getName().equals(apcDefinition.getBeanClassName())) {
          int currentPriority = findPriorityForClass(
            apcDefinition.getBeanClassName());
          int requiredPriority = findPriorityForClass(cls);
          if (currentPriority < requiredPriority) {
              apcDefinition.setBeanClassName(cls.getName());
          }
      }

      return null;
  } else {
      RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);
      beanDefinition.setSource(source);
      beanDefinition.getPropertyValues().add("order", -2147483648);
      beanDefinition.setRole(2);
      registry.registerBeanDefinition(
        "org.springframework.aop.config.internalAutoProxyCreator",   
        beanDefinition);
      return beanDefinition;
  }
}

在方法内部, 首先检查容器中是否包含名称为 org.springframework.aop.config.internalAutoProxyCreator 的bean ,容器第一次启动总不包含该bean,进入else 逻辑,创建一个 AnnotationAwareAspectJAutoProxyCreator.class的bean定义,并且注册bean的名称为AnnotationAwareAspectJAutoProxyCreator.class

2.调用org.springframework.context.annotation.AnnotationConfigUtils#attributesFor(org.springframework.core.type.AnnotatedTypeMetadata, java.lang.Class<?>) 该类主要完成 读取主配置类的 EnableAspectJAutoProxy的注解的属性。 主要检查 proxyTargetClassexposeProxy 属性的值

AnnotationAwareAspectJAutoProxyCreator

在容器启动的过程中, AOP 向容器中注入了一个 AnnotationAwareAspectJAutoProxyCreator 的 bean , 我们来分析一下这个bean 。
类的继承体系 :
image.png
通过 类的继承体系,我们发现 AnnotationAwareAspectJAutoProxyCreator 实现了 BeanFactoryAware ,BeanClassLoaderAware, SmartInstantiationAwareBeanPostProcessor,InstantiationAwareBeanPostProcessor , BeanPostProcessor , BeanClassLoaderAware 等接口 来介入容器启动过程容Bean的生命周期。
类的接口实现:
AOP类继承图.jpg
AnnotationAwareAspectJAutoProxyCreator的接口实现中:

BeanFactoryAware接口
定义了setBeanFactory 接口, 在容器启动的时候调用org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator#setBeanFactory

@Override
public void setBeanFactory(BeanFactory beanFactory) {
  // 设置容器
  super.setBeanFactory(beanFactory);
  if (!(beanFactory instanceof ConfigurableListableBeanFactory)) {
  throw new IllegalArgumentException(
  "AdvisorAutoProxyCreator requires a ConfigurableListableBeanFactory: " + beanFactory);
  }
  initBeanFactory((ConfigurableListableBeanFactory) beanFactory);
}

protected void initBeanFactory(ConfigurableListableBeanFactory beanFactory) {
    // 创建增强器探索工具
  this.advisorRetrievalHelper = new     BeanFactoryAdvisorRetrievalHelperAdapter(beanFactory);
}

其中initBeanFactory 最终调用org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator#initBeanFactory

@Override
protected void initBeanFactory(ConfigurableListableBeanFactory beanFactory) {
  // 调用父类的initBeanFactory方法
  super.initBeanFactory(beanFactory);
  if (this.aspectJAdvisorFactory == null) {
    // 创建Aspect增强器工厂
    this.aspectJAdvisorFactory = new ReflectiveAspectJAdvisorFactory(beanFactory);
  }
  // 创建一个增强器的构建器
  this.aspectJAdvisorsBuilder =
    new BeanFactoryAspectJAdvisorsBuilderAdapter(beanFactory, this.aspectJAdvisorFactory);
}

InstantiationAwareBeanPostProcessor接口
我们知道在spring 容器创建任意一个bean的过程中。在 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBean的方法中:

@Override
    protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
            throws BeanCreationException {

        // ... 省略代码

        try {
            // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
            Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
            if (bean != null) {
                return bean;
            }
        }
        catch (Throwable ex) {
            throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
                    "BeanPostProcessor before instantiation of bean failed", ex);
        }

        Object beanInstance = doCreateBean(beanName, mbdToUse, args);
            //... 省略代码
    }

在调用真正创建bean的方法doCreateBean 之前, 先调用了 resolveBeforeInstantiation方法。 我们跟踪org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#resolveBeforeInstantiation 方法:

protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
  Object bean = null;
  if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
    // Make sure bean class is actually resolved at this point.
    // 当容器中存在InstantiationAwareBeanPostProcessors 时,调用InstantiationAwareBeanPostProcessors 的 postProcessBeforeInstantiation 方法和 postProcessAfterInitialization 方法
    if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
      Class<?> targetType = determineTargetType(beanName, mbd);
      if (targetType != null) {
        bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
        if (bean != null) {
          bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
        }
      }
    }
    mbd.beforeInstantiationResolved = (bean != null);
  }
  return bean;
}

当容器中存在InstantiationAwareBeanPostProcessors的bean时
1.先调用applyBeanPostProcessorsBeforeInstantiation方法,
2.然后在调用applyBeanPostProcessorsAfterInitialization 方法
跟踪 applyBeanPostProcessorsBeforeInstantiation 方法

protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
    // 获取容器中所有BeanPostProcessor, 若BeanPostProcessor 是InstantiationAwareBeanPostProcessor ,则调用其 postProcessBeforeInstantiation 方法
  for (BeanPostProcessor bp : getBeanPostProcessors()) {
    if (bp instanceof InstantiationAwareBeanPostProcessor) {
      InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
      Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
      if (result != null) {
        return result;
      }
    }
  }
  return null;
}

applyBeanPostProcessorsBeforeInstantiation 方法内部,首先获取容器中所有BeanPostProcessor

BeanPostProcessorInstantiationAwareBeanPostProcessor

则调用其 postProcessBeforeInstantiation 方法 。

​ 然后我们在容器启动的时候,在容器中注册了AnnotationAwareAspectJAutoProxyCreator 并且这个bean 实现的InstantiationAwareBeanPostProcessor接口,所以在容器创建bean的时候,会触发AnnotationAwareAspectJAutoProxyCreatorapplyBeanPostProcessorsBeforeInstantiation方法。

这个是Spring AOP 的真正入口。

接下来我们详细分析:

org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#postProcessBeforeInstantiationAnnotationAwareAspectJAutoProxyCreator 继承了 AbstractAutoProxyCreator

postProcessBeforeInstantiation

调用链:
postProcessBeforeInstantiation调用链图.jpg

详细分析:
在postProcessBeforeInstantiation 中查找所有的增强器org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#postProcessBeforeInstantiation的源码如下,在容器创建任何一个bean的时候触发:

public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) {
  //1.先获取 bean的key
  Object cacheKey = getCacheKey(beanClass, beanName);
    //2. 判断bean是否已经处理过,处理过的bean被放入targetSourcedBeans 集合中。
  if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) {
    //3.判断是否已经包含bean的增强器
    if (this.advisedBeans.containsKey(cacheKey)) {
      return null;
    }
    //4.判断bean类型 和 是否应该跳过
    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);
  if (targetSource != null) {
    if (StringUtils.hasLength(beanName)) {
      this.targetSourcedBeans.add(beanName);
    }
    Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, 
                                                                 beanName, targetSource);
    // 创建代理bean
    Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
    this.proxyTypes.put(cacheKey, proxy.getClass());
    return proxy;
  }

  return null;
}

1.先获取 bean的key
2.判断bean是否已经处理过,处理过的bean被放入targetSourcedBeans 集合中。
3.判断是否已经包含bean的增强器
4.判断是否是需要增强的bean

a.判断bean的类型是否为基础类:Advice,Pointcut,Advisor,AopInfrastructureBean进入isInfrastructureClass源码:
protected boolean isInfrastructureClass(Class<?> beanClass) {
  boolean retVal = Advice.class.isAssignableFrom(beanClass) ||
    Pointcut.class.isAssignableFrom(beanClass) ||
      Advisor.class.isAssignableFrom(beanClass) ||
        AopInfrastructureBean.class.isAssignableFrom(beanClass);
  if (retVal && logger.isTraceEnabled()) {
    logger.trace("");
  }
  return retVal;
}

b.判断是否跳过处理,进入shouldSkip方法源码

 @Override
protected boolean shouldSkip(Class<?> beanClass, String beanName) {

// 查找容器中所有的候选的增强器列表
List<Advisor> candidateAdvisors = findCandidateAdvisors();
// 若列表中包含当前bean的增强器,返回true
for (Advisor advisor : candidateAdvisors) {
  if (advisor instanceof AspectJPointcutAdvisor &&
      ((AspectJPointcutAdvisor) advisor).getAspectName().equals(beanName)) {
    return true;
  }
}
return super.shouldSkip(beanClass, beanName);
}

跟踪findCandidateAdvisors 方法内部:

@Override
protected List<Advisor> findCandidateAdvisors() {
  // Add all the Spring advisors found according to superclass rules.
  // 容器中所有实现Advisor接口的bean组件,熟悉 Spring 事物的都知道,Advisor接口是为Spring事务服务的
  List<Advisor> advisors = super.findCandidateAdvisors();
  // Build Advisors for all AspectJ aspects in the bean factory.
  // 查找容器是标注@Aspect 组件的bean ,并解析bean的标注 @Before, @After, @AfterReturning, @AfterThrowing 的方法,即查找增强器。并加入缓存中。
  if (this.aspectJAdvisorsBuilder != null) {
    advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
  }
  return advisors;
}

5.后续第一次执行不到

postProcessAfterInitialization

调用链:
postProcessAfterInitialization调用链.jpg
详细过程:
跟踪org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#postProcessAfterInitialization源码:

@Override
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
  if (bean != null) {
    Object cacheKey = getCacheKey(bean.getClass(), beanName);
    if (this.earlyProxyReferences.remove(cacheKey) != bean) {
      // 必要的话,包装代理对象
      return wrapIfNecessary(bean, beanName, cacheKey);
    }
  }
  return bean;
}

进入wrapIfNecessary方法:

protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
 
  if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
    return bean;
  }
  if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
    return bean;
  }
  // 判断是否生成代理对象
  if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
    this.advisedBeans.put(cacheKey, Boolean.FALSE);
    return bean;
  }
    // 获取通知和增强器
  // Create proxy if we have advice.
  Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
  if (specificInterceptors != DO_NOT_PROXY) {
    this.advisedBeans.put(cacheKey, Boolean.TRUE);
    // 创建代理对象
    Object proxy = createProxy(
      bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
    this.proxyTypes.put(cacheKey, proxy.getClass());
    return proxy;
  }

  this.advisedBeans.put(cacheKey, Boolean.FALSE);
  return bean;
}

跟踪getAdvicesAndAdvisorsForBean()方法最终调用:org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator#findEligibleAdvisors:

protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
 // 找到候选的增强器
  List<Advisor> candidateAdvisors = findCandidateAdvisors();
  // 筛选可用的增强器
  List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
  // 扩展
  extendAdvisors(eligibleAdvisors);
  if (!eligibleAdvisors.isEmpty()) {
    // 排序
    eligibleAdvisors = sortAdvisors(eligibleAdvisors);
  }
  return eligibleAdvisors;
}

跟踪: findCandidateAdvisors():

@Override
protected List<Advisor> findCandidateAdvisors() {
  // Add all the Spring advisors found according to superclass rules.
  // 查找所有 实现Advisor的接口的增强器
  List<Advisor> advisors = super.findCandidateAdvisors();
  // Build Advisors for all AspectJ aspects in the bean factory.
  if (this.aspectJAdvisorsBuilder != null) {
    // 查找所有Aspect ,查找容器是标注@Aspect 组件的bean ,并解析bean的标注 @Before, @After, @AfterReturning, @AfterThrowing 的方法,即查找增强器。并加入缓存中。
    advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
  }
  return advisors;
}

跟踪:findAdvisorsThatCanApply 并最终调用:org.springframework.aop.support.AopUtils#findAdvisorsThatCanApply

public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz) {
  if (candidateAdvisors.isEmpty()) {
    return candidateAdvisors;
  }
  List<Advisor> eligibleAdvisors = new ArrayList<>();
  for (Advisor candidate : candidateAdvisors) {
    if (candidate instanceof IntroductionAdvisor && canApply(candidate, clazz)) {
      eligibleAdvisors.add(candidate);
    }
  }
  boolean hasIntroductions = !eligibleAdvisors.isEmpty();
  for (Advisor candidate : candidateAdvisors) {
    if (candidate instanceof IntroductionAdvisor) {
      // already processed
      continue;
    }
    if (canApply(candidate, clazz, hasIntroductions)) {
      eligibleAdvisors.add(candidate);
    }
  }
  return eligibleAdvisors;
}

进入 canApply方法: 最终调用:org.springframework.aop.support.AopUtils#canApply(org.springframework.aop.Pointcut, java.lang.Class<?>, boolean)方法:

public static boolean canApply(Pointcut pc, Class<?> targetClass, boolean hasIntroductions) {
  Assert.notNull(pc, "Pointcut must not be null");
  if (!pc.getClassFilter().matches(targetClass)) {
    return false;
  }

  MethodMatcher methodMatcher = pc.getMethodMatcher();
  if (methodMatcher == MethodMatcher.TRUE) {
    // No need to iterate the methods if we're matching any method anyway...
    return true;
  }
    // 创建方法匹配器
  IntroductionAwareMethodMatcher introductionAwareMethodMatcher = null;
  if (methodMatcher instanceof IntroductionAwareMethodMatcher) {
    introductionAwareMethodMatcher = (IntroductionAwareMethodMatcher) methodMatcher;
  }

  Set<Class<?>> classes = new LinkedHashSet<>();
  if (!Proxy.isProxyClass(targetClass)) {
    classes.add(ClassUtils.getUserClass(targetClass));
  }
  classes.addAll(ClassUtils.getAllInterfacesForClassAsSet(targetClass));

  for (Class<?> clazz : classes) {
    Method[] methods = ReflectionUtils.getAllDeclaredMethods(clazz);
    for (Method method : methods) {
      if (introductionAwareMethodMatcher != null ?
          introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions) :
          // 匹配切面的方法
          methodMatcher.matches(method, targetClass)) {
        return true;
      }
    }
  }

  return false;
}

getAdvicesAndAdvisorsForBean 方法逻辑分析结束。

跟踪createProxy 方法:org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#createProxy

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);
    // 设置使用JDK代理还是使用CGLIB代理
  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());
}

这样 postProcessAfterInitialization 的逻辑就分析。

总结

在分析了Spring AOP的启动过程,总结一下总体过程:

1.setBeanFacotry 接口,在容器启动的时候,创建了 BeanFactoryAdvisorRetrievalHelperAdapter 增强器探索更具和BeanFactoryAspectJAdvisorsBuilderAdapter 增强器的构建器

2.postProcessBeforeInstantiation 接口: 查找所有的切面和Advisor,并将切面的通知解析,构建成初步的增强器,加入到缓存中来。

3.postProcessAfterInitialization 接口,从缓存取出所有的将所有的增强器,创建代理工厂,并织入增强器,创建代理对象

调用过程:

待更新...

目录
相关文章
|
10月前
|
负载均衡 监控 Java
Spring Cloud Gateway 全解析:路由配置、断言规则与过滤器实战指南
本文详细介绍了 Spring Cloud Gateway 的核心功能与实践配置。首先讲解了网关模块的创建流程,包括依赖引入(gateway、nacos 服务发现、负载均衡)、端口与服务发现配置,以及路由规则的设置(需注意路径前缀重复与优先级 order)。接着深入解析路由断言,涵盖 After、Before、Path 等 12 种内置断言的参数、作用及配置示例,并说明了自定义断言的实现方法。随后重点阐述过滤器机制,区分路由过滤器(如 AddRequestHeader、RewritePath、RequestRateLimiter 等)与全局过滤器的作用范围与配置方式,提
Spring Cloud Gateway 全解析:路由配置、断言规则与过滤器实战指南
|
10月前
|
缓存 安全 Java
Spring Security通用权限管理模型解析
Spring Security作为Spring生态的核心安全框架,结合RBAC与ACL权限模型,基于IoC与AOP构建灵活、可扩展的企业级权限控制体系,涵盖认证、授权流程及数据库设计、性能优化等实现策略。
688 0
|
10月前
|
缓存 安全 Java
Spring Security权限管理解析
Spring Security是Spring生态中的核心安全框架,采用认证与授权分离架构,提供高度可定制的权限管理方案。其基于过滤器链实现认证流程,通过SecurityContextHolder管理用户状态,并结合RBAC模型与动态权限决策,支持细粒度访问控制。通过扩展点如自定义投票器、注解式校验与前端标签,可灵活适配多租户、API网关等复杂场景。结合缓存优化与无状态设计,适用于高并发与前后端分离架构。
675 0
|
10月前
|
人工智能 Java 开发者
【Spring】原理解析:Spring Boot 自动配置
Spring Boot通过“约定优于配置”的设计理念,自动检测项目依赖并根据这些依赖自动装配相应的Bean,从而解放开发者从繁琐的配置工作中解脱出来,专注于业务逻辑实现。
2969 0
|
10月前
|
SQL Java 数据库连接
Spring Data JPA 技术深度解析与应用指南
本文档全面介绍 Spring Data JPA 的核心概念、技术原理和实际应用。作为 Spring 生态系统中数据访问层的关键组件,Spring Data JPA 极大简化了 Java 持久层开发。本文将深入探讨其架构设计、核心接口、查询派生机制、事务管理以及与 Spring 框架的集成方式,并通过实际示例展示如何高效地使用这一技术。本文档约1500字,适合有一定 Spring 和 JPA 基础的开发者阅读。
892 0
|
9月前
|
XML Java 数据格式
《深入理解Spring》:AOP面向切面编程深度解析
Spring AOP通过代理模式实现面向切面编程,将日志、事务等横切关注点与业务逻辑分离。支持注解、XML和编程式配置,提供五种通知类型及丰富切点表达式,助力构建高内聚、低耦合的可维护系统。
|
9月前
|
前端开发 Java 微服务
《深入理解Spring》:Spring、Spring MVC与Spring Boot的深度解析
Spring Framework是Java生态的基石,提供IoC、AOP等核心功能;Spring MVC基于其构建,实现Web层MVC架构;Spring Boot则通过自动配置和内嵌服务器,极大简化了开发与部署。三者层层演进,Spring Boot并非替代,而是对前者的高效封装与增强,适用于微服务与快速开发,而深入理解Spring Framework有助于更好驾驭整体技术栈。
|
10月前
|
Java 数据库 数据安全/隐私保护
Spring Boot四层架构深度解析
本文详解Spring Boot四层架构(Controller-Service-DAO-Database)的核心思想与实战应用,涵盖职责划分、代码结构、依赖注入、事务管理及常见问题解决方案,助力构建高内聚、低耦合的企业级应用。
1770 1
|
10月前
|
Kubernetes Java 微服务
Spring Cloud 微服务架构技术解析与实践指南
本文档全面介绍 Spring Cloud 微服务架构的核心组件、设计理念和实现方案。作为构建分布式系统的综合工具箱,Spring Cloud 为微服务架构提供了服务发现、配置管理、负载均衡、熔断器等关键功能的标准化实现。本文将深入探讨其核心组件的工作原理、集成方式以及在实际项目中的最佳实践,帮助开发者构建高可用、可扩展的分布式系统。
811 0

热门文章

最新文章

推荐镜像

更多
  • DNS