【源码分析】@Configuration源码分析2

谁借莪1个温暖的怀抱¢ 2023-10-08 17:36 110阅读 0赞

@Configuration源码分析1

@Configuration源码分析2

使用版本:5.3.22

1.注册ConfigurationClassPostProcessor流程源码解析

下面开始搞@Configuration注解涉及到的ConfigurationClassPostProcessor核心类的注册流程的源码执行过程。

1.启动类ConfigurationDemo的main()方法

在main()方法中会调用AnnotationConfigApplicationContext类的构造方法传入配置类ConfigurationAnnotationConfig的Class对象来创建IOC容器。

  1. public static void main(String[] args) {
  2. AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ConfigurationAnnotationConfig.class);
  3. }

2.解析AnnotationConfigApplicationContext类的AnnotationConfigApplicationContext(Class<?>… componentClasses)构造方法

  1. public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
  2. this();
  3. register(componentClasses);
  4. refresh();
  5. }

在上述构造方法中,会通过this()调用AnnotationConfigApplicationContext类的无参构造方法。

3.解析AnnotationConfigApplicationContext类的AnnotationConfigApplicationContext()无参构造方法

  1. public AnnotationConfigApplicationContext() {
  2. StartupStep createAnnotatedBeanDefReader = this.getApplicationStartup().start("spring.context.annotated-bean-reader.create");
  3. //表示注解类型的Bean定义信息读取器,主要就是读取通过注解方式进行实例化的Bean的定义信息。
  4. this.reader = new AnnotatedBeanDefinitionReader(this);
  5. createAnnotatedBeanDefReader.end();
  6. //表示类路径下的Bean定义扫描器,主要就是扫描类路径下的Bean定义信息。
  7. this.scanner = new ClassPathBeanDefinitionScanner(this);
  8. }

在AnnotationConfigApplicationContext类的无参构造方法中,主要的逻辑就是实例化了AnnotatedBeanDefinitionReader类型的reader成员变量和ClassPathBeanDefinitionScanner类型的scanner成员变量。

@Configuration注解涉及到的注册流程源码的执行过程,会执行实例化reader成员变量的代码.

  1. this.scanner = new ClassPathBeanDefinitionScanner(this);

下面在调用:

  1. public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) {
  2. this(registry, getOrCreateEnvironment(registry));
  3. }

在上述构造方法中,通过this调用了AnnotatedBeanDefinitionReader类的AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment)构造方法。

4.解析 AnnotatedBeanDefinitionReader#AnnotatedBeanDefinitionReader

  1. public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {
  2. Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
  3. Assert.notNull(environment, "Environment must not be null");
  4. this.registry = registry;
  5. this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);
  6. AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
  7. }

在上述构造方法中,最核心的逻辑就是调用了AnnotationConfigUtils工具类的registerAnnotationConfigProcessors()方法,将BeanDefinitionRegistry类型的registry对象传入方法中。

registry对象本质上就是一个AnnotationConfigApplicationContext类对象的实例,这是因为AnnotationConfigApplicationContext类继承了GenericApplicationContext类,而GenericApplicationContext类实现了BeanDefinitionRegistry接口。

如下:

  1. public class AnnotationConfigApplicationContext extends GenericApplicationContext {
  2. }
  3. public class GenericApplicationContext extends AbstractApplicationContext implements BeanDefinitionRegistry {
  4. }

5.解析AnnotationConfigUtils# registerAnnotationConfigProcessors

  1. public static void registerAnnotationConfigProcessors(BeanDefinitionRegistry registry) {
  2. registerAnnotationConfigProcessors(registry, null);
  3. }

在AnnotationConfigUtils类的registerAnnotationConfigProcessors(BeanDefinitionRegistry registry)方法中调用了AnnotationConfigUtils类中的另外一个registerAnnotationConfigProcessors()方法。

再往下看 registerAnnotationConfigProcessors()方法

