一、AopConfigUtils.registerAutoProxyCreatorIfNecessary(registry);
该方法调用主要功能为:
- 检查并确保配置了自动代理创建器(Auto Proxy Creator);
- 如未配置,则进行注册,以便支持AOP(面向切面编程)功能;
1.1 BeanDefinitionRegistry
我有点疑惑,BeanDefinitionRegistry里的beanDefinitionMap放了很多类名,仿佛@Service、@Controller注解等都会出现在这里:
BeanDefinitionRegistry 类的作用:
- 注册Bean定义::允许在运行时动态地向Spring IoC容器中注册新的Bean定义。
- 管理Bean生命周期:提供接口来管理Bean定义的注册、存储和查询。
- 支持动态配置:支持在应用运行期间动态更改或扩展Bean定义;
beanDefinitionMap 的作用:
- 存储Bean定义:作为BeanDefinitionRegistry内部的数据结构,用来存储所有已注册的Bean定义;
- 快速查找:通过Bean名称快速查找对应的Bean定义信息,支持依赖注入等功能‘;
- 维护依赖关系:帮助维护Bean之间的依赖关系,确保正确的初始化顺序;
1.1.2 关于beanDefinitionMap的一些疑问
1.1.2.1 BeanDefinitionRegistry里的beanDefinitionMap什么时候会把类名放进来,以及什么时候会把这些类注入?
BeanDefinitionRegistry 的 beanDefinitionMap 通常在以下场景中填充类定义信息:
- 通过XML配置:当使用基于XML的配置文件时,在Spring容器启动过程中解析这些配置文件时,会将其中定义的bean信息注册到 BeanDefinitionRegistry 中。
- 通过注解配置:当使用注解(如 @Component, @Service, @Repository, 或 @Configuration 等)时,在Spring容器初始化阶段扫描指定包路径下的类时,会自动检测带有这些注解的类,并将其注册到 BeanDefinitionRegistry 中。
至于类的注入时机:
- 容器初始化时:在Spring容器完成所有bean定义的加载后,它会根据bean之间的依赖关系进行依赖注入。
- 按需创建时:对于那些懒加载(lazy-init)的bean,它们的依赖注入会在第一次请求时发生。
以上过程都是Spring框架内部自动管理的,无需开发者手动干预。
1.1.2.2 放到BeanDefinitionRegistry 的beanDefinitionMap中的类,是已经注入到spring容器了吗?
放入 BeanDefinitionRegistry 的 beanDefinitionMap 中的类并不是直接实例化后的对象,而是 BeanDefinition 对象,它描述了如何实例化一个类(例如,类名、构造函数参数、依赖项等)。当一个类的 BeanDefinition 被添加到 beanDefinitionMap 中时,这意味着Spring容器知道了如何创建该类的一个实例,但它并不意味着类已经被实例化或注入到容器中。
类的实际实例化(即创建一个具体的对象)会在以下几种情况下发生:
- 容器启动时:如果类被标记为非懒加载(non-lazy-init),则在容器初始化完成时,所有的非懒加载bean会被实例化。
- 按需创建:如果类被标记为懒加载(lazy-init),那么它的实例将在首次请求时创建。
- 显式创建:通过 ApplicationContext 或 BeanFactory 的 getBean 方法显式获取bean时,如果该bean尚未被创建,那么它将在此时被创建。
因此,beanDefinitionMap 中的条目表示的是待创建的bean的配置信息,而不是实际的对象实例。只有当需要具体使用这些bean时,Spring容器才会根据这些配置信息来创建相应的对象实例。
1.2 AopConfigUtils.registerAutoProxyCreatorIfNecessary(registry);
讲完了题外话,继续追踪代码:
注意这个类:InfrastructureAdvisorAutoProxyCreator.class,就是要创建或升级这个类。
直接到AopConfigUtils#registerOrEscalateApcAsRequired:
该方法强制自动代理创建器使用基于类的代理,而非接口代理。作用包括:
- 修改代理类型以适应更广泛的方法调用场景。
- 确保AOP(面向切面编程)功能在特定环境下正常工作。
该函数检查指定的BeanDefinitionRegistry中是否包含名为internalAutoProxyCreator的bean定义。如果存在,则修改其配置以强制使用类代理而非接口代理。
- 检查registry中是否存在特定的自动代理创建者。
- 若存在,则获取其BeanDefinition。
- 设置proxyTargetClass属性为true,强制使用类代理。
注意,这里的BeanDefinition是AnnotationAwareAspectJAutoProxyCreator类。
这里走完后,就加一个属性了。