Spring扩展接口-BeanPostProcessor
简介
该接口目前有两个方法:
- postProcessBeforeInitialization 该在初始化方法之前调用。
- postProcessAfterInitialization 该方法再初始化方法之后调用。
public interface BeanPostProcessor {
@Nullable
default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
@Nullable
default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
}
用途示例
Spring aop注入切面-BeanNameAutoProxyCreator
在目标bean初始化完成之后,包装之后返回一个代理对象,注入相关的切面逻辑。
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (bean != null) {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
if (!this.earlyProxyReferences.contains(cacheKey)) {
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
if (beanName != null && this.targetSourcedBeans.contains(beanName)) {
return bean;
}
if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
return bean;
}
if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
// Create proxy if we have advice.
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
if (specificInterceptors != DO_NOT_PROXY) {
this.advisedBeans.put(cacheKey, Boolean.TRUE);
//对原来的bean进行代理
Object proxy = createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
this.proxyTypes.put(cacheKey, proxy.getClass());
//返回代理对象
return proxy;
}
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
监控 Bean 初始化耗时, 常用来排查Spring启动慢分析流程中,排查是否Bean初始化所致
@Service
@Slf4j
public class BeanInitMetrics implements BeanPostProcessor {
private final Map<String, Long> stats = new HashMap<>();
private final List<Metric> metrics = new ArrayList<>();
@Data
public static class Metric{
public Metric() {
}
public Metric(String name, Integer value) {
this.name = name;
this.value = value;
this.createDate = new Date();
}
private String name; //bean名称打印
private Integer value; //bean耗时,单位为毫秒
private Date createDate; //bean耗时的创建时间
}
//重写初始化接口
@Override
public Object postProcessBeforeInitialization(@NotNull Object bean, @NotNull String beanName) throws BeansException {
stats.put(beanName, System.currentTimeMillis());
return bean;
}
//后处理后初始化
@Override
public Object postProcessAfterInitialization(@NotNull Object bean, @NotNull String beanName) throws BeansException {
Long start = stats.get(beanName);
if (start != null) {
metrics.add(new Metric(beanName, Math.toIntExact(System.currentTimeMillis() - start)));
}
return bean;
}
//通过后处理后初始化 - 初始化的时间算出bean耗时
public List<Metric> getMetrics() {
metrics.sort((o1, o2) -> {
try {
return o2.getValue() - o1.getValue();
}catch (Exception e){
return 0;
}
});
log.info("metrics {}", JSON.toJSONString(metrics));
return UnmodifiableList.unmodifiableList(metrics); //只读的集合
}
}
更多信息请移步Spring专栏:www.yuque.com/mrhuang-ire…
参考: [1].zhuanlan.zhihu.com/p/617821971 [2].blog.csdn.net/weixin_4393…
本文来自博客园,作者:扎Zn了老Fe,转载请注明原文链接:https://www.cnblogs.com/itThinking/p/17771118.html