此方法主要是将@Configuration注解涉及到的ConfigurationClassPostProcessor类的Bean定义信息注册到IOC容器中的核心代码。

  1. public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
  2. BeanDefinitionRegistry registry, @Nullable Object source) {
  3. DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
  4. if (beanFactory != null) {
  5. if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
  6. beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
  7. }
  8. if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
  9. beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
  10. }
  11. }
  12. Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);
  13. // 会调用registerPostProcessor()方法注册后置处理器。
  14. if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
  15. RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
  16. def.setSource(source);
  17. beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
  18. }
  19. if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
  20. RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
  21. def.setSource(source);
  22. beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
  23. }
  24. // Check for JSR-250 support, and if present add the CommonAnnotationBeanPostProcessor.
  25. if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {
  26. RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);
  27. def.setSource(source);
  28. beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));
  29. }
  30. // Check for JPA support, and if present add the PersistenceAnnotationBeanPostProcessor.
  31. if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) {
  32. RootBeanDefinition def = new RootBeanDefinition();
  33. try {
  34. def.setBeanClass(ClassUtils.forName(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME,
  35. AnnotationConfigUtils.class.getClassLoader()));
  36. }
  37. catch (ClassNotFoundException ex) {
  38. throw new IllegalStateException(
  39. "Cannot load optional framework class: " + PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, ex);
  40. }
  41. def.setSource(source);
  42. beanDefs.add(registerPostProcessor(registry, def, PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME));
  43. }
  44. if (!registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME)) {
  45. RootBeanDefinition def = new RootBeanDefinition(EventListenerMethodProcessor.class);
  46. def.setSource(source);
  47. beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_PROCESSOR_BEAN_NAME));
  48. }
  49. if (!registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME)) {
  50. RootBeanDefinition def = new RootBeanDefinition(DefaultEventListenerFactory.class);
  51. def.setSource(source);
  52. beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_FACTORY_BEAN_NAME));
  53. }
  54. return beanDefs;
  55. }

这里会调用registerPostProcessor()方法注册后置处理器。

  1. // 会调用registerPostProcessor()方法注册后置处理器。
  2. if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
  3. RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
  4. def.setSource(source);
  5. beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
  6. }

6.解析registerPostProcessor方法

  1. private static BeanDefinitionHolder registerPostProcessor(
  2. BeanDefinitionRegistry registry, RootBeanDefinition definition, String beanName) {
  3. definition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
  4. registry.registerBeanDefinition(beanName, definition);
  5. return new BeanDefinitionHolder(definition, beanName);
  6. }

代码主要是,调用了registry参数的registerBeanDefinition()方法来注册ConfigurationClassPostProcessor类的Bean定义信息,definition参数本质上就是一个AnnotationConfigApplicationContext类的实例对象。
最终会调用DefaultListableBeanFactory类的registerBeanDefinition()方法来注册ConfigurationClassPostProcessor类的Bean定义信息。

7.解析DefaultListableBeanFactory#registerBeanDefinition方法

  1. @Override
  2. public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
  3. throws BeanDefinitionStoreException {
  4. this.beanDefinitionMap.put(beanName, beanDefinition);
  5. }

主要看这一行代码,Spring的IOC容器中注册类的Bean定义信息,其实就是向beanDefinitionMap对象中添加元素,beanDefinitionMap对象本质上是一个ConcurrentHashMap对象。向beanDefinitionMap对象中添加的元素的Key为Bean的名称,Value为Bean的定义信息。

  1. private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);

到这@Configuration注解涉及到的ConfigurationClassPostProcessor类的注册过程分析完成了,可以多看几遍理解就好,记住谁也记不住。

2.注册ConfigurationAnnotationConfig 源码解析

启动Spring IOC容器时,向IOC容器中注册ConfigurationAnnotationConfig类的Bean定义信息的源码。

1.启动类ConfigurationDemo的main()方法

在main()方法中会调用AnnotationConfigApplicationContext类的构造方法传入配置类ConfigurationAnnotationConfig的Class对象来创建IOC容器。

  1. public static void main(String[] args) {
  2. AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ConfigurationAnnotationConfig.class);
  3. }

2.解析AnnotationConfigApplicationContext类的AnnotationConfigApplicationContext(Class<?>… componentClasses)构造方法

  1. public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
  2. this();
  3. register(componentClasses);
  4. refresh();
  5. }

