Spring Aop源码解析与细节

终于看完了庞大的Spring core(spring ioc / spring aop),鉴于ioc更为庞大,先整理下aop的源码流程,也能简单回顾下springioc的流程

首先要理解spring bean的启动大致的流程与生命周期,建议看另一篇已经简要解释 spring生命周期

基础概念
AOP 与 Spring AOP 与 AspectJ的区别

AOP 是思想,Spring AOP 与 AspectJ是AOP的实现,Spring AOP实现的时候用了AspectJ的规范

基本使用与AOP概念

//TODO

源码解析
入口

1、AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(Application.class);
refresh()初始化bean和执行后置处理器
2、@EnableAspectJAutoProxy
添加AOP的后置处理器,等同于xml中的 aop:aspectj-autoproxy/

@EnableAspectJAutoProxy解析

1、@EnableAspectJAutoProxy注解中@Import了类AspectJAutoProxyRegistrar,AspectJAutoProxyRegistrar 实现了 ImportBeanDefinitionRegistrar,可以拿到BeanDefinitionRegistry(spring bean生命周期相关),可以在类初始化之前加入AOP的后置处理器 ----> AnnotationAwareAspectJAutoProxyCreator
在这里插入图片描述

2、AnnotationAwareAspectJAutoProxyCreator的父类实现了BeanPostProcessor,会在spring对象产生之后进行操作,spring最核心的扩展点
3、父类实现BeanPostProcessor,真正执行后置处理器的类在AbstractAutoProxyCreator#postProcessAfterInitialization

	public Object AbstractAutoProxyCreator#postProcessAfterInitialization(@Nullable 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;
	}

其中wrapIfNecessary()中执行了创建代理类的方法

	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)) {
			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;
	}

4、动态代理的选择方式 (jdk、cjlib) DefaultAopProxyFactory#createAopProxy

// 这段代码有前人解释的很好了
public AopProxy DefaultAopProxyFactory#createAopProxy(AdvisedSupport config) throws AopConfigException {
    //这段代码用来判断选择哪种创建代理对象的方式
    //config.isOptimize()   是否对代理类的生成使用策略优化 其作用是和isProxyTargetClass是一样的 默认为false
    //config.isProxyTargetClass() 是否使用Cglib的方式创建代理对象 默认为false
    //hasNoUserSuppliedProxyInterfaces目标类是否有接口存在 且只有一个接口的时候接口类型不是
    //SpringProxy类型 
    if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
        //上面的三个方法有一个为true的话,则进入到这里
        //从AdvisedSupport中获取目标类 类对象
        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.");
        }
        //判断目标类是否是接口 如果目标类是接口的话,则还是使用JDK的方式生成代理对象
        //如果目标类是Proxy类型 则还是使用JDK的方式生成代理对象
        if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
            return new JdkDynamicAopProxy(config);
        }
        //配置了使用Cglib进行动态代理  或者目标类没有接口 那么使用Cglib的方式创建代理对象
        return new ObjenesisCglibAopProxy(config);
    }
    else {
        //上面的三个方法没有一个为true 那使用JDK的提供的代理方式生成代理对象
        return new JdkDynamicAopProxy(config);
    }
}

用户可以自行配置@EnableAspectJAutoProxy注解有一个proxyTargetClass属性表示是否使用CGLIB进行代理,源码中可以看出,即便是自定义了CGLIB代理,如果是个接口口,依旧会选择jdk动态代理

jdk动态代理

public Object JdkDynamicAopProxy#getProxy(@Nullable ClassLoader classLoader) {
		if (logger.isDebugEnabled()) {
			logger.debug("Creating JDK dynamic proxy: target source is " + this.advised.getTargetSource());
		}
		Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);
		findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
		return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
	}

