发布于2021-05-29 20:01 阅读(622) 评论(0) 点赞(16) 收藏(2)
本章讲spring Bean生命周期中非常重要的功能,即BeanPostProcessor后置处理器, 很多功能都依赖BeanPostProcessor实现,如AOP,Autowired,初始化方法调用等。精通BeanPostProcessor并灵活加以利用,spring 容器就学会了一大半。
既然如此重要,还是先看源码:
package org.springframework.beans.factory.config;
import org.springframework.beans.BeansException;
import org.springframework.lang.Nullable;
/**
* Factory hook that allows for custom modification of new bean instances —
* for example, checking for marker interfaces or wrapping beans with proxies.
*
* <p>Typically, post-processors that populate beans via marker interfaces
* or the like will implement {@link #postProcessBeforeInitialization},
* while post-processors that wrap beans with proxies will normally
* implement {@link #postProcessAfterInitialization}.
*
* <h3>Registration</h3>
* <p>An {@code ApplicationContext} can autodetect {@code BeanPostProcessor} beans
* in its bean definitions and apply those post-processors to any beans subsequently
* created. A plain {@code BeanFactory} allows for programmatic registration of
* post-processors, applying them to all beans created through the bean factory.
*
* <h3>Ordering</h3>
* <p>{@code BeanPostProcessor} beans that are autodetected in an
* {@code ApplicationContext} will be ordered according to
* {@link org.springframework.core.PriorityOrdered} and
* {@link org.springframework.core.Ordered} semantics. In contrast,
* {@code BeanPostProcessor} beans that are registered programmatically with a
* {@code BeanFactory} will be applied in the order of registration; any ordering
* semantics expressed through implementing the
* {@code PriorityOrdered} or {@code Ordered} interface will be ignored for
* programmatically registered post-processors. Furthermore, the
* {@link org.springframework.core.annotation.Order @Order} annotation is not
* taken into account for {@code BeanPostProcessor} beans.
*
* @author Juergen Hoeller
* @author Sam Brannen
* @since 10.10.2003
* @see InstantiationAwareBeanPostProcessor
* @see DestructionAwareBeanPostProcessor
* @see ConfigurableBeanFactory#addBeanPostProcessor
* @see BeanFactoryPostProcessor
*/
public interface BeanPostProcessor {
/**
* Apply this {@code BeanPostProcessor} to the given new bean instance <i>before</i> any bean
* initialization callbacks (like InitializingBean's {@code afterPropertiesSet}
* or a custom init-method). The bean will already be populated with property values.
* The returned bean instance may be a wrapper around the original.
* <p>The default implementation returns the given {@code bean} as-is.
* @param bean the new bean instance
* @param beanName the name of the bean
* @return the bean instance to use, either the original or a wrapped one;
* if {@code null}, no subsequent BeanPostProcessors will be invoked
* @throws org.springframework.beans.BeansException in case of errors
* @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet
*/
@Nullable
default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
/**
* Apply this {@code BeanPostProcessor} to the given new bean instance <i>after</i> any bean
* initialization callbacks (like InitializingBean's {@code afterPropertiesSet}
* or a custom init-method). The bean will already be populated with property values.
* The returned bean instance may be a wrapper around the original.
* <p>In case of a FactoryBean, this callback will be invoked for both the FactoryBean
* instance and the objects created by the FactoryBean (as of Spring 2.0). The
* post-processor can decide whether to apply to either the FactoryBean or created
* objects or both through corresponding {@code bean instanceof FactoryBean} checks.
* <p>This callback will also be invoked after a short-circuiting triggered by a
* {@link InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation} method,
* in contrast to all other {@code BeanPostProcessor} callbacks.
* <p>The default implementation returns the given {@code bean} as-is.
* @param bean the new bean instance
* @param beanName the name of the bean
* @return the bean instance to use, either the original or a wrapped one;
* if {@code null}, no subsequent BeanPostProcessors will be invoked
* @throws org.springframework.beans.BeansException in case of errors
* @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet
* @see org.springframework.beans.factory.FactoryBean
*/
@Nullable
default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
}
从源码注释中可以分析出如下信息:
用于bean对象初始化前后进行逻辑增强。spring默认提供了很多非常重要的BeanPostProcessor实现类,如:AutowiredAnnotationBeanPostProcessor用于@Autowired注解的实现;AnnotationAwareAspectJAutoProxyCreator用于Spring AOP的动态代理。
定义一个普通的Bean class
package win.elegentjs.spring.ioc.beanpost;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import javax.annotation.PostConstruct;
@Data
@Slf4j
public class Car {
// 车身颜色
private String color;
// 车子型号
private String version;
@PostConstruct
public void init() {
log.info("==> in Car init method.");
}
}
定义了两个BeanPostProcessor
package win.elegentjs.spring.ioc.beanpost;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.core.Ordered;
/**
* 自定义BeanPostProcessor,实现了Ordered接口可设定后置处理器的执行顺序,值越小越先执行
*/
@Slf4j
public class CheckColorBeanPostProcessor implements BeanPostProcessor, Ordered {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
log.info("==> in CheckColorBeanPostProcessor beforeInitialization method.");
return BeanPostProcessor.super.postProcessBeforeInitialization(bean, beanName);
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
log.info("==> in CheckColorBeanPostProcessor afterInitialization method.");
return BeanPostProcessor.super.postProcessAfterInitialization(bean, beanName);
}
@Override
public int getOrder() {
return 1;
}
}
实现的逻辑很简单,就写了个打印语句,并实现了Ordered接口,本后置处理器设置的序列为1。
这是第二个后置处理器,实现逻辑跟第一个相同,但序列为2,期望第一个后置处理器先执行,第二个后执行
package win.elegentjs.spring.ioc.beanpost;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.core.Ordered;
/**
* 自定义BeanPostProcessor,实现了Ordered接口可设定后置处理器的执行顺序,值越小越先执行
*/
@Slf4j
public class CheckVersionBeanPostProcessor implements BeanPostProcessor, Ordered {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
log.info("==> in CheckVersionBeanPostProcessor beforeInitialization method.");
return BeanPostProcessor.super.postProcessBeforeInitialization(bean, beanName);
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
log.info("==> in CheckVersionBeanPostProcessor afterInitialization method.");
return BeanPostProcessor.super.postProcessAfterInitialization(bean, beanName);
}
@Override
public int getOrder() {
return 2;
}
}
这是java config配置类
package win.elegentjs.spring.ioc.beanpost;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class CarConfig {
@Bean
public CheckVersionBeanPostProcessor checkVersionBeanPostProcessor() {
return new CheckVersionBeanPostProcessor();
}
@Bean
public CheckColorBeanPostProcessor checkColorBeanPostProcessor() {
return new CheckColorBeanPostProcessor();
}
@Bean
public Car car() {
return new Car();
}
}
测试看看结果
package win.elegentjs.spring.ioc.beanpost;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import win.elegentjs.spring.ioc.lifecycle.postpre.MonkeyConfig;
@Slf4j
public class CarSample {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(CarConfig.class);
context.close();
}
}
// result
2021-05-28 15:41:01.408 [main] INFO w.e.s.ioc.beanpost.CheckColorBeanPostProcessor-==> in CheckColorBeanPostProcessor beforeInitialization method.
2021-05-28 15:41:01.410 [main] INFO w.e.s.ioc.beanpost.CheckVersionBeanPostProcessor-==> in CheckVersionBeanPostProcessor beforeInitialization method.
2021-05-28 15:41:01.410 [main] INFO win.elegentjs.spring.ioc.beanpost.Car-==> in Car init method.
2021-05-28 15:41:01.410 [main] INFO w.e.s.ioc.beanpost.CheckColorBeanPostProcessor-==> in CheckColorBeanPostProcessor afterInitialization method.
2021-05-28 15:41:01.410 [main] INFO w.e.s.ioc.beanpost.CheckVersionBeanPostProcessor-==> in CheckVersionBeanPostProcessor afterInitialization method.
2021-05-28 15:41:01.445 [main] DEBUG o.s.c.a.AnnotationConfigApplicationContext-Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@36f6e879, started on Fri May 28 15:41:01 CST 2021
可以看出执行结果符合我们的预期。
本节分析了BeanPostProcessor的作用以及编写了实际示例。下一节会重点讲解spring自带的若干BeanPostProcessor, 我们深入源码看看spring容器如何借助BeanPostProcessor实现各种有用功能特性的。
作者:我长得真不赖
链接:http://www.javaheidong.com/blog/article/207135/f690274cf3a4dc04efa5/
来源:java黑洞网
任何形式的转载都请注明出处,如有侵权 一经发现 必将追究其法律责任
昵称:
评论内容:(最多支持255个字符)
---无人问津也好,技不如人也罢,你都要试着安静下来,去做自己该做的事,而不是让内心的烦躁、焦虑,坏掉你本来就不多的热情和定力
Copyright © 2018-2021 java黑洞网 All Rights Reserved 版权所有,并保留所有权利。京ICP备18063182号-2
投诉与举报,广告合作请联系vgs_info@163.com或QQ3083709327
免责声明:网站文章均由用户上传,仅供读者学习交流使用,禁止用做商业用途。若文章涉及色情,反动,侵权等违法信息,请向我们举报,一经核实我们会立即删除!