Spring AOP

AOP(底层原理)

1.1 AOP底层是使用动态代理进行实现

(1)有两种情况动态代理

1、有接口情况 使用JDK动态代理
创建接口实现类代理对象 增强类的方法

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cIxxxJEB-1617801756181)(C:\Users\dell\AppData\Roaming\Typora\typora-user-images\image-20210307153604401.png)]

2、 没有接口情况 使用cglib动态代理
创建子类的代理对象增强类的方法

``[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-csXYa9GC-1617801756183)(C:\Users\dell\AppData\Roaming\Typora\typora-user-images\image-20210307153751803.png)]

AOP底层原理(JDK动态代理)

1.使用JDK动态代理,使用Proxy里面的方法创建代理对象

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gEKGQFUS-1617801756185)(C:\Users\dell\AppData\Roaming\Typora\typora-user-images\image-20210307154138849.png)]

(1)调用newProxyInstance方法

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LeDxumoV-1617801756187)(C:\Users\dell\AppData\Roaming\Typora\typora-user-images\image-20210307154248773.png)]

方法里有三个参数:

​ 第一个参数:类加载器

​ 第二个参数:增加方法所在的类,这个类实现的接口,可以写多个接口

第三个参数:InvocationHandler :实现InvocationHandler 接口,创建代理的对象,写增强的方法【重点JVM会自动回调】

2、JDK动态代理代码

(1)创建接口,定义方法
public interface UserDao {

    public int add(int a,int b);

    public String update(String id);
}
(2)创建接口实现类,实现方法
public class UserDaoImpl implements UserDao{
    @Override
    public int add(int a, int b) {
        return a+b;
    }

    @Override
    public String update(String id) {
        return id;
    }
}
(3)使用Proxy类创建接口代理对象
package com.yc;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Arrays;

/**
 * @program: SpringAOP_demo
 * @description:
 * @author: HillCheung
 * @create: 2021-03-07 15:52
 */
public class JDKProxy {
    public static void main(String[] args) {
        //创捷接口实现类代理对象
        Class[] interfaces ={UserDao.class};
//        Proxy.newProxyInstance(JDKProxy.class.getClassLoader(), interfaces, new InvocationHandler() {
//
//
//            //匿名内部类
//            @Override
//            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//                return null;
//            }
//        });
        UserDaoImpl userDao =new UserDaoImpl();
        //代理对象
        UserDao dao = (UserDao) Proxy.newProxyInstance(JDKProxy.class.getClassLoader(), interfaces, new UserDaoProxy(userDao));
        System.out.println(dao.add(1, 1));
    }
}

class UserDaoProxy implements  InvocationHandler{

    //1.把创建的是谁的对象,把谁传递过来
    //有参数构造传递
    private Object obj;
    public UserDaoProxy(Object obj){
        this.obj=obj;
    }

    //增强的逻辑
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        //方法之前
        System.out.println("方法之前执行....."+method.getName()+":传递的参数"+ Arrays.toString(args));
        //被增强的方法执行
        Object res = method.invoke(obj, args);

        //方法之后
        System.out.println("方法之后执行...."+obj);
        return res;
    }
}

AOP(术语)

1.连接点

类里面的哪些方法可以被增强,这些方法可以称为连接点

2.切入点

实际被增强的方法,被称为切入点

3.通知(增强)

(1)实际增强的逻辑部分称为通知

(2)通知有多种类型

​ 1.前置通知

​ 2.后置通知

​ 3.环绕通知

​ 4.异常通知

​ 5.最终通知(finally)

4.切面

是动作

(1)把通知应用到切入点的过程叫做切面

AOP操作(准备)

Spring框架中一般基于AspectJ实现AOP操作

(1)什么是AspectJ

AspectJ不是Spring的组成部分,独立AOP框架,一般把AspectJ和Spring框架进行使用,进行AOP操作

2.基于AspectJ使用AOP操作

基于 xml配置文件进行配置

基于注解方式进行配置(使用)

3. 在项目工程中引用AOP相关依赖

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6nDI9r2D-1617801756189)(C:\Users\dell\AppData\Roaming\Typora\typora-user-images\image-20210307163309160.png)]

4.切入点表达式

(1)切入点表达式作用:知道对哪个类里面的哪个方法进行增强

(2)语法结构:

execution([权限修饰符] [返回类型] [类全路径] [方法名称] ([参数列表]))

举例1: 对com.yc.dao.BookDao类里面的add方法

execution(* com.yc.dao.BookDao.add(…))

举例2: 对com.yc.dao.BookDao类里面的所有方法

execution(* com.yc.dao.BookDao.*(…))

