先来个简单demo
1首先在xml配置使用aop的标签
2.在创建一个切面系统
3.然后进行测试就行了 666666666666666
源码分析:首先aop 是自定义标签,我们知道spring解析自定义标签的步骤会
首先获取标签的命名空间,
然后提取自定义的解析器,
最后进行自定义标签的解析
其中得到名称空间会马上执行继承了 NamespaceHandlerSupport 中的init()方法进行解析器的注册
NamespaceHandler namespaceHandler = (NamespaceHandler)BeanUtils.instantiateClass(handlerClass);
namespaceHandler.init();
handlerMappings.put(namespaceUri, namespaceHandler);
return namespaceHandler;
解析返回的是一个BeanDedinition,parse()方法的实现在NamespaceHandlerSupport
private BeanDefinitionParser findParserForElement(Element element, ParserContext parserContext) {
//localName 为aop
String localName = parserContext.getDelegate().getLocalName(element);
//找到aop 对应的解析器 AspectJAutoProxyBeanDefinitionParser
BeanDefinitionParser parser = this.parsers.get(localName);
if (parser == null) {
parserContext.getReaderContext().fatal(
"Cannot locate BeanDefinitionParse
r for element [" + localName + "]", element);
}
return parser;
所有的解析器都是对BeanDefinitionParser接口的统一实现:
class AspectJAutoProxyBeanDefinitionParser implements BeanDefinitionParser
入口都为parse()方法
public BeanDefinition parse(Element element, ParserContext parserContext) {
AopNamespaceUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(parserContext, element);
this.extendBeanDefinition(element, parserContext);
return null;
public static void registerAspectJAnnotationAutoProxyCreatorIfNecessary(ParserContext parserContext, Element sourceElement) {
BeanDefinition beanDefinition = AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(parserContext.getRegistry(), parserContext.extractSource(sourceElement));
useClassProxyingIfNecessary(parserContext.getRegistry(), sourceElement);
registerComponentIfNecessary(beanDefinition, parserContext);
}
public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry, Object source) {
return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
}
主要是向容器中注册了AnnotationAwareAspectJAutoProxyCreator;类型的组件
AnnotationAwareAspectJAutoProxyCreator 的父类AbstractAutoProxyCreator 实现BeanPostProcess
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if(bean != null) {
Object cacheKey = this.getCacheKey(bean.getClass(), beanName);
if(!this.earlyProxyReferences.contains(cacheKey)) {
return this.wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
if(beanName != null && this.targetSourcedBeans.contains(beanName)) {
return bean;
} else if(Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
return bean;
} else if(!this.isInfrastructureClass(bean.getClass()) && !this.shouldSkip(bean.getClass(), beanName)) {
//获取增强器
Object[] specificInterceptors = this.getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, (TargetSource)null);
if(specificInterceptors != DO_NOT_PROXY) {
this.advisedBeans.put(cacheKey, Boolean.TRUE);
//创建代理对象
Object proxy = this.createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
} else {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
} else {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
}
获取增强器其实是有AnnotationAwareAspectJAutoProxyCreator中的:
protected List<Advisor> findCandidateAdvisors() {
List<Advisor> advisors = super.findCandidateAdvisors();
advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
return advisors;
}
这个时候返回的增强器有两个一个是after增强器,另一个为before增强器
public Advisor getAdvisor(Method candidateAdviceMethod, MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrderInAspect, String aspectName) {
this.validate(aspectInstanceFactory.getAspectMetadata().getAspectClass());
//切点信息的获取 :也就是execution 表达式
AspectJExpressionPointcut expressionPointcut = this.getPointcut(candidateAdviceMethod, aspectInstanceFactory.getAspectMetadata().getAspectClass());
//红色标记 使用切点信息生成增强器
return expressionPointcut == null?null:new InstantiationModelAwarePointcutAdvisorImpl(expressionPointcut, candidateAdviceMethod, this, aspectInstanceFactory, declarationOrderInAspect, aspectName);
}
//获取方法上面的注解
protected static AbstractAspectJAdvisorFactory.AspectJAnnotation<?> findAspectJAnnotationOnMethod(Method method) {
Class<?>[] classesToLookFor = new Class[]{Before.class, Around.class, After.class, AfterReturning.class, AfterThrowing.class, Pointcut.class};
Class[] var2 = classesToLookFor;
int var3 = classesToLookFor.length;
for(int var4 = 0; var4 < var3; ++var4) {
Class<?> c = var2[var4];
AbstractAspectJAdvisorFactory.AspectJAnnotation<?> foundAnnotation = findAnnotation(method, c);
if(foundAnnotation != null) {
return foundAnnotation;
}
}
return null;
}
这里使用了后置增强
JdkDynamicAopProxy 的
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object oldProxy = null;
boolean setProxyContext = false;
TargetSource targetSource = this.advised.targetSource;
Class<?> targetClass = null;
Object target = null;
Boolean var10;
try {
if(this.equalsDefined || !AopUtils.isEqualsMethod(method)) {
if(!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
Integer var20 = Integer.valueOf(this.hashCode());
return var20;
}
if(method.getDeclaringClass() == DecoratingProxy.class) {
Class var18 = AopProxyUtils.ultimateTargetClass(this.advised);
return var18;
}
Object retVal;
if(!this.advised.opaque && method.getDeclaringClass().isInterface() && method.getDeclaringClass().isAssignableFrom(Advised.class)) {
retVal = AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);
return retVal;
}
if(this.advised.exposeProxy) {
oldProxy = AopContext.setCurrentProxy(proxy);
setProxyContext = true;
}
target = targetSource.getTarget();
if(target != null) {
targetClass = target.getClass();
}
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
if(chain.isEmpty()) {
Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
} else {
MethodInvocation invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
retVal = invocation.proceed();
}
Class<?> returnType = method.getReturnType();
if(retVal != null && retVal == target && returnType != Object.class && returnType.isInstance(proxy) && !RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {
retVal = proxy;
} else if(retVal == null && returnType != Void.TYPE && returnType.isPrimitive()) {
throw new AopInvocationException("Null return value from advice does not match primitive return type for: " + method);
}
Object var13 = retVal;
return var13;
}
var10 = Boolean.valueOf(this.equals(args[0]));
} finally {
if(target != null && !targetSource.isStatic()) {
targetSource.releaseTarget(target);
}
if(setProxyContext) {
AopContext.setCurrentProxy(oldProxy);
}
}
return var10;
}
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
代理对象-----执行目标方法时候会进入intercept()方法
//获得拦截器链
拦截器链(每一个通知方法又被包装为方法拦截器,利用MethodInterceptor机制)
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
//拦截器链为空,直接执行目标方法
if(chain.isEmpty() && Modifier.isPublic(method.getModifiers())) {
Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
retVal = methodProxy.invoke(target, argsToUse);
} else {
//不为空把需要执行的目标对象,目标方法, 拦截器链等信息传入创建一个 CglibMethodInvocation 对象,
retVal = (new CglibAopProxy.CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy)).proceed();
}
}
拦截器链的触发过程;
1)、如果没有拦截器执行执行目标方法,或者拦截器的索引和拦截器数组-1大小一样(指定到了最后一个拦截器)执行目标方法;
return this.invokeJoinpoint();
return method.invoke(target, args);//执行目标方法
2)、链式获取每一个拦截器,拦截器执行invoke方法,每一个拦截器等待下一个拦截器执行完成返回以后再来执行;
拦截器链的机制,保证通知方法与目标方法的执行顺序;
先执行before()的通知方法
继续执行after的通知方法
注解版的
@EnableAspectJAutoProxy
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import({AspectJAutoProxyRegistrar.class})//想容器总注册AspectJAutoProxyRegistrar注解
public @interface EnableAspectJAutoProxy {
boolean proxyTargetClass() default false;
boolean exposeProxy() default false;
}