在register(Class<?>… componentClasses)方法中调用了reader的register()方法。

  1. @Override
  2. public void register(Class<?>... componentClasses) {
  3. Assert.notEmpty(componentClasses, "At least one component class must be specified");
  4. StartupStep registerComponentClass = this.getApplicationStartup().start("spring.context.component-classes.register")
  5. .tag("classes", () -> Arrays.toString(componentClasses));
  6. this.reader.register(componentClasses);
  7. registerComponentClass.end();
  8. }

3.解析AnnotatedBeanDefinitionReader # register

  1. public void register(Class<?>... componentClasses) {
  2. for (Class<?> componentClass : componentClasses) {
  3. registerBean(componentClass);
  4. }
  5. }

循环遍历传入的可变参数componentClasses,每次循环时,都会调用registerBean()方法。

4.解析AnnotatedBeanDefinitionReader# doRegisterBean

  1. public void registerBean(Class<?> beanClass) {
  2. doRegisterBean(beanClass, null, null, null, null);
  3. }

主要部分会用注释备注:

  1. // 从给定的bean类注册bean,从类声明的注释派生其元数据。
  2. private <T> void doRegisterBean(Class<T> beanClass, @Nullable String name,
  3. @Nullable Class<? extends Annotation>[] qualifiers, @Nullable Supplier<T> supplier,
  4. @Nullable BeanDefinitionCustomizer[] customizers) {
  5. AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass);
  6. if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
  7. return;
  8. }
  9. abd.setInstanceSupplier(supplier);
  10. ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
  11. abd.setScope(scopeMetadata.getScopeName());
  12. String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));
  13. AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
  14. if (qualifiers != null) {
  15. for (Class<? extends Annotation> qualifier : qualifiers) {
  16. if (Primary.class == qualifier) {
  17. abd.setPrimary(true);
  18. }
  19. else if (Lazy.class == qualifier) {
  20. abd.setLazyInit(true);
  21. }
  22. else {
  23. abd.addQualifier(new AutowireCandidateQualifier(qualifier));
  24. }
  25. }
  26. }
  27. if (customizers != null) {
  28. for (BeanDefinitionCustomizer customizer : customizers) {
  29. customizer.customize(abd);
  30. }
  31. }
  32. BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
  33. definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
  34. //主要看这个
  35. BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
  36. }

可以看到调用了BeanDefinitionReaderUtils.registerBeanDefinition()

5.解析BeanDefinitionReaderUtils.registerBeanDefinition

  1. public static void registerBeanDefinition(
  2. BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
  3. throws BeanDefinitionStoreException {
  4. // Register bean definition under primary name.
  5. String beanName = definitionHolder.getBeanName();
  6. registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());
  7. // Register aliases for bean name, if any.
  8. String[] aliases = definitionHolder.getAliases();
  9. if (aliases != null) {
  10. for (String alias : aliases) {
  11. registry.registerAlias(beanName, alias);
  12. }
  13. }
  14. }

在registerBeanDefinition(BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)方法中通过调用registry的registerBeanDefinition()方法来向IOC容器中注册Bean定义信息。

到这里后面 registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());就跟上面的第7部分一样了,主要就是Spring的IOC容器中注册类的Bean定义信息。

3.实例化流程源码解析

Spring IOC容器在刷新时,会实例化使用@Configuration注解标注的类

1.启动类ConfigurationDemo的main()方法

在main()方法中会调用AnnotationConfigApplicationContext类的构造方法传入配置类ConfigurationAnnotationConfig的Class对象来创建IOC容器。

  1. public static void main(String[] args) {
  2. AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ConfigurationAnnotationConfig.class);
  3. }

2.解析AnnotationConfigApplicationContext类的AnnotationConfigApplicationContext(Class<?>… componentClasses)构造方法

  1. public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
  2. this();
  3. register(componentClasses);
  4. refresh();
  5. }

在register(Class<?>… componentClasses)方法中调用了reader的 refresh() 方法刷新IOC容器。

3.解析AbstractApplicationContext类的refresh()方法

  1. @Override
  2. public void refresh() throws BeansException, IllegalStateException {
  3. // 在上下文中调用注册为bean的工厂处理器。
  4. invokeBeanFactoryPostProcessors(beanFactory);
  5. }