Cglib动态代理

	protected Object ObjenesisCglibAopProxy#createProxyClassAndInstance(Enhancer enhancer, Callback[] callbacks) {
		Class<?> proxyClass = enhancer.createClass();
		Object proxyInstance = null;

		if (objenesis.isWorthTrying()) {
			try {
				proxyInstance = objenesis.newInstance(proxyClass, enhancer.getUseCache());
			}
			catch (Throwable ex) {
				logger.debug("Unable to instantiate proxy using Objenesis, " +
						"falling back to regular proxy construction", ex);
			}
		}

		if (proxyInstance == null) {
			// Regular instantiation via default constructor...
			try {
				Constructor<?> ctor = (this.constructorArgs != null ?
						proxyClass.getDeclaredConstructor(this.constructorArgTypes) :
						proxyClass.getDeclaredConstructor());
				ReflectionUtils.makeAccessible(ctor);
				proxyInstance = (this.constructorArgs != null ?
						ctor.newInstance(this.constructorArgs) : ctor.newInstance());
			}
			catch (Throwable ex) {
				throw new AopConfigException("Unable to instantiate proxy using Objenesis, " +
						"and regular proxy instantiation via default constructor fails as well", ex);
			}
		}

		((Factory) proxyInstance).setCallbacks(callbacks);
		return proxyInstance;
	}
后置处理器在哪里执行的呢(spring bean相关,简略说一下) 以注解为例

入口: AnnotationConfigApplicationContext的构造方法中的 refresh()方法

一个问题: 代理类生成的时机是getbean的时候还是getbean之前呢?
答案: 在getbean之前,在AnnotationConfigApplicationContext构造方法中执行了refresh方法,执行了getbean实例化,并生成了代理类(源码解读)

refresh()方法中进行了较多的操作,实例化工厂、配置工厂、生成db、注册beanPostProcessor…,我们的重点在finishBeanFactoryInitialization(beanFactory);方法中

然后进入到默认工厂类DefaultListableBeanFactory#preInstantiateSingletons#getBean()

准备进入核心代码:(后面补上完整调用链)
AbstractAutowireCapableBeanFactory#doCreateBean(去除了干扰代码)

	protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
			throws BeanCreationException {

		// Instantiate the bean.
		BeanWrapper instanceWrapper = null;
		if (mbd.isSingleton()) {
			instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
		}
		if (instanceWrapper == null) {
			instanceWrapper = createBeanInstance(beanName, mbd, args);
		}
		final Object bean = instanceWrapper.getWrappedInstance();
		Class<?> beanType = instanceWrapper.getWrappedClass();
		if (beanType != NullBean.class) {
			mbd.resolvedTargetType = beanType;
		}
		
		boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
				isSingletonCurrentlyInCreation(beanName));
		if (earlySingletonExposure) {
			addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
		}

		// Initialize the bean instance.
		Object exposedObject = bean;
		try {
			//设置属性,非常重要
			populateBean(beanName, mbd, instanceWrapper);
			//执行后置处理器,aop就是在这里完成的处理
			exposedObject = initializeBean(beanName, exposedObject, mbd);
		}
		catch (Throwable ex) {}

}

AbstractAutowireCapableBeanFactory#initializeBean
这里执行了后置处理器的after方法,这里就会执行第一步中注册的后置处理器,这里也能看出BeanPostProcessors执行的时机和spring bean创建的时机

protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
		if (System.getSecurityManager() != null) {
			AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
				invokeAwareMethods(beanName, bean);
				return null;
			}, getAccessControlContext());
		}else {
			invokeAwareMethods(beanName, bean);
		}

		Object wrappedBean = bean;
		if (mbd == null || !mbd.isSynthetic()) {
			//执行后置处理的befor
			wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
		}

		try {
			//执行bean的声明周期回调中的init方法
			invokeInitMethods(beanName, wrappedBean, mbd);
		}
		catch (Throwable ex) {
	
		}
		if (mbd == null || !mbd.isSynthetic()) {
			//执行后置处理器的after方法
			wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
		}

		return wrappedBean;
	}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值