栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

spring核心源码分析第十篇 refresh流程之invokeBeanFactoryPostProcessors-postProcessBeanFactory-对full模式的代理增强

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

spring核心源码分析第十篇 refresh流程之invokeBeanFactoryPostProcessors-postProcessBeanFactory-对full模式的代理增强

以ConfigurationClassPostProcessor为例子讲解invokeBeanFactoryPostProcessors-postProcessBeanFactory
  • full和lite的区别如下
  • full模式区别的实现一ConfigurationClassPostProcessor.postProcessBeanFactory
  • 增强的目的以及实现
    • 目的
    • 实现
      • BeanFactoryAwareMethodInterceptor作用
      • BeanMethodInterceptor完成full模式实现
  • 总结

full和lite的区别如下
  • full输出:

com.renxl.demo.Hi2@12ae75f1
com.renxl.demo.Hi2@12ae75f1

@Configuration
public class ConfigClass {
    @Bean
    public Hi1 hi1() {
        System.out.println( hi2());
        System.out.println( hi2());
        return  new Hi1();
    }
    @Bean
    public Hi2 hi2() {
        return  new Hi2();
    }
}
  • lite输出:

com.renxl.demo.Hi2@12ae75f1
com.renxl.demo.Hi2@6eeb15f9

@Component
public class ConfigClass {
    @Bean
    public Hi1 hi1() {
        System.out.println( hi2());
        System.out.println( hi2());
        return  new Hi1();
    }
    @Bean
    public Hi2 hi2() {
        return  new Hi2();
    }
}
full模式区别的实现一ConfigurationClassPostProcessor.postProcessBeanFactory
 通过cglib代理完成对full模式的处理
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
		int factoryId = System.identityHashCode(beanFactory);
		if (this.factoriesPostProcessed.contains(factoryId)) {
			throw new IllegalStateException(
					"postProcessBeanFactory already called on this post-processor against " + beanFactory);
		}
		this.factoriesPostProcessed.add(factoryId);
		if (!this.registriesPostProcessed.contains(factoryId)) {
			// BeanDefinitionRegistryPostProcessor hook apparently not supported...
			// Simply call processConfigurationClasses lazily at this point then.
			processConfigBeanDefinitions((BeanDefinitionRegistry) beanFactory);
		}
		// 通过cglib代理完成对full模式的处理
		enhanceConfigurationClasses(beanFactory);
		beanFactory.addBeanPostProcessor(new importAwareBeanPostProcessor(beanFactory));
	}
  • enhanceConfigurationClasses的实现目标是找出所有的Configuration注解的配置类并进行增强
public void enhanceConfigurationClasses(ConfigurableListableBeanFactory beanFactory) {
		Map configBeanDefs = new linkedHashMap<>();
		找出所有full模式的配置
		for (String beanName : beanFactory.getBeanDefinitionNames()) {
			BeanDefinition beanDef = beanFactory.getBeanDefinition(beanName);
			if (ConfigurationClassUtils.isFullConfigurationClass(beanDef)) {
				......删除其他代码
				configBeanDefs.put(beanName, (AbstractBeanDefinition) beanDef);
			}
		}
		
		通过增强替换了BeanDefinition原来的beanclass
		ConfigurationClassEnhancer enhancer = new ConfigurationClassEnhancer();
		for (Map.Entry entry : configBeanDefs.entrySet()) {
			......删除其他代码
				if (configClass != null) {
					Class enhancedClass = enhancer.enhance(configClass, this.beanClassLoader);
					beanDef.setBeanClass(enhancedClass);
				}
		}
	}
增强的目的以及实现 目的
  • 增强的目的是对所有@bean方法的调用改从spring容器中获取
  • 获取的方式区分factorybean和普通bean
beanfactorybean
beanFactory.getBean(beanName, beanMethodArgs)beanFactory.getBean(beanName)
实现
  • 代理类实现了EnhancedConfiguration
  • 代理类拦截点如下BeanMethodInterceptor,BeanFactoryAwareMethodInterceptor
  • EnhancedConfiguration是BeanFactoryAware子接口
  • 增加一个$$beanFactory属性
	private Enhancer newEnhancer(Class configSuperClass, @Nullable ClassLoader classLoader) {
		Enhancer enhancer = new Enhancer();
		enhancer.setSuperclass(configSuperClass);
		代理类实现了EnhancedConfiguration
		enhancer.setInterfaces(new Class[] {EnhancedConfiguration.class});
		enhancer.setUseFactory(false);
		enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
		设置一个属性$$beanFactory
		enhancer.setStrategy(new BeanFactoryAwareGeneratorStrategy(classLoader));
		代理类拦截点如下BeanMethodInterceptor,BeanFactoryAwareMethodInterceptor
		enhancer.setCallbackFilter(CALLBACK_FILTER);
		enhancer.setCallbackTypes(CALLBACK_FILTER.getCallbackTypes());
		return enhancer;
	}