4.解析AbstractApplicationContext#invokeBeanFactoryPostProcessors

在invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory)方法中调用了PostProcessorRegistrationDelegate类的invokeBeanFactoryPostProcessors()方法。

  1. //实例化并调用所有注册的BeanFactoryPostProcessor bean
  2. protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
  3. PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
  4. ...
  5. }
  6. }

5.解析PostProcessorRegistrationDelegate # invokeBeanFactoryPostProcessors

  1. public static void invokeBeanFactoryPostProcessors(
  2. ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
  3. // 核心代码 这里,主要关注的是标注了@Configuration注解的类的实例化过程,所以,只需要关注invokeBeanFactoryPostProcessors()
  4. invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
  5. invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
  6. }

在invokeBeanFactoryPostProcessors()方法中会解析标注了@Configuration注解的类中标注了@Bean等注解的方法,生成相应的Bean定义信息注册到IOC容器中。

6. 解析PostProcessorRegistrationDelegate # invokeBeanFactoryPostProcessors (内部方法)

  1. private static void invokeBeanFactoryPostProcessors(
  2. Collection<? extends BeanFactoryPostProcessor> postProcessors, ConfigurableListableBeanFactory beanFactory) {
  3. for (BeanFactoryPostProcessor postProcessor : postProcessors) {
  4. StartupStep postProcessBeanFactory = beanFactory.getApplicationStartup().start("spring.context.bean-factory.post-process")
  5. .tag("postProcessor", postProcessor::toString);
  6. postProcessor.postProcessBeanFactory(beanFactory);
  7. postProcessBeanFactory.end();
  8. }
  9. }

在invokeBeanFactoryPostProcessors()方法中,会循环遍历传递进来的所有postProcessors集合,每次循环时,都会使用一个postProcessor对象来接收postProcessors集合中的每一个元素,调用postProcessor对象的postProcessBeanFactory()方法,并传入beanFactory来实例化对象。

7.解析ConfigurationClassPostProcessor类中的postProcessBeanFactory

  1. @Override
  2. //通过用CGLIB增强的子类替换Configuration类,准备在运行时为bean请求提供服务的Configuration类。
  3. public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
  4. int factoryId = System.identityHashCode(beanFactory);
  5. if (this.factoriesPostProcessed.contains(factoryId)) {
  6. throw new IllegalStateException(
  7. "postProcessBeanFactory already called on this post-processor against " + beanFactory);
  8. }
  9. this.factoriesPostProcessed.add(factoryId);
  10. if (!this.registriesPostProcessed.contains(factoryId)) {
  11. // BeanDefinitionRegistryPostProcessor hook apparently not supported...
  12. // Simply call processConfigurationClasses lazily at this point then.
  13. processConfigBeanDefinitions((BeanDefinitionRegistry) beanFactory);
  14. }
  15. // 核心方法
  16. enhanceConfigurationClasses(beanFactory);
  17. beanFactory.addBeanPostProcessor(new ImportAwareBeanPostProcessor(beanFactory));
  18. }

再看enhanceConfigurationClasses()方法

8.ConfigurationClassPostProcessor # enhanceConfigurationClasses()方法

  1. public void enhanceConfigurationClasses(ConfigurableListableBeanFactory beanFactory) {
  2. ConfigurationClassEnhancer enhancer = new ConfigurationClassEnhancer();
  3. for (Map.Entry<String, AbstractBeanDefinition> entry : configBeanDefs.entrySet()) {
  4. AbstractBeanDefinition beanDef = entry.getValue();
  5. beanDef.setAttribute(AutoProxyUtils.PRESERVE_TARGET_CLASS_ATTRIBUTE, Boolean.TRUE);
  6. Class<?> configClass = beanDef.getBeanClass();
  7. // 核心代码
  8. Class<?> enhancedClass = enhancer.enhance(configClass, this.beanClassLoader);
  9. if (configClass != enhancedClass) {
  10. if (logger.isTraceEnabled()) {
  11. logger.trace(String.format("Replacing bean definition '%s' existing class '%s' with " +
  12. "enhanced class '%s'", entry.getKey(), configClass.getName(), enhancedClass.getName()));
  13. }
  14. beanDef.setBeanClass(enhancedClass);
  15. }
  16. }
  17. enhanceConfigClasses.tag("classCount", () -> String.valueOf(configBeanDefs.keySet().size())).end();
  18. }

