@Configuration 原理

一、执行这个注解的位置ConfigurationClassPostProcessor
refresh();invokeBeanFactoryPostProcessors(beanFactory); 在方法中执行beanFactoryPostProcess后置处理器invokeBeanFactoryPostProcessors(registryPostProcessors, beanFactory);执行beanFactoryPostProcess后置处理器执行ConfigurationClassPostProcessor类的postProcessBeanFactory方法
二、postProcessBeanFactoryenhanceConfigurationClasses(beanFactory);1)循环遍历所有的BeanDefinition进行如下操作ConfigurationClassUtils.isFullConfigurationClass(beanDef)判断是否是全注解(这个类是否有@Configuration注解)如果有这个注解将beanDef放到Map中 configBeanDefs.put(beanName, (AbstractBeanDefinition) beanDef); 2)创建new ConfigurationClassEnhancer类,类中创建了三个拦截对象,用于对创建的增强对象进行拦截new BeanMethodInterceptor(),new BeanFactoryAwareMethodInterceptor(),NoOp.INSTANCE这三个类都实现了MethodInterceptor接口3)循环遍历所有的configBeanDefs(其中存放的所有的加了@Configuration的类)进行如下操作enhancer.enhance(configClass, this.beanClassLoader); 通过cglib创建代理对象
三、如何创建代理对象1)if (EnhancedConfiguration.class.isAssignableFrom(configClass)) return configClass;如果是EnhancedConfiguration.class类型则直接返回(在创建完的代理对象后,会给代理对象设置成接口为EnhancedConfiguration类型)换句话来说就是如果是这个类型则代表这个对象已经增强过了2)没有被代理则 createClass(newEnhancer(configClass, classLoader));其中的newEnhancer(configClass, classLoader)Enhancer enhancer = new Enhancer();enhancer.setSuperclass(superclass); //设置增强类继承superclassenhancer.setInterfaces(new Class<?>[] {EnhancedConfiguration.class});  //设置代理对象的实现接口,便于判断是否被增强enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);//设置名字enhancer.setStrategy(new BeanFactoryAwareGeneratorStrategy(classLoader));//在代理类中添加一个属性1.在BeanFactoryAwareGeneratorStrategy的transform方法中declare_field(Constants.ACC_PUBLIC, BEAN_FACTORY_FIELD, Type.getType(BeanFactory.class), null);添加了一个公共的 名字为 BEAN_FACTORY_FIELD常量 的 BeanFactory.class(相当于在@Configuration所在的类中添加了一个BeanFactory类型的成员变量,用于调用getBean获得对象)enhancer.setCallbackFilter(CALLBACK_FILTER); (传入ConfigurationClassEnhancer类中的三个拦截器)new BeanMethodInterceptor(),new BeanFactoryAwareMethodInterceptor(),NoOp.INSTANCEenhancer.setCallbackTypes(CALLBACK_FILTER.getCallbackTypes());
四、是如何增强的主要是这三个过滤器(这里比较难)拦截方法 intercept(Object enhancedConfigInstance, Method beanMethod, Object[] beanMethodArgs,MethodProxy cglibMethodProxy)拦截的beanMethod是@Configuration 所在类中的方法1)new BeanMethodInterceptor(),isCurrentlyInvokedFactoryMethod(beanMethod) //判断调用方法和创建方法是否是同一个如果是创建对象如果不是从ioc容器中获取,如果没有则创建2)new BeanFactoryAwareMethodInterceptor(),3)NoOp.INSTANCE五、如果是static则会失效原因@Configurationpublic class PersionConfig {@Beanpublic static Persion persionBean(){return new com.lizhiyu.studyaspects.Persion();}@Beanpublic Acpects acpectsBean(){persionBean();return new Acpects();}
在ConfigurationClassPostProcessor的 processConfigBeanDefinitions 方法中的this.reader.loadBeanDefinitions(configClasses);loadBeanDefinitionsForConfigurationClass(configClass, trackedConditionEvaluator);loadBeanDefinitionsForBeanMethod(beanMethod);if (metadata.isStatic()) { //如果是静态的 应该是设置成了一个factorybeanbeanDef.setBeanClassName(configClass.getMetadata().getClassName());beanDef.setFactoryMethodName(methodName);}else {beanDef.setFactoryBeanName(configClass.getBeanName());beanDef.setUniqueFactoryMethodName(methodName);}

@Configuration志宇分析相关推荐

  1. 一周年感谢信 | 黑萤科技赖志宇:志同者将道合一处

    一周年感谢信 | 黑萤科技赖志宇:志同者将道合一处 赖志宇 IPFS黑萤科技 1周前 亲爱的萤火虫: 你们好! 自2018年4月30日公司的营业执照下来,黑萤科技已满一周年. 这一年,我们经历过高光时 ...

  2. 志宇-dubbo源码分析

    dubbo源码分析 文档 dubbo加载配置文件 dubboSPI dubbo服务提供 1.校验配置信息 2.创建URL 3.本地注册 4.远程注册 4.1 开启netty服务端 4.2 连接注册中心 ...

  3. 志宇-Spring源码分析

    AnnotationConfigApplicationContext Spring初始化流程 Spring循环依赖 SpringAOP spring注解 @Configuration 一.组件添加 @ ...

  4. 志宇-springSecurty

    springSecurty启动流程 首先EnableWebSecurity 注解导入了WebSecurityConfiguration配置类 @Retention(value = java.lang. ...

  5. SLS-日志服务分析查询

    格式 查询格式 查询语句 | 分析语句 示例 status>200 |select avg(latency),max(latency),count(1) as c GROUP BY method ...

  6. 志宇-RocketMQ学习

    RocketMQ RocketMQ安装 RocketMQ-console安装 RocketMQ简单使用 RabbitMQ核心概念 消息发送状态(返回对象中的枚举类型有4种) 重试次数 RocketMQ ...

  7. 志宇-RabbitMQ学习

    RabbitMQ RabbitMQ安装 RabbitMQ使用 RabbitMQ发送消息步骤图 公平消费和消息可靠性传递 防止重复消费 有序消费 消息堆积怎么处理 spring集成RabbitMQ使用 ...

  8. 志宇-Nginx学习

    Nginx nginx如何去处理一个请求 Nginx可用性探测 Nginx搭建静态资源服务器 Nginx配置https服务 Nginx流量统计 Nginx黑白名单拦截 异常兜底返回 OpenResty ...

  9. 志宇-Jenkins学习

    Jenkins 部署Jenkins 访问Jenkins Jenkins安装插件 Jenkins配置 配置JDK 配置MAVEN 配置Git 配置邮箱 Jenkins配置GitHub Jenkins授权 ...

最新文章

  1. OpenCV 中的 Scalar 类、Vec类
  2. 使用git submodule
  3. 农民代言人谋定农业大健康--万祥军:创业路上功能性农业
  4. wxWidgets:wxDataObjectComposite类用法
  5. 正则表达式高级用法【原】
  6. LeetCode 5843. 作为子字符串出现在单词中的字符串数目
  7. 数智德州,创新未来 | 智慧城市赛题上线山东大赛德州分赛场
  8. [JLOI2016]方
  9. php环境informix,在Nginx + php-fpm(fastcgi)环境下配置informix的连接
  10. 解决svn中“工作副本已经锁定”,或者svn清理失败的解决方法
  11. 设计一个完善可用的服务框架
  12. java 绩效考核系统源码_基于jsp的企业绩效考核系统-JavaEE实现企业绩效考核系统 - java项目源码...
  13. 在PreferenceScreen加入自定义布局
  14. Handler native层实现原理
  15. android端的声音检测程序(检测声音分贝大小)
  16. matlab 多变量求偏导,新手求解两个自变量的函数,求其中一个变量的偏导
  17. 用for循环打印输出数据三角形图形
  18. springboo集成bboss-elasticsearch实现elasticsearch客户端
  19. oracle数据库基础:sqlplus与spool命令
  20. Java_输入输出(Scanner)

热门文章

  1. ChatGPT有同理心吗?
  2. 杭州三日游(第一天)
  3. 【JS】——数组拼接的多种方式包括ES6写法
  4. Git | 常用 指令
  5. oracle自动加载项,exceloracle加载项
  6. 【soft6星评论】腾讯:To C互联网如何实现产业互联网野心?
  7. 工业齿轮润滑油市场现状及未来发展趋势
  8. word 标题编号变成黑色方块怎么解决
  9. 基础算法与数据结构——页面置换算法
  10. Transformer升级之路:长度外推性与位置鲁棒性