举例3: 对com.yc.dao包里面的所有类,类里面所有方法进行增强

execution(* com.yc.dao..(…))

AOP操作(AspectJ注解)

1.创建类,在类里面定义方法

public class User {
    public void add(){
        System.out.println("add.......");
    }
}

2.创建增强类,编写你增强的逻辑

(1)在增强类里面,创建方法,让不同方法代表不同通知类型

//增强的类
public class UserProxy {

    //前置通知java
    public void before(){
        System.out.println("before......");
    }

}

3.进行配置的通知

(1)在spring配置文件中开启注解扫描

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
                        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
                        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
    <!-- 开启注解扫描 -->
    <context:component-scan base-package="com.yc.annoactionaop"></context:component-scan>

    <!-- 开启Aspect生成代理对象-->
    <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
</beans>

(2)使用注解创建User和UserProxy对象

在User和UserProxy类上面加入@compent注解

(3)在增强类上面添加@Aspect

//增强的类
    @Component
    @Aspect //生成代理对象
public class UserProxy {

    //前置通知
    public void before(){
        System.out.println("before......");
    }

}

(4)在Spring配置文件中开启生成代理对象

(1)在增强类的里面,在作为通知方法上面通知类型注解,使用切入点表达式

//增强的类
    @Component
    @Aspect //生成代理对象
public class UserProxy {

        //
        @Before(value = "execution(* com.yc.annoactionaop.User.add(..))")
    //前置通知
    public void before(){
        System.out.println("before......");
    }

}

AOP源码分析(重点)

1)寻找 aop:aspectj-autoproxy/ 注解对应的解析器

但凡注解都有对应的解析器,以用来解析该注解的行为。全局搜索之后可发现

public class AopNamespaceHandler extends NamespaceHandlerSupport {

   /**
    * Register the {@link BeanDefinitionParser BeanDefinitionParsers} for the
    * '{@code config}', '{@code spring-configured}', '{@code aspectj-autoproxy}'
    * and '{@code scoped-proxy}' tags.
    */
   @Override
   public void init() {
      // In 2.0 XSD as well as in 2.5+ XSDs
      registerBeanDefinitionParser("config", new ConfigBeanDefinitionParser());
      //重点
      registerBeanDefinitionParser("aspectj-autoproxy", new AspectJAutoProxyBeanDefinitionParser());
      registerBeanDefinitionDecorator("scoped-proxy", new ScopedProxyBeanDefinitionDecorator());

      // Only in 2.0 XSD: moved to context namespace in 2.5+
      registerBeanDefinitionParser("spring-configured", new SpringConfiguredBeanDefinitionParser());
   }

}

2)了解AspectJAutoProxyBeanDefinitionParser对应的行为

class AspectJAutoProxyBeanDefinitionParser implements BeanDefinitionParser {
 
	@Override
	public BeanDefinition parse(Element element, ParserContext parserContext) {
        // 1.注册proxy creator
		AopNamespaceUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(parserContext, element);
		extendBeanDefinition(element, parserContext);
		return null;
	}
    ...
    
    // registerAspectJAnnotationAutoProxyCreatorIfNecessary()
    public static void registerAspectJAnnotationAutoProxyCreatorIfNecessary(
			ParserContext parserContext, Element sourceElement) {
        // 注册行为主要内容
		BeanDefinition beanDefinition = AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(
				parserContext.getRegistry(), parserContext.extractSource(sourceElement));
		useClassProxyingIfNecessary(parserContext.getRegistry(), sourceElement);
		registerComponentIfNecessary(beanDefinition, parserContext);
	}
 
    // registerAspectJAnnotationAutoProxyCreatorIfNecessary()
	public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry, Object source) {
        // 主要就是为了注册AnnotationAwareAspectJAutoProxyCreator类
		return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
	}
 
    // 注册类相关代码
    private static BeanDefinition registerOrEscalateApcAsRequired(Class<?> cls, BeanDefinitionRegistry registry, Object source) {
		Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
		if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {
			BeanDefinition apcDefinition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);
			if (!cls.getName().equals(apcDefinition.getBeanClassName())) {
				int currentPriority = findPriorityForClass(apcDefinition.getBeanClassName());
				int requiredPriority = findPriorityForClass(cls);
				if (currentPriority < requiredPriority) {
					apcDefinition.setBeanClassName(cls.getName());
				}
			}
			return null;
		}
        
        // 类似于我们在使用BeanFactory.getBean()时候的操作,生成一个RootBeanDefinition,然后放入map中
		RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);
		beanDefinition.setSource(source);
		beanDefinition.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE);
		beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
		registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition);
		return beanDefinition;
	}

