Spring Aop分析总结

本来打算自己跟了源码后整理成博客,发现有的地方没弄懂,然后去网上找资料,看到一个写的很好的博客,就放弃了自己详细写。
做一个总结:
首先明白三个概念
1.pointcut :切入点 指明了对某个类的某个方法切入
2.advice 通知,分为前置,后置,环绕,异常,返回前 等五类通知,指明了 在某个时机干某事。
3.advisor pointcut+advice :指明了在某个地方的某个时机干某个事情。

spring在初始化IOC容器的时候,就会解析pointcut,advice生成对应的beanDefinition。
spring是在那个地方为bean创建的代理呢?
在bean初始化完后有个处理所有后置通知的逻辑

@Override
	public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
			throws BeansException {

		Object result = existingBean;
		for (BeanPostProcessor processor : getBeanPostProcessors()) {
			Object current = processor.postProcessAfterInitialization(result, beanName);
			if (current == null) {
				return result;
			}
			result = current;
		}
		return result;
	}

public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware

public interface SmartInstantiationAwareBeanPostProcessor extends InstantiationAwareBeanPostProcessor
InstantiationAwareBeanPostProcessor extends BeanPostProcessor

aop的处理逻辑类就是AbstractAutoProxyCreator,因为这个类也间接实现了BeanPostProcessor,所有这个类的postProcessAfterInitialization也会被调用

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

表面上的逻辑就是这个样子,当然,spring肯定还多了很多的处理
比如:为bean方法寻找合适的通知器(根据pointcut定义的规则,按照类和方法匹配)
生成拦截器链(一个方法可能有多个advise,spring将多个advise封装成拦截器链)
生成代理对象,加入了advise的逻辑

<aop:aspectj-autoproxy proxy-target-class=“true”/>
roxy-target-class:默认为false,接口用jdk代理,其它用cglib代理
设置为true时,强制采用cglib代理

<aop:aspectj-autoproxy expose-proxy=“true” />
expose-proxy:默认为false,为true时会将代理对象放到ThreadLocal中
比如TestService中有两个方法 A(),B() ,A调用B中的方法this.B(),这样B方法是没有经过代理的
要是想调用代理后的B(),就应该 ((TestService) AopContext.currentProxy()).B();

要了解AOP的整个代理实现逻辑:
可以看这三篇博客
https://www.imooc.com/article/43378
https://www.imooc.com/article/43379
https://www.imooc.com/article/43380

发布了42 篇原创文章 · 获赞 29 · 访问量 2535

猜你喜欢

转载自blog.csdn.net/qq_32314335/article/details/103672715