范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文
国学影视

Spring中的Configuration注解你真的了解吗?

  环境:Springboot2.3.12.RELEASE
  关于使用@Configuration注解后为何 类内部使用@Bean注解方法声明的方法在多次调用后会是返回相同的实例? 1 示例
  如下:  @Configuration  public class BeanConfig {            @Bean      public Date date() {          CustomerDAO c1 = customer() ;          CustomerDAO c2 = customer() ;          System.out.println("c1 = " + c1) ;          System.out.println("c2 = " + c2) ;          return new Date() ;      }            @Bean      public CustomerDAO customer() {          return new CustomerDAO() ;      }        }
  输出:  c1 = com.pack.config.CustomerDAO@1c0cf193  c2 = com.pack.config.CustomerDAO@1c0cf193
  将上面的@Configuration注解换成@Component后再次运行:  c1 = com.pack.config.CustomerDAO@7b7e4b20  c2 = com.pack.config.CustomerDAO@5ac0bf84
  多个实例。 2 原理
  使用@Configuration注解的类会为何会保证多次方法的调用返回的是同一个实例? 2.1 创建Spring上下文
  创建上下文最核心的就是注册了一个 BeanFactory  处理器  public class SpringApplication {      public ConfigurableApplicationContext run(String... args) {          ConfigurableApplicationContext context = null;          context = createApplicationContext();      }      protected ConfigurableApplicationContext createApplicationContext() {          return this.applicationContextFactory.create(this.webApplicationType);      }  }
  跟踪createApplicationContext方法  public class SpringApplication {      protected ConfigurableApplicationContext createApplicationContext() {          return this.applicationContextFactory.create(this.webApplicationType);      }  }
  进入 ApplicationContextFactory   public interface ApplicationContextFactory {      ApplicationContextFactory DEFAULT = (webApplicationType) -> {          try {              switch (webApplicationType) {              case SERVLET:                  // 当前是基于SERVLET容器的,所以创建下面这个实例                  return new AnnotationConfigServletWebServerApplicationContext();              case REACTIVE:                  return new AnnotationConfigReactiveWebServerApplicationContext();              default:                  return new AnnotationConfigApplicationContext();              }          }      };  }
  进入 AnnotationConfigServletWebServerApplicationContext   public class AnnotationConfigServletWebServerApplicationContext extends ServletWebServerApplicationContext          implements AnnotationConfigRegistry {      public AnnotationConfigServletWebServerApplicationContext() {          this.reader = new AnnotatedBeanDefinitionReader(this);          this.scanner = new ClassPathBeanDefinitionScanner(this);      }  }
  进入 AnnotatedBeanDefinitionReader  构造方法  public class AnnotatedBeanDefinitionReader {      public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) {          this(registry, getOrCreateEnvironment(registry));      }      public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {          this.registry = registry;          this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);          // 核心方法,这里非常重要,会注册系统的一些处理器          AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);      }  }
  进入 AnnotationConfigUtils#registerAnnotationConfigProcessors  方法  public abstract class AnnotationConfigUtils {      public static void registerAnnotationConfigProcessors(BeanDefinitionRegistry registry) {          registerAnnotationConfigProcessors(registry, null);      }  }
  进入 AnnotationConfiguUtils#registerAnnotationConfigProcessors  方法  public class AnnotationBeanDefinitionReader {      public static final String CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME =              "org.springframework.context.annotation.internalConfigurationAnnotationProcessor";      public static Set registerAnnotationConfigProcessors(              BeanDefinitionRegistry registry, @Nullable Object source) {          // ...          // 判断当前上下文中是否有internalConfigurationAnnotationProcessor          // 没有则注册专门用来处理@Configuration注解的          // ConfigurationClassPostProcessor处理器          if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {              RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);              def.setSource(source);              beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));          }          // ...          return beanDefs;      }  }
  以上在创建Spring上下文对象的时候注册了一个非常核心的处理器 ConfigurationClassPostProcessor  该类会处理带有@Configuration注解的类。 2.2 执行处理器
  这里就会执行上一步中注册的 BeanFactoryPostProcessor  。
  上面注册的 ConfigurationClassPostProcessor  实现了 BeanFactoryPostProcessor  接口  public class SpringApplication {      public ConfigurableApplicationContext run(String... args) {          ConfigurableApplicationContext context = null;          context = createApplicationContext();          // 刷新上下文          refreshContext(context);      }  }
  跟踪refreshContext方法,进入到如下代码执行  public abstract class AbstractApplicationContext extends DefaultResourceLoader          implements ConfigurableApplicationContext {      public void refresh() throws BeansException, IllegalStateException {          synchronized (this.startupShutdownMonitor) {              // ...              // 执行BeanFactoryPostProcessor中的回调方法              invokeBeanFactoryPostProcessors(beanFactory);              // ...          }      }  }
  进入invokeBeanFactoryPostProcessors方法  public abstract class AbstractApplicationContext extends DefaultResourceLoader          implements ConfigurableApplicationContext {      protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {          PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());      }  }
  进入invokeBeanfactoryPostProcessors方法
  注意ConfigurationClassPostProcessor实现了 BeanDefinitionRegistryPostProcessor  也实现了 BeanFactoryPostProcessor  接口,这里方法的执行是会先执行 BeanDefinitionRegistryPostProcessor  的回调方法,最后再执行 BeanFactoryPostProcessor  中的回调方法。
  执行流程为: ConfigurationClassPostProcessor#postProcessBeanDefinitionRegistry  该方法主要左右通过方法名称也能猜到处理并注册当前CLASSPATH下的所有类中符合条件的Bean。 ConfigurationClassPostProcessor#postProcessBeanFactory  该方法的作用  final class PostProcessorRegistrationDelegate {      public static void invokeBeanFactoryPostProcessors(              ConfigurableListableBeanFactory beanFactory, List beanFactoryPostProcessors) {          // ...          // Now, invoke the postProcessBeanFactory callback of all processors handled so far.          // 执行ConfigurationClassPostProcessor#postProcessBeanFactory方法          invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);          invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);      }      private static void invokeBeanFactoryPostProcessors(              Collection<? extends BeanFactoryPostProcessor> postProcessors, ConfigurableListableBeanFactory beanFactory) {          // 执行ConfigurationClassPostProcessor中的回调          for (BeanFactoryPostProcessor postProcessor : postProcessors) {              postProcessor.postProcessBeanFactory(beanFactory);          }      }  }
  进入 ConfigurationClassPostProcessor#postProcessBeanFactory  方法  public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPostProcessor,  PriorityOrdered, ResourceLoaderAware,   ApplicationStartupAware, BeanClassLoaderAware, EnvironmentAware {      public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {          // 增强配置类          enhanceConfigurationClasses(beanFactory);          beanFactory.addBeanPostProcessor(new ImportAwareBeanPostProcessor(beanFactory));      }  }2.3 增强配置类
  接着上面进入enhanceConfigurationClasses方法  public class ConfigurationClassPostProcessor {      public void enhanceConfigurationClasses(ConfigurableListableBeanFactory beanFactory) {          Map configBeanDefs = new LinkedHashMap<>();          // 遍历当前上下文中注册的所有BeanDefinition集合,找到所有的配置类          // 这里会就会找到两个,一个是启动类,一个是上面示例中的配置类BeanConfig          for (String beanName : beanFactory.getBeanDefinitionNames()) {              BeanDefinition beanDef = beanFactory.getBeanDefinition(beanName);              // ...              configBeanDefs.put(beanName, (AbstractBeanDefinition) beanDef);          }          if (configBeanDefs.isEmpty() || NativeDetector.inNativeImage()) {              // nothing to enhance -> return immediately              enhanceConfigClasses.end();              return;          }            ConfigurationClassEnhancer enhancer = new ConfigurationClassEnhancer();          // 遍历找到所有的@Configuration配置类          for (Map.Entry entry : configBeanDefs.entrySet()) {              AbstractBeanDefinition beanDef = entry.getValue();              // If a @Configuration class gets proxied, always proxy the target class              beanDef.setAttribute(AutoProxyUtils.PRESERVE_TARGET_CLASS_ATTRIBUTE, Boolean.TRUE);              // Set enhanced subclass of the user-specified bean class              Class<?> configClass = beanDef.getBeanClass();              // 这里就将BeanConfig配置类进行创建代理              Class<?> enhancedClass = enhancer.enhance(configClass, this.beanClassLoader);              if (configClass != enhancedClass) {                  beanDef.setBeanClass(enhancedClass);              }          }      }  }
  进入 ConfigurationClassEnhancer#enhance  方法  class ConfigurationClassEnhancer {        // The callbacks to use. Note that these callbacks must be stateless.      private static final Callback[] CALLBACKS = new Callback[] {              new BeanMethodInterceptor(),              new BeanFactoryAwareMethodInterceptor(),              NoOp.INSTANCE      };      private static final ConditionalCallbackFilter CALLBACK_FILTER = new ConditionalCallbackFilter(CALLBACKS);      public Class<?> enhance(Class<?> configClass, @Nullable ClassLoader classLoader) {          if (EnhancedConfiguration.class.isAssignableFrom(configClass)) {              return configClass;          }          // 创建代理类          Class<?> enhancedClass = createClass(newEnhancer(configClass, classLoader));          return enhancedClass;      }      private Enhancer newEnhancer(Class<?> configSuperClass, @Nullable ClassLoader classLoader) {          Enhancer enhancer = new Enhancer();          enhancer.setSuperclass(configSuperClass);          enhancer.setInterfaces(new Class<?>[] {EnhancedConfiguration.class});          enhancer.setUseFactory(false);          enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);          enhancer.setStrategy(new BeanFactoryAwareGeneratorStrategy(classLoader));          // 这里就是设置代理类执行的方法拦截器          // 最核心的就是上面的BeanMethodInterceptor类          enhancer.setCallbackFilter(CALLBACK_FILTER);          enhancer.setCallbackTypes(CALLBACK_FILTER.getCallbackTypes());          return enhancer;      }  }
  进入 BeanMethodInterceptor  类  private static class BeanMethodInterceptor implements MethodInterceptor, ConditionalCallback {      public Object intercept(Object enhancedConfigInstance, Method beanMethod, Object[] beanMethodArgs,                              MethodProxy cglibMethodProxy) throws Throwable {            // ...           // 该方法中就是从Spring容器中获取当前的Bean          return resolveBeanReference(beanMethod, beanMethodArgs, beanFactory, beanName);      }  }
  进入resolveBeanReference方法  class ConfigurationClassEnhancer {      private Object resolveBeanReference(Method beanMethod, Object[] beanMethodArgs,                  ConfigurableBeanFactory beanFactory, String beanName) {          Object beanInstance = (useArgs ? beanFactory.getBean(beanName, beanMethodArgs) :                          beanFactory.getBean(beanName));          return beanInstance ;      }  }
  完毕!!!
  求个关注+转发
  Spring 自定义Advisor以编程的方式实现AOP
  SpringBoot WebFlux整合Spring Security进行权限认证
  Springboot Security 基础应用 (1)
  Springboot中Redis事务的使用及Lua脚本
  SpringCloud Feign实现原理源分析
  Spring Cloud全链路追踪SkyWalking及整合Elasticsearch
  Spring Cloud 微服务日志收集管理Elastic Stack完整详细版
  Spring Cloud链路追踪zipkin及整合Elasticsearch存储
  Spring Cloud Gateway应用详解2内置过滤器
  Spring通过源码分析了解这3种Bean处理器的执行过程
  SpringBoot集群环境下使用Redis实现Session共享

小S女儿富江杀青,小时候不起眼长大变漂亮的星二代还有谁?最近,小S的大女儿许曦文发布动态,表示杀青了,那天风好大。原来,是为了纪念她参演台版富江的杀青。许曦文还配了一张自己的靓照,穿着红衣的她手捧鲜花,虽然她看起来没化什么妆,但皮肤状态30岁女星突然官宣怀孕!被冯小刚导演一手捧红,孩子父亲身份成谜30岁女星隋源官宣怀孕8月底。知名女星隋源,突然在个人社媒上高调官宣自己已经怀孕了,让网友有一点措手不及。隋源晒出了自己做B超的照片,照片中显示隋源的确已经怀上了孩子,另外隋源还不每年花费约9286元,解析比亚迪海豹养车成本近段时间,在国内的新能源汽车市场领域内,比亚迪海豹的热度一直都比较高。而据笔者此前了解的信息来看,比亚迪海豹在上市当天的订单量就已经超过了6万辆,可见大家对于这款车的期待还是比较高曹云金朋友别处辞职叫跳槽,德云社辞职叫叛徒?郭德纲不讲武德最近,有个自称是曹云金朋友的人,不停地私信我,要跟我交流,话题无非是那些关于退社或者在德云社很倒霉一退出就变成叛徒之类的话。在这里我单开一篇说一下我自己的看法,此后再也不提,也不会公然抗法包庇商家继续出售变质食品流氓平台拼多多已成国民毒瘤拼多多自上市以来,便因为虚假产品虚假活动虚假宣传而纷争不断。近期再次闹出一桩公然违法包庇纵容商家继续出售发霉变质食品丑闻。据悉,8月19日,一名拼多多用户在平台上一家名为呈念食品专黑龙江省文化旅游形象LOGO什么样?宣传推广平台的名字叫什么?黑龙江省文化旅游形象LOGO什么样?宣传推广平台的名字叫什么?今天,见分晓了!看看这条龙腾虎跃多彩的龙,就是今天黑龙江省文化和旅游厅揭晓的黑龙江省文化旅游形象LOGOLOGO融入1台积电猜对了?中芯正式宣布后!美索要数据的理由彻底站不住了在去年的时候,美对很多芯片巨头们都索要了关键的数据,其中包括了三星台积电等国际代工大巨头。当然,一开始的时候,三星和台积电等都不愿意交出数据,毕竟数据一被交出去,很容易降低他们在行道天录武神殿,PvP装备技能阵容推荐头条创作挑战赛说起武神殿里无外乎阵容装备技能搭配等,都已经是老生常谈了。双方如果阵容相似,输赢除了看脸之外,还有小细节的差距比如技能搭配装备穿戴等。随着新轮回者不断增多,团队阵容可射手群回归,杜兰特扭转局势!欧文内部瓦解篮网,詹姆斯还在坚持对于篮网来说,他们的休赛期只是过去了一周时间。自从杜兰特宣布归队之后,篮网用一份双向合同续约了年轻球员大卫杜克,昨天更是用一份底薪合同签下了马基夫莫里斯,可以看出,篮网正在有益地补2款边骑边充电的电动车,最高续航150km,2小时快充,男女都适合阅读本文前,请您先点击上面的关注,这样您就可以免费收到我们的最新内容,感谢支持说到选购电动车,最注意的两点硬件要求就是电机和电池,在保证续航持久的情况下,电动车的智能水平也是现在车千城之战!重返帝国开荒最快的保姆级攻略启蒙时代新一代策略手游重返帝国新版本千城之战即将重磅打响,想要参与这场战役的萌新玩家不要急!超贴心的保姆级开荒攻略现在奉上,手把手护你崛起。只需要1分钟,从扫盲入门到萌新大神启蒙时代在遵循
一个人的时候我们来到这个世界,身不由己我们离开这个世界,迫不得已。一辈子只能活一次,没有谁会一直护佑着你,等你已经长大了,父母变老了,我们必须得靠自己,靠自己,把自己成全!我们不管走到哪里,路关于写作疗愈1。给我一支铅笔,一张白纸,我就有了全世界。在这里就是我的天下,老子天下第一,我可以是艺术家,军事家,作家可以是任何想成为的,可以放下任何你想放下的一切,坏的情绪,坏的感受等一切负中日双语稻盛和夫经典名言培养能感受到幸福的心心純粋行動成功心美。心灵要纯粹行动的成功,源于美好的心灵。人自分一人生。私今日生存分慟空気水食料地球環境社会家族職場仲間至自分取卷支。人无法单独活在这个世界上。我们今来杯2023,加糖,去冰,愿来年温暖如常,美好如初日子不紧不慢地过着,漂泊了青春,洗尽了铅华。这个冬天,尤其的冷。持续的低温,冰冷了心情,却冻结不了希望。水到绝处是瀑布,人到绝境是重生。相信,一切都是老天最好的安排。困境绝境,都是果粉狂喜!苹果官网亲自下场降价!网友少见,幸福很突然!众所周知,iPhone以及众多苹果设备的价格一直分为三挡。第一档位就是苹果官网和官方直营店,价格一般都是发行价,除非官网进行调价(比如因为汇率涨价或者降价),价格一向坚挺,官方也一你好BOE完美收官屏之物联肇启智慧美好未来新篇章12月28日,BOE(京东方)你好BOEOSPACE美好生活研究所重磅亮相北京三里屯太古里这一顶级时尚潮流地标,伴随着浓浓的跨年气氛,为这个极不平凡的2022年划上了精彩的句号。作2022天翼数字科技生态大会来了!看天翼云数智起笔绘就美好生活数字技术日新月异,为经济社会发展插上数字翅膀。云计算大数据等技术与传统产业深度融合,催生新业态新模式,引领经济社会全面变革。云服务与应用的广泛落地,正深切地改变着人们的生活。深山蜂零售业复苏元年将至实体门店如何突围?都市丽人启动百城千店营销战役本文来源时代周报作者肖宇在大环境的冲击之下,近三年来,挑战与考验已经成为终端实体店日常经营的关键词。无论是门店亦或是企业,升级转型都充满了不确定性。如今,随着全国经济迎来全面复苏,看2023黑弓创始人王志鸥推动中华优秀传统文化创新性发展站在2022岁末,看2023年,企业家作为中国经济的重要力量,如何看待当前的中国经济政策,对未来中国经济有何期待?新京报贝壳财经邀请百余位来自各行各业的企业家,以问卷方式完成对新一儿童性侵案频发,是时候教会孩子们自我保护了根据女童保护统计,2021年全年媒体公开报道的性侵儿童(18岁以下)案例223起,受害人数569人(未表明具体人数的案例中,多人按3人计,十几人按15人计,几十人数十人按30人计)男性比女性天生拥有更好的方向感吗?几百万年前的远古人类给出了答案(图片来源Pxhere)撰文阿娴审校Ziv现在,抬头!你能准确分辨你现在所面朝的方向是东南西北哪个方向吗?随着城市道路建设越来越复杂,人们的出行也更加依赖于导航,但是在处理相同的导