在enhanceConfigurationClasses(ConfigurableListableBeanFactory beanFactory)方法中,主要是使用ConfigurationClassEnhancer对象的enhance()方法生成代理类,也就是使用CGLib生成代理类。

9.解析ConfigurationClassEnhancer # enhance

  1. public Class<?> enhance(Class<?> configClass, @Nullable ClassLoader classLoader) {
  2. if (EnhancedConfiguration.class.isAssignableFrom(configClass)) {
  3. if (logger.isDebugEnabled()) {
  4. }
  5. return configClass;
  6. }
  7. // 核心代码
  8. Class<?> enhancedClass = createClass(newEnhancer(configClass, classLoader));
  9. if (logger.isTraceEnabled()) {
  10. logger.trace(String.format("Successfully enhanced %s; enhanced class name is: %s",
  11. configClass.getName(), enhancedClass.getName()));
  12. }
  13. return enhancedClass;
  14. }

可以看到在方法中调用了createClass()方法创建代理类,在这之前先调用newEnhancer()方法实例化Enhancer对象。

10.解析ConfigurationClassEnhancer # newEnhancer

  1. private Enhancer newEnhancer(Class<?> configSuperClass, @Nullable ClassLoader classLoader) {
  2. Enhancer enhancer = new Enhancer();
  3. enhancer.setSuperclass(configSuperClass);
  4. enhancer.setInterfaces(new Class<?>[] {
  5. EnhancedConfiguration.class});
  6. enhancer.setUseFactory(false);
  7. enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
  8. enhancer.setStrategy(new BeanFactoryAwareGeneratorStrategy(classLoader));
  9. enhancer.setCallbackFilter(CALLBACK_FILTER);
  10. enhancer.setCallbackTypes(CALLBACK_FILTER.getCallbackTypes());
  11. return enhancer;
  12. }

创建一个新的CGLIB Enhancer实例后续会使用Enhancer对象生成代理类。

在newEnhancer()方法中为要生成的代理类设置了父类和接口,由于为要生成的代理类设置的接口为EnhancedConfiguration,同时,EnhancedConfiguration接口继承了BeanFactoryAware接口,所以,在后续生成的代理类中可以调用BeanFactoryAware接口的setBeanFactory(BeanFactory beanFactory)方法获取到beanFactory对象。

11.解析ConfigurationClassEnhancer#createClass

  1. private Class<?> createClass(Enhancer enhancer) {
  2. Class<?> subclass = enhancer.createClass();
  3. // Registering callbacks statically (as opposed to thread-local)
  4. // is critical for usage in an OSGi environment (SPR-5932)...
  5. Enhancer.registerStaticCallbacks(subclass, CALLBACKS);
  6. return subclass;
  7. }

在createClass(Enhancer enhancer)方法中,主要调用了enhancer对象的createClass()方法来创建代理类,因为使用CGLib创建出来的代理类是目标类的子类,所以,这里创建出来的代理类就是目标类的子类。

12.解析CALLBACKS

  1. private static final Callback[] CALLBACKS = new Callback[] {
  2. new BeanMethodInterceptor(),
  3. new BeanFactoryAwareMethodInterceptor(),
  4. NoOp.INSTANCE
  5. };

CALLBACKS是一个Callback类型的数组,数组中的每个元素都是一个Callback类型的对象。

BeanMethodInterceptor类和BeanFactoryAwareMethodInterceptor类也是拦截器类型,是两个内部类。

13.解析BeanMethodInterceptor类

BeanMethodInterceptor实现了MethodInterceptor接口和ConditionalCallback接口,主要的作用就是对标注了@Bean的注解的方法进行拦截。

