作者简介:大齐,自学Java入门,现在某国企担任初级架构师
有自己独立的学习方法,以及适合大部分人的学习路线,面试架构思路等
关注公众号【大齐架构】,查看最新最全的知识分享
Spring 的扩展点 是Spring易扩展的一个重要体现,熟悉这些扩展点的定义方式,以及其调用时机,不仅成为工作中利器,也能深度理解Spring框架的切入点。
InstantiationAwareBeanPostProcessor接口扩展了BeanPostProcessor子接口,提供了Bean被实例化之前、Bean实例化之后、Bean属性装配前更细粒度控制Bean创建流程的处理。
查看Sprng源码接口上的注解:
/**
* BeanPostProcessor接口的子接口,它添加了一个在实例化之前的回调,以及一个在实例化后但在显式属性设置或自动装配之前的回调。
* 通常用于特定目标bean的默认实例化
* Subinterface of {@link BeanPostProcessor} that adds a before-instantiation callback,
* and a callback after instantiation but before explicit properties are set or
* autowiring occurs.
* 例如使用特殊的 TargetSource 创建代理(例如池化目标、延迟初始化目标等),
* 或实现其他类型的注入策略,例如字段注入
* Typically used to suppress default instantiation for specific target beans,
* for example to create proxies with special TargetSources (pooling targets,
* lazily initializing targets, etc), or to implement additional injection strategies
* such as field injection.
*/
public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor {
postProcessPropertyValues()在Spring5.1版本后被弃用
org.springframework.beans它是由Spring本身提供的容器级别的接口。
主要的扩展点有以下5个方法,在bean生命周期的两大阶段:实例化阶段和初始化阶段,按调用顺序为:
postProcessBeforeInstantiation:实例化bean之前,相当于new这个bean之前
postProcessAfterInstantiation:实例化bean之后,相当于new这个bean之后,属性注入前触发执行
postProcessPropertiess:bean已经实例化完成,在属性注入时阶段触发,@Autowired,@Resource等注解原理基于此方法实现
postProcessBeforeInitialization:初始化bean之前,相当于把bean注入spring上下文之前
postProcessAfterInitialization:初始化bean之后,相当于把bean注入spring上下文之后
BeanPostProcess接口只在bean的初始化阶段进行扩展(注入spring上下文前后)
InstantiationAwareBeanPostProcessor接口在此基础上增加了3个方法,把可扩展的范围增加了实例化阶段和属性注入阶段。
InstantiationAwareBeanPostProcessor扩展点的实现方式很简单,实现接口,重写相应的方法实现扩展逻辑。
@Component
@Slf4j
public class ExampleComponent implements InitializingBean {
public ExampleComponent() {
log.info("----ExampleComponent无参构造方法被执行");
}
@Override
public void afterPropertiesSet() throws Exception {
log.info("----ExampleComponent被初始化");
}
}
@Service
@Slf4j
public class ExampleService {
private String userName="大齐架构";
private ExampleComponent exampleComponent;
public ExampleService() {
log.info("----ExampleService无参构造方法被执行");
}
@Autowired
public void setExampleService(ExampleComponent exampleComponent) {
this.exampleComponent = exampleComponent;
log.info("----ExampleService内的exampleComponent属性被注入");
}
public void setUserName(String userName) {
this.userName = userName;
log.info("----ExampleService内的userName属性被注入");
}
public String getUserName() {
return userName;
}
}
ExampleService 代码
@Component
@Slf4j
public class MyInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor {
@SneakyThrows
@Override
public Object postProcessBeforeInstantiation(Class> beanClass, String beanName) throws BeansException {
if (beanName.equals("exampleService")) {
log.info("----postProcessBeforeInstantiation被执行:" + beanName);
return null;
}
return null;
}
@Override
public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
if (beanName.equals("exampleService")) {
log.info("----postProcessAfterInstantiation被执行:" + beanName);
}
return true;
}
@Override
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
if (beanName.equals("exampleService")) {
log.info("----postProcessProperties被执行:" + beanName);
MutablePropertyValues mutablePropertyValues=new MutablePropertyValues();
mutablePropertyValues.addPropertyValue("userName","李四");
pvs=mutablePropertyValues;
}
return pvs;
}
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if (beanName.equals("exampleService")) {
log.info("----postProcessBeforeInitialization---" + beanName);
//如果特定的bean实例化完成后,还未执行InitializingBean.afterPropertiesSet()方法之前,有一些其他操作,可以在这里实现
}
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (beanName.equals("exampleService")) {
log.info("----postProcessAfterInitialization---" + beanName);
//如果特定的bean实例化完成,InitializingBean.afterPropertiesSet()方法执行后,有一些其他操作,可以在这里实现
}
return bean;
}
}
MyInstantiationAwareBeanPostProcessor 代码
@Test
public void test() {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext("com.rfq");
ExampleService bean = context.getBean(ExampleService.class);
Assert.isTrue("李四".equals(bean.getUserName()), "属性替换失败");
log.info("----" + bean.getUserName());
}
单元测试代码
c.r.s.component.ExampleComponent : ----ExampleComponent无参构造方法被执行
c.r.s.component.ExampleComponent : ----ExampleComponent被初始化
.p.MyInstantiationAwareBeanPostProcessor : ----postProcessBeforeInstantiation被执行:exampleService
c.rfq.springtest.service.ExampleService : ----ExampleService无参构造方法被执行
.p.MyInstantiationAwareBeanPostProcessor : ----postProcessAfterInstantiation被执行:exampleService
.p.MyInstantiationAwareBeanPostProcessor : ----postProcessProperties被执行:exampleService
c.rfq.springtest.service.ExampleService : ----ExampleService内的exampleComponent属性被注入
c.rfq.springtest.service.ExampleService : ----ExampleService内的userName属性被注入
.p.MyInstantiationAwareBeanPostProcessor : ----postProcessBeforeInitialization---exampleService
.p.MyInstantiationAwareBeanPostProcessor : ----postProcessAfterInitialization---exampleService
c.r.s.rfqtest.RfqTestApplicationTests : ----李四
控制台输出结果
因为InstantiationAwareBeanPostProcessor接口继承于BeanPostProcessor接口,所以InstantiationAwareBeanPostProcessor接口的实现类的注册时机和BeanPostProcessor是一致的。
应用启动后进入,AbstractApplicationContext#refresh()方法中
在refresh方法中调用registerBeanPostProcessors最终用交由类PostProcessorRegistrationDelegate#registerBeanPostProcessors的方法进行注
获取所有实现BeanPostProcessor接口的实现类的名称
把所有的BeanPostProcessor接口的实现类,按照是否实现PriorityOrdered接口、是否实现Ordered接口、其他三种筛选条件进行分类
最终将所有的BeanPostProcessor接口的实现类注册到工厂BeanFactory中
近期文章精选(关注公众号大齐架构,获取更多精彩知识):
架构のSpring扩展点(一):上下文创建前的动态处理-ApplicationContextInitializer
架构のSpring扩展点(二):Bean定义操作-BeanDefinitionRegistryPostProcessor
架构のSpring扩展点(四):Bean初始化时对象自动注入-Aware全解析
架构のSpring扩展点(五):如何保证在同一线程内获取的bean是同一对象-自定义Scope
架构のSpring扩展点(六):ApplicationContextAwareProcessor接口全解析,看完就懂
认知结构的提升,需要合适的思考方法-架构提升
架构のSpring扩展点(一):上下文创建前的动态处理-ApplicationContextInitializer
认知结构的提升,需要合适的思考方法-架构提升