在spring生命周期流程中,有一个过程是执行BeanPostProcessor的后置方法
BeanPostProcessor 是一个接口,其实现有
aop实现的核心类是AbstractAutoProxyCreator,其位于spring-aop包下,实现了BeanPostProcessor
//BeanPostProcessor的后置方法实现
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
if (bean != null) {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
if (this.earlyProxyReferences.remove(cacheKey) != bean) {
//核心处理方法
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
... 其他处理逻辑
//返回当前bean的所有 advisor、advice、interceptor
//如果定义了一个@Pointcut 会有一个advisor
//如果定义了一个@Around 会有一个advisor
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
//如果获取的结果是null,则这个bean没有被代理
if (specificInterceptors != DO_NOT_PROXY) {
//将当前的bean标记为代理类
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;
}
创建代理前的前置方法,这个方法核心做了三个事情
1 缺点该用cglib还是jdk动态代理,如果设置了使用cglib,则会使用cglib,如果没有设置,会根据是否有接口来进行判断,有接口使用jdk动态代理,没有接口使用cglib。
2 合并构建advisor,由于在上一步获取到的specificInterceptors,有多种情况,分别是advice、advisor和interceptor,这里要把这些都构建成advisor
3 创建代理:创建代理会根据是否使用cglib,然后创建不同的工厂对象进行创建不同的代理
//specificInterceptors 携带的advisor信息
//targetSource
protected Object createProxy(Class<?> beanClass, @Nullable String beanName,
@Nullable Object[] specificInterceptors, TargetSource targetSource) {
...
//判断是否要转换使用cglib进行代理增强
if (!proxyFactory.isProxyTargetClass()) {
//根据是否有接口,将proxyTargetClass设置成true,就是使用cglib进行增强
if (shouldProxyTargetClass(beanClass, beanName)) {
proxyFactory.setProxyTargetClass(true);
}
else {
//这里会判断是否有适合代理的接口,如果没有,还是会设置使用cglib
evaluateProxyInterfaces(beanClass, proxyFactory);
}
}
//将advice、interceptor和advisor都构造成advisor
Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
proxyFactory.addAdvisors(advisors);
proxyFactory.setTargetSource(targetSource);
//空方法,啥也不是
customizeProxyFactory(proxyFactory);
...
//获取代理核心方法
return proxyFactory.getProxy(getProxyClassLoader());
}
传送门
简单说说 Bean的生命周期源码-CSDN博客