总结:通过以上的代码分析,可知,AspectJAutoProxyBeanDefinitionParser主要的功能就是将*AnnotationAwareAspectJAutoProxyCreator注册到Spring容器中,把bean交给Spring去托管。*****

3)分析AnnotationAwareAspectJAutoProxyCreator主要行为

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-F64waX8P-1617801756190)(C:\Users\dell\AppData\Roaming\Typora\typora-user-images\image-20210307193228939.png)]

通过查看AnnotationAwareAspectJAutoProxyCreator的类层次结构,可知,其实现了BeanPostProcessor接口,实现类为AbstractAutoProxyCreator

4)AbstractAutoProxyCreator主要方法

``

@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) {
   return bean;
}

/**
 * Create a proxy with the configured interceptors if the bean is
 * identified as one to proxy by the subclass.
 * @see #getAdvicesAndAdvisorsForBean
 */
 
 
 // 主要看这个方法,在bean初始化之后对生产出的bean进行包装

@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.
		 // 意思就是如果该类有advice(通知 增强)则创建proxy
		Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
		if (specificInterceptors != DO_NOT_PROXY) {
			this.advisedBeans.put(cacheKey, Boolean.TRUE);
			  // 1.通过方法名也能简单猜测到,这个方法就是把bean包装为proxy的主要方法,
			Object proxy = createProxy(
					bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
			this.proxyTypes.put(cacheKey, proxy.getClass());
			 // 2.返回该proxy代替原来的bean
			return proxy;
		}

		this.advisedBeans.put(cacheKey, Boolean.FALSE);
		return bean;
	}

总结:

**1)通过AspectJAutoProxyBeanDefinitionParser类将AnnotationAwareAspectJAutoProxyCreator注册到Spring容器中 **

2)AnnotationAwareAspectJAutoProxyCreator类的postProcessAfterInitialization()方法将所有有advice的bean重新包装成proxy

4.创建proxy过程分析

以下是AbstractAutoProxyCreator.wrapIfNecessary(Object bean, String beanName, Object cacheKey)中的createProxy()代码片段分析

/**
 * Wrap the given bean if necessary, i.e. if it is eligible for being proxied.
 * @param bean the raw bean instance
 * @param beanName the name of the bean
 * @param cacheKey the cache key for metadata access
 * @return a proxy wrapping the bean, or the raw bean instance as-is
 */
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);
       //重点createProxy
      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;
}

createProxy源码分析

protected Object createProxy(Class<?> beanClass, @Nullable String beanName,
      @Nullable Object[] specificInterceptors, TargetSource targetSource) {

   if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
      AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
   }
	// 1.创建proxyFactory,proxy的生产主要就是在proxyFactory做的
   ProxyFactory proxyFactory = new ProxyFactory();
   proxyFactory.copyFrom(this);

   if (!proxyFactory.isProxyTargetClass()) {
      if (shouldProxyTargetClass(beanClass, beanName)) {
         proxyFactory.setProxyTargetClass(true);
      }
      else {
         evaluateProxyInterfaces(beanClass, proxyFactory);
      }
   }
// 2.将当前bean适合的advice,重新封装下,封装为Advisor类,然后添加到ProxyFactory中
   Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
   proxyFactory.addAdvisors(advisors);
   proxyFactory.setTargetSource(targetSource);
   customizeProxyFactory(proxyFactory);

   proxyFactory.setFrozen(this.freezeProxy);
   if (advisorsPreFiltered()) {
      proxyFactory.setPreFiltered(true);
   }
// 3.调用getProxy获取bean对应的proxy
   return proxyFactory.getProxy(getProxyClassLoader());
}

1)创建何种类型的Proxy?JDKProxy还是CGLIBProxy?

public Object getProxy(@Nullable ClassLoader classLoader) {
    //点击去看源码
   return createAopProxy().getProxy(classLoader);
}
	protected final synchronized AopProxy createAopProxy() {
		if (!this.active) {
			activate();
		}
         //点击去看源码
		return getAopProxyFactory().createAopProxy(this);
	}
  // createAopProxy()
	public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
        // 1.config.isOptimize()是否使用优化的代理策略,目前使用与CGLIB
        // config.isProxyTargetClass() 是否目标类本身被代理而不是目标类的接口
        // hasNoUserSuppliedProxyInterfaces()是否存在代理接口
		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.");
			}
            
            // 2.如果目标类是接口或者是代理类,则直接使用JDKproxy
			if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
				return new JdkDynamicAopProxy(config);
			}
            
            // 3.其他情况则使用CGLIBproxy
			return new ObjenesisCglibAopProxy(config);
		}
		else {
			return new JdkDynamicAopProxy(config);
		}
	}

