Spring AOP 源码解析

本文涉及的产品
全局流量管理 GTM,标准版 1个月
云解析 DNS,旗舰版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: 基于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 接口,从缓存取出所有的将所有的增强器,创建代理工厂,并织入增强器,创建代理对象

调用过程:

待更新...

目录
相关文章
|
11天前
|
XML Java 开发者
Spring底层架构核心概念解析
理解 Spring 框架的核心概念对于开发和维护 Spring 应用程序至关重要。IOC 和 AOP 是其两个关键特性,通过依赖注入和面向切面编程实现了高效的模块化和松耦合设计。Spring 容器管理着 Beans 的生命周期和配置,而核心模块为各种应用场景提供了丰富的功能支持。通过全面掌握这些核心概念,开发者可以更加高效地利用 Spring 框架开发企业级应用。
54 18
|
2月前
|
设计模式 存储 安全
【23种设计模式·全精解析 | 创建型模式篇】5种创建型模式的结构概述、实现、优缺点、扩展、使用场景、源码解析
创建型模式的主要关注点是“怎样创建对象?”,它的主要特点是"将对象的创建与使用分离”。这样可以降低系统的耦合度,使用者不需要关注对象的创建细节。创建型模式分为5种:单例模式、工厂方法模式抽象工厂式、原型模式、建造者模式。
【23种设计模式·全精解析 | 创建型模式篇】5种创建型模式的结构概述、实现、优缺点、扩展、使用场景、源码解析
|
2月前
|
设计模式 XML Java
【23种设计模式·全精解析 | 自定义Spring框架篇】Spring核心源码分析+自定义Spring的IOC功能,依赖注入功能
本文详细介绍了Spring框架的核心功能,并通过手写自定义Spring框架的方式,深入理解了Spring的IOC(控制反转)和DI(依赖注入)功能,并且学会实际运用设计模式到真实开发中。
【23种设计模式·全精解析 | 自定义Spring框架篇】Spring核心源码分析+自定义Spring的IOC功能,依赖注入功能
|
2月前
|
存储 设计模式 算法
【23种设计模式·全精解析 | 行为型模式篇】11种行为型模式的结构概述、案例实现、优缺点、扩展对比、使用场景、源码解析
行为型模式用于描述程序在运行时复杂的流程控制,即描述多个类或对象之间怎样相互协作共同完成单个对象都无法单独完成的任务,它涉及算法与对象间职责的分配。行为型模式分为类行为模式和对象行为模式,前者采用继承机制来在类间分派行为,后者采用组合或聚合在对象间分配行为。由于组合关系或聚合关系比继承关系耦合度低,满足“合成复用原则”,所以对象行为模式比类行为模式具有更大的灵活性。 行为型模式分为: • 模板方法模式 • 策略模式 • 命令模式 • 职责链模式 • 状态模式 • 观察者模式 • 中介者模式 • 迭代器模式 • 访问者模式 • 备忘录模式 • 解释器模式
【23种设计模式·全精解析 | 行为型模式篇】11种行为型模式的结构概述、案例实现、优缺点、扩展对比、使用场景、源码解析
|
2月前
|
设计模式 存储 安全
【23种设计模式·全精解析 | 创建型模式篇】5种创建型模式的结构概述、实现、优缺点、扩展、使用场景、源码解析
结构型模式描述如何将类或对象按某种布局组成更大的结构。它分为类结构型模式和对象结构型模式,前者采用继承机制来组织接口和类,后者釆用组合或聚合来组合对象。由于组合关系或聚合关系比继承关系耦合度低,满足“合成复用原则”,所以对象结构型模式比类结构型模式具有更大的灵活性。 结构型模式分为以下 7 种: • 代理模式 • 适配器模式 • 装饰者模式 • 桥接模式 • 外观模式 • 组合模式 • 享元模式
【23种设计模式·全精解析 | 创建型模式篇】5种创建型模式的结构概述、实现、优缺点、扩展、使用场景、源码解析
|
1月前
|
监控 JavaScript 数据可视化
建筑施工一体化信息管理平台源码,支持微服务架构,采用Java、Spring Cloud、Vue等技术开发。
智慧工地云平台是专为建筑施工领域打造的一体化信息管理平台,利用大数据、云计算、物联网等技术,实现施工区域各系统数据汇总与可视化管理。平台涵盖人员、设备、物料、环境等关键因素的实时监控与数据分析,提供远程指挥、决策支持等功能,提升工作效率,促进产业信息化发展。系统由PC端、APP移动端及项目、监管、数据屏三大平台组成,支持微服务架构,采用Java、Spring Cloud、Vue等技术开发。
|
21天前
|
自然语言处理 数据处理 索引
mindspeed-llm源码解析(一)preprocess_data
mindspeed-llm是昇腾模型套件代码仓,原来叫"modelLink"。这篇文章带大家阅读一下数据处理脚本preprocess_data.py(基于1.0.0分支),数据处理是模型训练的第一步,经常会用到。
42 0
|
3月前
|
缓存 监控 Java
Java线程池提交任务流程底层源码与源码解析
【11月更文挑战第30天】嘿,各位技术爱好者们,今天咱们来聊聊Java线程池提交任务的底层源码与源码解析。作为一个资深的Java开发者,我相信你一定对线程池并不陌生。线程池作为并发编程中的一大利器,其重要性不言而喻。今天,我将以对话的方式,带你一步步深入线程池的奥秘,从概述到功能点,再到背景和业务点,最后到底层原理和示例,让你对线程池有一个全新的认识。
72 12
|
2月前
|
PyTorch Shell API
Ascend Extension for PyTorch的源码解析
本文介绍了Ascend对PyTorch代码的适配过程,包括源码下载、编译步骤及常见问题,详细解析了torch-npu编译后的文件结构和三种实现昇腾NPU算子调用的方式:通过torch的register方式、定义算子方式和API重定向映射方式。这对于开发者理解和使用Ascend平台上的PyTorch具有重要指导意义。
|
2月前
|
存储 缓存 Java
Spring面试必问:手写Spring IoC 循环依赖底层源码剖析
在Spring框架中,IoC(Inversion of Control,控制反转)是一个核心概念,它允许容器管理对象的生命周期和依赖关系。然而,在实际应用中,我们可能会遇到对象间的循环依赖问题。本文将深入探讨Spring如何解决IoC中的循环依赖问题,并通过手写源码的方式,让你对其底层原理有一个全新的认识。
69 2

推荐镜像

更多