执行intercept(Object enhancedConfigInstance, Method beanMethod, Object[] beanMethodArgs, MethodProxy cglibMethodProxy)方法,生成Bean的实例对象。

  1. public Object intercept(Object enhancedConfigInstance, Method beanMethod, Object[] beanMethodArgs,
  2. MethodProxy cglibMethodProxy) throws Throwable {
  3. //如果已经创建了Bean的代理实例对象,则调用父类的方法。
  4. if (isCurrentlyInvokedFactoryMethod(beanMethod)) {
  5. // The factory is calling the bean method in order to instantiate and register the bean
  6. // (i.e. via a getBean() call) -> invoke the super implementation of the method to actually
  7. // create the bean instance.
  8. if (logger.isInfoEnabled() &&
  9. BeanFactoryPostProcessor.class.isAssignableFrom(beanMethod.getReturnType())) {
  10. return cglibMethodProxy.invokeSuper(enhancedConfigInstance, beanMethodArgs);
  11. }
  12. return resolveBeanReference(beanMethod, beanMethodArgs, beanFactory, beanName);
  13. }

上述代码能够保证在类上添加@Configuration注解后,只会为类生成一个代理对象。也就是说,上述代码的逻辑能够保证标注了@Configuration注解的类生成的代理类是单例模式的。

因为使用CGLib创建出来的代理类是目标类的子类,所以第一次执行上述代码片段时,会调用cglibMethodProxy的invokeSuper()方法执行父类的方法,也就是执行目标类的方法。第二次执行上述代码片段时,会调用resolveBeanReference()方法。

resolveBeanReference()

  1. private Object resolveBeanReference(Method beanMethod, Object[] beanMethodArgs,
  2. ConfigurableBeanFactory beanFactory, String beanName) {
  3. // 确定指定的bean当前是否正在创建中。
  4. boolean alreadyInCreation = beanFactory.isCurrentlyInCreation(beanName);
  5. try {
  6. if (alreadyInCreation) {
  7. beanFactory.setCurrentlyInCreation(beanName, false);
  8. }
  9. boolean useArgs = !ObjectUtils.isEmpty(beanMethodArgs);
  10. if (useArgs && beanFactory.isSingleton(beanName)) {
  11. for (Object arg : beanMethodArgs) {
  12. if (arg == null) {
  13. useArgs = false;
  14. break;
  15. }
  16. }
  17. }
  18. //通过beanFactory获取已经初始化好的Bean对象,并将这个已经初始化好的bean对象返回,并不会再进行第二次初始化的操作。
  19. Object beanInstance = (useArgs ? beanFactory.getBean(beanName, beanMethodArgs) :
  20. beanFactory.getBean(beanName));
  21. if (!ClassUtils.isAssignableValue(beanMethod.getReturnType(), beanInstance)) {
  22. if (beanInstance.equals(null)) {
  23. beanInstance = null;
  24. }
  25. else {
  26. String msg = String.format("@Bean method %s.%s called as bean reference " +
  27. "for type [%s] but overridden by non-compatible bean instance of type [%s].",
  28. beanMethod.getDeclaringClass().getSimpleName(), beanMethod.getName(),
  29. beanMethod.getReturnType().getName(), beanInstance.getClass().getName());
  30. try {
  31. BeanDefinition beanDefinition = beanFactory.getMergedBeanDefinition(beanName);
  32. msg += " Overriding bean of same name declared in: " + beanDefinition.getResourceDescription();
  33. }
  34. catch (NoSuchBeanDefinitionException ex) {
  35. // Ignore - simply no detailed message then.
  36. }
  37. throw new IllegalStateException(msg);
  38. }
  39. }
  40. Method currentlyInvoked = SimpleInstantiationStrategy.getCurrentlyInvokedFactoryMethod();
  41. if (currentlyInvoked != null) {
  42. String outerBeanName = BeanAnnotationHelper.determineBeanNameFor(currentlyInvoked);
  43. beanFactory.registerDependentBean(beanName, outerBeanName);
  44. }
  45. return beanInstance;
  46. }
  47. finally {
  48. if (alreadyInCreation) {
  49. beanFactory.setCurrentlyInCreation(beanName, true);
  50. }
  51. }
  52. }

所以上面代码作用是,在类上添加@Configuration注解后,Spring能够保证为类生成的代理类是单例的。最后把beanInstance 返回出去。

终于梳理了一遍一遍学习一遍进步加油~

发表评论

表情:
评论列表 (有 0 条评论,110人围观)

还没有评论,来说两句吧...

相关阅读