(2)CGLIB

class ObjenesisCglibAopProxy extends CglibAopProxy {

	private static final Log logger = LogFactory.getLog(ObjenesisCglibAopProxy.class);

	private static final SpringObjenesis objenesis = new SpringObjenesis();


	/**
	 * Create a new ObjenesisCglibAopProxy for the given AOP configuration.
	 * @param config the AOP configuration as AdvisedSupport object
	 */
	public ObjenesisCglibAopProxy(AdvisedSupport config) {
		super(config);
	}

	//创建代理类和实例(核心代码)
	@Override
	protected Object 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;
	}

}

(2)JDK动态代理

final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializable// JdkDynamicAopProxy类结构,由此可知,其实现了InvocationHandler,则必定有invoke方法,来被调用,也就是用户调用bean相关方法时,此invoke()被真正调用
    // getProxy()
    public Object getProxy(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);
        
        // JDK proxy 动态代理的标准用法
		return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
	}

(3) invoke()方法

以上的代码模式可以很明确的看出来,使用了JDK动态代理模式,真正的方法执行在invoke()方法里,下面我们来看下该方法,来看下bean方法如何被代理执行的

public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
MethodInvocation invocation;
Object oldProxy = null;
boolean setProxyContext = false;
	TargetSource targetSource = this.advised.targetSource;
	Class<?> targetClass = null;
	Object target = null;
 
	try {
        // 1.以下的几个判断,主要是为了判断method是否为equals、hashCode等Object的方法
		if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
			// The target does not implement the equals(Object) method itself.
			return equals(args[0]);
		}
		else if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
			// The target does not implement the hashCode() method itself.
			return hashCode();
		}
		else if (method.getDeclaringClass() == DecoratingProxy.class) {
			// There is only getDecoratedClass() declared -> dispatch to proxy config.
			return AopProxyUtils.ultimateTargetClass(this.advised);
		}
		else if (!this.advised.opaque && method.getDeclaringClass().isInterface() &&
				method.getDeclaringClass().isAssignableFrom(Advised.class)) {
			// Service invocations on ProxyConfig with the proxy config...
			return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);
		}
 
		Object retVal;
 
		if (this.advised.exposeProxy) {
			// Make invocation available if necessary.
			oldProxy = AopContext.setCurrentProxy(proxy);
			setProxyContext = true;
		}
 
		// May be null. Get as late as possible to minimize the time we "own" the target,
		// in case it comes from a pool.
		target = targetSource.getTarget();
		if (target != null) {
			targetClass = target.getClass();
		}
 
		// 2.获取当前bean被拦截方法链表
		List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
 
		// 3.如果为空,则直接调用target的method
		if (chain.isEmpty()) {
			Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
			retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
		}
        // 4.不为空,则逐一调用chain中的每一个拦截方法的proceed
		else {
			// We need to create a method invocation...
			invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
			// Proceed to the joinpoint through the interceptor chain.
			retVal = invocation.proceed();
		}
 
		...
		return retVal;
	}
	...
}

4)拦截方法真正被执行调用invocation.proceed()

public Object proceed() throws Throwable {
//	We start with an index of -1 and increment early.
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
return invokeJoinpoint();
	}
Object interceptorOrInterceptionAdvice =
			this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
	if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
		// Evaluate dynamic method matcher here: static part will already have
		// been evaluated and found to match.
		InterceptorAndDynamicMethodMatcher dm =
				(InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
		if (dm.methodMatcher.matches(this.method, this.targetClass, this.arguments)) {
			return dm.interceptor.invoke(this);
		}
		else {
			// Dynamic matching failed.
			// Skip this interceptor and invoke the next in the chain.
			return proceed();
		}
	}
	else {
		// It's an interceptor, so we just invoke it: The pointcut will have
		// been evaluated statically before this object was constructed.
		return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
	}
}

总结4:依次遍历拦截器链的每个元素,然后调用其实现,将真正调用工作委托给各个增强器

总结:

纵观以上过程可知:实际就是为bean创建一个proxy,JDKproxy或者CGLIBproxy,然后在调用bean的方法时,会通过proxy来调用bean方法

重点过程可分为:

1)通过AspectJAutoProxyBeanDefinitionParser类将AnnotationAwareAspectJAutoProxyCreator注册到Spring容器中

2)AnnotationAwareAspectJAutoProxyCreator类的postProcessAfterInitialization()方法将所有有advice的bean重新包装成proxy

3)调用bean方法时通过proxy来调用,proxy依次调用增强器的相关方法,来实现方法切入


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值