前言
创建AOP代理的逻辑,主要分为两个部分讲解,一是获取增强器或者增强方法,二是对增强器或者增强方法进行代理。上篇博文分析了解获取增强器或者增强方法的流程,接下来继续分析根据获取到的增强器创建代理的流程。
程序入口
从AbstractAutoProxyCreator#wrapIfNecessary方法进入,调用AbstractAutoProxyCreator#createProxy开始创建代理。
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
// 如果已经处理过了 直接返回
return bean;
}
if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
// 不需要代理 直接返回
return bean;
}
if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
// 如果事一个基础设置类
// 或者配置了指定的bean不需要代理
// 即设置为不需要代理,然后返回
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);
// 开始创建代理,这个方法才是真正创建代理的逻辑
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;
}
初始化ProxyFactory
AbstractAutoProxyCreator#createProxy的功能是对proxyFactory进行实例化和初始化的操作,然后委托 ProxyFactory 去创建代理。
初始化操作主要包括:
- 提前暴露ConfigurationListableBeanFactory
- 获取当前类的属性
- 如果是引介增强场景要显示处理JDK代理目标
- 构建Advisors
- 子类对ProxyFactory进一步封装
- 获取代理对象
protected Object createProxy(Class<?> beanClass, @Nullable String beanName,
@Nullable Object[] specificInterceptors, TargetSource targetSource) {
// 如果是ConfigurableListableBeanFactory,设置提前暴露
if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
}
// 创建代理工厂
ProxyFactory proxyFactory = new ProxyFactory();
// 复制当前类中的相关属性到代理工厂
proxyFactory.copyFrom(this);
// 判断是否代理目标类
if (proxyFactory.isProxyTargetClass()) {
// Explicit handling of JDK proxy targets (for introduction advice scenarios)
// 显式处理 JDK 代理目标(用于引介增强场景)
if (Proxy.isProxyClass(beanClass)) {
// Must allow for introductions; can't just set interfaces to the proxy's interfaces only.
// 必须允许引介;不能只将接口设置为代理的接口。
for (Class<?> ifc : beanClass.getInterfaces()) {
proxyFactory.addInterface(ifc);
}
}
}
else {
// 确定给定的 bean 是否应该使用它的目标类而不是它的接口来代理
// 主要判断PRESERVE_TARGET_CLASS_ATTRIBUTE属性 preserveTargetClass
if (shouldProxyTargetClass(beanClass, beanName)) {
proxyFactory.setProxyTargetClass(true);
}
else {
evaluateProxyInterfaces(beanClass, proxyFactory);
}
}
// 构建增强器
Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
// 加入增强器
proxyFactory.addAdvisors(advisors);
// 设置要代理目标类
proxyFactory.setTargetSource(targetSource);
// 定制代理工厂
customizeProxyFactory(proxyFactory);
// 控制代理工厂被配置后 是否允许修改通知。
// 默认false
proxyFactory.setFrozen(this.freezeProxy);
if (advisorsPreFiltered()) {
proxyFactory.setPreFiltered(true);
}
// 初始化工作准备完毕,委托ProxyFactory处理具体逻辑
return proxyFactory.getProxy(getProxyClassLoader());
}
这个方法内构建Advisors加入ProxyFactory和创建代理两个流程比较繁琐。
构建Advisors
AbstractAutoProxyCreator#buildAdvisors
protected Advisor[] buildAdvisors(@Nullable String beanName, @Nullable Object[] specificInterceptors) {
// Handle prototypes correctly...
// 解析注册的所有InterceptorName
Advisor[] commonInterceptors = resolveInterceptorNames();
List<Object> allInterceptors = new ArrayList<>();
if (specificInterceptors != null) {
if (specificInterceptors.length > 0) {
// specificInterceptors may equals PROXY_WITHOUT_ADDITIONAL_INTERCEPTORS
// 加入当前切面类的拦截器
allInterceptors.addAll(Arrays.asList(specificInterceptors));
}
if (commonInterceptors.length > 0) {
// 加入通用的拦截器
if (this.applyCommonInterceptorsFirst) {
allInterceptors.addAll(0, Arrays.asList(commonInterceptors));
}
else {
allInterceptors.addAll(Arrays.asList(commonInterceptors));
}
}
}
if (logger.isTraceEnabled()) {
int nrOfCommonInterceptors = commonInterceptors.length;
int nrOfSpecificInterceptors = (specificInterceptors != null ? specificInterceptors.length : 0);
logger.trace("Creating implicit proxy for bean '" + beanName + "' with " + nrOfCommonInterceptors +
" common interceptors and " + nrOfSpecificInterceptors + " specific interceptors");
}
Advisor[] advisors = new Advisor[allInterceptors.size()];
for (int i = 0; i < allInterceptors.size(); i++) {
// 将拦截器转换为 Advisors对象
advisors[i] = this.advisorAdapterRegistry.wrap(allInterceptors.get(i));
}
return advisors;
}
将拦截器转换为Advisors
因为spring中有各种增强器、增强方法、拦截器等等方式对逻辑进行增强,所有有必要统一封装为Advisor,方便后续处理。
@Override
public Advisor wrap(Object adviceObject) throws UnknownAdviceTypeException {
if (adviceObject instanceof Advisor) {
// 如果本身就是Advisor 无需处理直接返回
return (Advisor) adviceObject;
}
// 如果不是Advice类型,抛出异常
if (!(adviceObject instanceof Advice)) {
throw new UnknownAdviceTypeException(adviceObject);
}
Advice advice = (Advice) adviceObject;
if (advice instanceof MethodInterceptor) {
// So well-known it doesn't even need an adapter.
// MethodInterceptor 使用 DefaultPointcutAdvisor封装
return new DefaultPointcutAdvisor(advice);
}
// 如果存在Advisor的适配器那么也同样需要进行封装
for (AdvisorAdapter adapter : this.adapters) {
// Check that it is supported.
if (adapter.supportsAdvice(advice)) {
return new DefaultPointcutAdvisor(advice);
}
}
throw new UnknownAdviceTypeException(advice);
}
创建代理
在DefaultAopProxyFactory#createAopProxy这个方法中决定采用JDK动态代理还是CGLIB代理。判断条件如下
- optimize:控制通过CGLIB创建的代理是否使用激进的优化策略
- proxyTargerClass:是否采用目标类本身代理,也就是如果设置为 ture,就采用CGLIB代理
- hasNoUserSuppliedProxyInterfaces:是否存在代理接口
public Object getProxy(@Nullable ClassLoader classLoader) {
return createAopProxy().getProxy(classLoader);
}
protected final synchronized AopProxy createAopProxy() {
if (!this.active) {
activate();
}
// 创建代理
return getAopProxyFactory().createAopProxy(this);
}
@Override
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
// 根据这三个条件 决定使用JDK动态代理 还是CGLIB代理
if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
Class<?> targetClass = config.getTargetClass();
if (targetClass == null) {
throw new AopConfigException("TargetSource cannot determine target class: " +
"Either an interface or a target is required for proxy creation.");
}
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
return new JdkDynamicAopProxy(config);
}
return new ObjenesisCglibAopProxy(config);
}
else {
return new JdkDynamicAopProxy(config);
}
}
创建代理的共同的逻辑暂时分析到此,后面再更新两篇博文分别讲解JDK动态代理实现和CGLIB代理实现。