首页 > 编程语言 >Spring源码-InstantiationAwareBeanPostProcessor

Spring源码-InstantiationAwareBeanPostProcessor

时间:2022-09-29 20:55:57浏览次数:66  
标签:beanName return String Spring Object bean 源码 null InstantiationAwareBeanPostProc

InstantiationAwareBeanPostProcessor继承了BeanPostProcessor接口,扩展了BeanPostProcessor的功能。

public interface BeanPostProcessor {

/**
 调用init方法的前置处理
 */
@Nullable
default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
	return bean;
}

/**
  调用init方法的后置处理
 */
@Nullable
default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
	return bean;
}

}

InstantiationAwareBeanPostProcessor :

public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor {

	/**
	  在bean实例化之前调用
	 */
	@Nullable
	default Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
		return null;
	}

	/**
	 在bean实例化之后调用
	 */
	default boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
		return true;
	}

	/**
	 当使用注解的时候,通过这个方法来完成属性的注入
	 */
	@Nullable
	default PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName)
			throws BeansException {

		return null;
	}

	/**
	属性注入后执行的方法,在5.1版本被废弃
	 */
	@Deprecated
	@Nullable
	default PropertyValues postProcessPropertyValues(
			PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {

		return pvs;
	}

}

InstantiationAwareBeanPostProcessor可以提前返回对象的代理,不必走完Spring的bean创建流程。

例子:

MyService.java

public class MyService {
public void print() {
	System.out.println("MyService");
}
}

MyInstantiationAwareBeanPostProcessor.java

public class MyInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
	System.out.println(beanName + "执行postProcessBeforeInitialization");
	return null;
}

@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
	System.out.println(beanName + "执行postProcessAfterInitialization");
	return bean;
}

@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
	System.out.println(beanName + "执行postProcessBeforeInstantiation");
	if(beanClass == MyService.class) {
		Enhancer enhancer = new Enhancer();
		enhancer.setSuperclass(MyService.class);
		enhancer.setCallback(new MethodInterceptor() {
			@Override
			public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
				System.out.println("执行方法之前");
				Object o1 = methodProxy.invokeSuper(o, objects);
				System.out.println("执行方法之后");
				return o1;
			}
		});
       return (MyService)enhancer.create();
	}
	return null;
}

@Override
public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
	System.out.println(beanName + "执行postProcessAfterInstantiation");
	return false;
}

@Override
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
	System.out.println(beanName + "执行postProcessProperties");
	return pvs;
}
}

instantiation.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	   xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd">

		<bean id="myService" class="instantiation.MyService"></bean>

	    <bean class="instantiation.MyInstantiationAwareBeanPostProcessor"/>
</beans>

Test.java

public class Test {
public static void main(String[] args) {
	ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("instantiation.xml");

	MyService myService = applicationContext.getBean(MyService.class);
	myService.print();
}
}

Spring源码执行InstantiationAwareBeanPostProcessor:

AbstractAutowireCapableBeanFactory的createBean方法:

protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
		throws BeanCreationException {

	if (logger.isTraceEnabled()) {
		logger.trace("Creating instance of bean '" + beanName + "'");
	}
	RootBeanDefinition mbdToUse = mbd;

	// Make sure bean class is actually resolved at this point, and
	// clone the bean definition in case of a dynamically resolved Class
	// which cannot be stored in the shared merged bean definition.
	Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
	if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
		mbdToUse = new RootBeanDefinition(mbd);
		mbdToUse.setBeanClass(resolvedClass);
	}

	// Prepare method overrides.
	try {
		mbdToUse.prepareMethodOverrides();
	}
	catch (BeanDefinitionValidationException ex) {
		throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
				beanName, "Validation of method overrides failed", ex);
	}

	try {
		// 给BeanPostProcessors一个机会来返回代理来替代真正的实例,应用实例化前的前置处理器,用户自定义动态代理的方式,针对于当前的被代理类需要经过标准的代理流程来创建对象
		Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
		if (bean != null) {
			return bean;
		}
	}
	catch (Throwable ex) {
		throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
				"BeanPostProcessor before instantiation of bean failed", ex);
	}

	try {
		Object beanInstance = doCreateBean(beanName, mbdToUse, args);
		if (logger.isTraceEnabled()) {
			logger.trace("Finished creating instance of bean '" + beanName + "'");
		}
		return beanInstance;
	}
	catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
		// A previously detected exception with proper bean creation context already,
		// or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.
		throw ex;
	}
	catch (Throwable ex) {
		throw new BeanCreationException(
				mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
	}
}

其中Object bean = resolveBeforeInstantiation(beanName, mbdToUse)执行InstantiationAwareBeanPostProcessor:

protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
	Object bean = null;
	if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
		// Make sure bean class is actually resolved at this point.
		if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
			Class<?> targetType = determineTargetType(beanName, mbd);
			if (targetType != null) {
				bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
				if (bean != null) {
					bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
				}
			}
		}
		mbd.beforeInstantiationResolved = (bean != null);
	}
	return bean;
}

   protected boolean hasInstantiationAwareBeanPostProcessors() {
	return !getBeanPostProcessorCache().instantiationAware.isEmpty();
}

    BeanPostProcessorCache getBeanPostProcessorCache() {
	BeanPostProcessorCache bpCache = this.beanPostProcessorCache;
	if (bpCache == null) {
		bpCache = new BeanPostProcessorCache();
		for (BeanPostProcessor bp : this.beanPostProcessors) {
			if (bp instanceof InstantiationAwareBeanPostProcessor) {
				bpCache.instantiationAware.add((InstantiationAwareBeanPostProcessor) bp);
				if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
					bpCache.smartInstantiationAware.add((SmartInstantiationAwareBeanPostProcessor) bp);
				}
			}
			if (bp instanceof DestructionAwareBeanPostProcessor) {
				bpCache.destructionAware.add((DestructionAwareBeanPostProcessor) bp);
			}
			if (bp instanceof MergedBeanDefinitionPostProcessor) {
				bpCache.mergedDefinition.add((MergedBeanDefinitionPostProcessor) bp);
			}
		}
		this.beanPostProcessorCache = bpCache;
	}
	return bpCache;
}

getBeanPostProcessorCache方法注册的beanPostProcessor集合,并分类为InstantiationAwareBeanPostProcessor,SmartInstantiationAwareBeanPostProcessor,DestructionAwareBeanPostProcessor,MergedBeanDefinitionPostProcessor四类,加入beanPostProcessorCache缓存中。

protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
	for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
		Object result = bp.postProcessBeforeInstantiation(beanClass, beanName);
		if (result != null) {
			return result;
		}
	}
	return null;
}

applyBeanPostProcessorsBeforeInstantiation执行InstantiationAwareBeanPostProcessor的postProcessBeforeInstantiation方法,若结果不为空直接返回,否则返回null。

public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
		throws BeansException {

	Object result = existingBean;
	for (BeanPostProcessor processor : getBeanPostProcessors()) {
		Object current = processor.postProcessAfterInitialization(result, beanName);
		if (current == null) {
			return result;
		}
		result = current;
	}
	return result;
}

applyBeanPostProcessorsAfterInitialization执行BeanPostProcessor的postProcessAfterInitialization方法,若结果不为空直接返回,否则返回null。

bean可以走InstantiationAwareBeanPostProcessor的postProcessBeforeInstantiation方法和BeanPostProcessor的postProcessAfterInitialization方法后可以创建完bean,而不用走完bean的创建流程。

标签:beanName,return,String,Spring,Object,bean,源码,null,InstantiationAwareBeanPostProc
From: https://www.cnblogs.com/shigongp/p/16742973.html

相关文章

  • springboot+mybatis 双数据源配置
    maven依赖spring-boot-starter-webmybatis-spring-boot-startermysql-connector-javalombokapplication.ymlserver:port:8080#启动端口spring:datasource:......
  • springaop笔记
    springaop解决的问题什么是增强增强代码,比如买装备在不惊动源代码的基础上对代码进行更改,增强,什么是aop第一步导入坐标第二步创建aop文件夹@Aspect作用标识此......
  • php源码安装
    参考:https://www.sunanzhi.com/archives/27/ 安装1、到官网获取下载地址 https://www.php.net/downloads2、下载并解压cd/home/install/php74wgethttps://www......
  • 基于Springboot的服务端开发脚手架-自动生成工具
    继之前的专题系列课程:​​从零开始搭建grpc分布式应用​​完整DEMO:​​基于Springboot的Rpc服务端开发脚手架(base-grpc-framework)​​后带来一款项目自动手成工具(由于包......
  • Spring Security 介绍中的 servlet 和 reactive
    最近在看看SpringSecurity中的内容。看到了下面一段话,还挺拗口的。SpringSecurity提供了一个验证(authentication),授权(authorization),和保护常见攻击的框架。Sprin......
  • 支付宝沙箱服务 (结合springboot实现,这里对接的是easy版本,工具用的是IDEA,WebStrom)
    一:打开支付宝开发平台,登录,然后点击控制台https://open.alipay.com/   二:滚动到底部,选着沙箱服务   三:获取到对接要用的appId和公钥私钥    四......
  • Oauth2.0 用Spring-security-oauth2 来实现
    前言:要准备再次研究下统一认证的功能了,我还是觉得实现统一认证用Oauth2最好了,所以,现在再次收集资料和记笔记。正文:一、概念理解    OAuth2,是个授权协议,......
  • 安全框架 SpringSecurity 和 Shiro 对比
    突然再次很想理一下权限的事,但是实在不知道实际情况选哪个框架好,现在整理下网上的资料,做一下对比。1、Spring-security对spring结合较好,如果项目用的springmvc,使用起来很......
  • Apache Shiro和Spring Security的详细对比
    参考资料:1)ApacheShiroApacheShiro:​​http://shiro.apache.org/​​在Web项目中应用ApacheShiro:​​http://www.ibm.com/developerworks/cn/java/j-lo-shiro/​​Apac......
  • Spring源码学习:day2
    前言:我还是太懒了,连截图都懒得粘贴,故直接用书上说的话的截图吧。代码的编写过程都是应该有一个入口的,所有的代码最终都是为了那个入口更加方便更加简单而产生的。......