BeanFactoryAwareMethodInterceptor作用
  • 如果是setBeanFactory方法则将beanfactory赋值到$$beanFactory属性
  • 前面说过EnhancedConfiguration是BeanFactoryAware子接口,而Aware接口在实例化的过程中会被spring容器自动注入相关目标实例,意味着所有的@Configuration都还有Beanfactory对象
	private static class BeanFactoryAwareMethodInterceptor implements MethodInterceptor, ConditionalCallback {
		@Override
		@Nullable
		public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
			......删除多余代码
			Field field = ReflectionUtils.findField(obj.getClass(), BEAN_FACTORY_FIELD);
			field.set(obj, args[0]);
		}

		@Override
		public boolean isMatch(Method candidateMethod) {
			return isSetBeanFactory(candidateMethod);
		}

		
	}
BeanMethodInterceptor完成full模式实现
  • 1 通过$$beanFactory属性获取BeanFactoryAwareMethodInterceptor设置的beanfactory
  • 2 匹配所有@bean注解方法
  • 3 如果是工厂bean,判断是通过cglib还是jdk代理实现,最后调用beanfactory获取bean
  • 4 普通bean,通过beanfactory获取bean
		public Object intercept(Object enhancedConfigInstance, Method beanMethod, Object[] beanMethodArgs,
					MethodProxy cglibMethodProxy) throws Throwable {
			......删除其他代码	
		    - 1 通过$$beanFactory属性获取BeanFactoryAwareMethodInterceptor设置的beanfactory
			ConfigurableBeanFactory beanFactory = getBeanFactory(enhancedConfigInstance);
			if (factoryContainsBean(beanFactory, BeanFactory.FACTORY_BEAN_PREFIX + beanName) &&
					 - 3 如果是工厂bean,判断是通过cglib还是jdk代理实现,最后调用beanfactory获取bean
					return enhanceFactoryBean(factoryBean, beanMethod.getReturnType(), beanFactory, beanName);
			}
			
			 -  4 普通bean,通过beanfactory获取bean
			return resolveBeanReference(beanMethod, beanMethodArgs, beanFactory, beanName);
		}

		private Object resolveBeanReference(Method beanMethod, Object[] beanMethodArgs,
				ConfigurableBeanFactory beanFactory, String beanName) {
				Object beanInstance = (useArgs ? beanFactory.getBean(beanName, beanMethodArgs) :
						beanFactory.getBean(beanName));
				return beanInstance;
		}

		@Override
		public boolean isMatch(Method candidateMethod) {
			- 2 匹配所有@bean注解方法
			return (candidateMethod.getDeclaringClass() != Object.class &&
					!BeanFactoryAwareMethodInterceptor.isSetBeanFactory(candidateMethod) &&
					BeanAnnotationHelper.isBeanAnnotated(candidateMethod));
		}

		private Object enhanceFactoryBean(final Object factoryBean, Class exposedType,
				final ConfigurableBeanFactory beanFactory, final String beanName) {
			......删除其他代码
			if (finalClass || finalMethod) {
				return createInterfaceProxyForFactoryBean(factoryBean, exposedType, beanFactory, beanName);
			}
			return createCglibProxyForFactoryBean(factoryBean, beanFactory, beanName);
		}

		private Object createInterfaceProxyForFactoryBean(final Object factoryBean, Class interfaceType,
				final ConfigurableBeanFactory beanFactory, final String beanName) {
				......删除其他代码
				省略了jdk代理部分,就留下如果创建对象的关键
				return beanFactory.getBean(beanName);
		}

		private Object createCglibProxyForFactoryBean(final Object factoryBean,
				final ConfigurableBeanFactory beanFactory, final String beanName) {
				......删除其他代码
				省略了cglib代理代码,就留下如果创建对象的关键
				return beanFactory.getBean(beanName);
		}
	}
总结
  • full模式对@bean的方法调用通过aop完成,改从beanfactory获取
  • lite模式还是直接对原来的方法调用,这也是文首输出不同的原因
  • full模式的实现通过MethodInterceptor完成aop
  • BeanFactoryAwareMethodInterceptor 通过aware功能实现beanfactory的Aware注入
  • BeanMethodInterceptor实现对原方法的拦截,改从beanfactory获取
    获取@bean注解注释的方法想要获取的对象
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/691183.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号