简单说说 spring是如何实现AOP的(源码分析)

在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博客

相关推荐
GodSure09143 分钟前
Java单一职责原则SRP详解
java·python·单一职责原则
探数API小喇叭7 分钟前
基站查询 API 怎么用?LAC、CELLID 参数详解与实战】
java·开发语言·api·基站定位
catino8 分钟前
spring-IOC、DI
java·spring·rpc
千里码aicood20 分钟前
flask基于数字人的储粮知识问答原型系统研究与实现
后端·python·flask
xcl092538 分钟前
宠物救助领养系统实战开发指南:从需求分析到部署上线
java·mfc·宠物
考虑考虑1 小时前
arthas使用
java·运维·后端
xcl09251 小时前
从零开发流浪宠物领养平台:技术选型与核心模块设计
java·spring boot·宠物
Dovis(誓平步青云)1 小时前
模拟器横评:电脑上看小说、追短剧用什么模拟器?MuMu、雷电、腾讯手游助手实测
android·java·服务器·前端·javascript·电脑