目录

  • 前言
  • AOP是什么
  • AOP框架要做什么
  • AOP技术元素分析
  • Advice设计
  • pointcut设计
  • 表达式设计
  • 类、接口设计
  • aspect设计(advisor)
  • weaving设计
  • 织入要完成什么
  • 织入时机
  • 如何确定bean需要增强
  • 如何实现织入
  • 加入扩展点BeanPostProcessor
  • 定义切面注册接口AdvisorRegistry
  • 定义BeanFactory注册接口BeanFactoryAware
  • 自动代理核心类AdvisorAutoProxyCreator
  • Aop代理创建工厂
  • Aop代理接口AopProxy
  • jdk动态代理
  • cglib动态代理
  • Aop执行处理工具类
  • 责任链模式处理所有advice
  • 测试
  • 测试类
  • 通知类


前言

本篇基于(一)手写spring IOC容器手写AOP框架。采用问答形式,逐步梳理手写aop过程。

AOP是什么

Aspect Oriented Programming 面向切面编程,在不改变类的代码情况下,对类方法进行功能增强。

AOP框架要做什么

AOP框架要向使用用户提供AOP功能,让用户可以通过AOP技术实现对类方法进行功能增强。

AOP技术元素分析

包含
Advice:通知,增强的功能
joIn point:连接点,可选的方法点
pointcut:切入点,选择切入的方法点
aspect:切面,选择的(多个)方法点 + 增强的功能
introduction: 引入,添加新的方法、属性到已存在的类中
weaving:织入,不改变原类的的代码,加入功能增强,实现AOP

Advice设计

定义Advice接口

public interface Advice {
}

前置通知

/**
 * 前置增强接口
 */
public interface MethodBeforeAdvice extends Advice {
    /**
     * 前置增强方法
     * @param method 将要被执行的方法
     * @param args 执行方法参数
     * @param target 执行方法的目标对象
     */
    void before(Method method, Object[] args, Object target);
}

后置通知

/**
 * 后置增强接口
 */
public interface AfterReturningAdvice extends Advice {
    /**
     * 方法执行完毕后的增强接口
     * 
     * @param returnValue 方法执行完后的返回值
     * @param method    被执行的方法
     * @param args      方法执行参数
     * @param target    执行方法的对象
     */
    void afterReturning(Object returnValue, Method method, Object[] args, Object target);
}

环绕通知

/**
 * 方法环绕增强接口
 */
public interface MethodInterceptor extends Advice {
	/**
	 * 对方法进行环绕(前置、后置)增强、异常处理增强,方法实现中需调用目标方法。
	 * 
	 * @param method
	 *            被增强的方法
	 * @param args
	 *            方法的参数
	 * @param target
	 *            方法所属对象
	 * @return Object 返回值
	 * @throws Throwable
	 */
	Object invoke(Method method, Object[] args, Object target) throws Throwable;
}

pointcut设计

pointcut特点

  • 用户性:由用户指定
  • 变化性:用户可灵活指定
  • 多点性:用户可在多个方法上进行增强

表达式设计

表达式可以表示一类方法的完整签名,比如AspectJ的pointcut表达式、正则表达式

类、接口设计

pointcut接口

/**
 * 切点抽象接口
 */
public interface Pointcut {
	/**
	 * 匹配类
	 * @param targetClass 将被匹配的目标类
	 * @return	true,表示匹配规则;否则返回false。
	 */
	boolean matchsClass(Class<?> targetClass);

	/**
	 * 匹配方法
	 * @param method 将要被匹配的方法
	 * @param targetClass 将要被匹配的目标类
	 * @return true,表示匹配规则;否则返回false。
	 */
	boolean matchsMethod(Method method, Class<?> targetClass);
}

AspectJExpressionPointcut 类

/**
 * 
 * AspectJ表达式切点实现类
 */
public class AspectJExpressionPointcut implements Pointcut {
	// 先获得切点解析器
	private static PointcutParser pp = PointcutParser
			.getPointcutParserSupportingAllPrimitivesAndUsingContextClassloaderForResolution();
	
	// 切点表达式的字符串形式
	private String expression;
	
	// aspectj中的切点表达式实例pe
	private PointcutExpression pe;

	public AspectJExpressionPointcut(String expression) {
		super();
		this.expression = expression;
		pe = pp.parsePointcutExpression(expression);
	}

	@Override
	public boolean matchsClass(Class<?> targetClass) {
		return pe.couldMatchJoinPointsInType(targetClass);
	}

	@Override
	public boolean matchsMethod(Method method, Class<?> targetClass) {
		ShadowMatch sm = pe.matchesMethodExecution(method);
		return sm.alwaysMatches();
	}

	public String getExpression() {
		return expression;
	}

}

aspect设计(advisor)

advisor接口

/**
 * 用户构建切面的接口,组合Advice和Pointcut
 */
public interface Advisor {
    /**
     * 通知bean的名称
     * @return
     */
    String getAdviceBeanName();

    /**
     * 表达式
     * @return
     */
    String getExpression();
}

PointcutAdvisor接口

/**
 * 切点通知者,继承自Advisor扩展了Pointcut
 */
public interface PointcutAdvisor extends Advisor {

	Pointcut getPointcut();
}

AspectJPointcutAdvisor类

/**
 * 基于aspectj表达式切点的通知者实现
 */
public class AspectJPointcutAdvisor implements PointcutAdvisor {

	private String adviceBeanName;	// 通知bean名称

	private String expression;		// 切点表达式

	private Pointcut pointcut;	// aspectJ切点实例

	/**
	 * 构造函数
	 * @param adviceBeanName 通知bean名称
	 * @param expression	切点表达式
	 */
	public AspectJPointcutAdvisor(String adviceBeanName, String expression) {
		this.adviceBeanName = adviceBeanName;
		this.expression = expression;
		this.pointcut = new AspectJExpressionPointcut(this.expression);
	}

	@Override
	public Pointcut getPointcut() {
		return this.pointcut;
	}

	@Override
	public String getAdviceBeanName() {
		return this.adviceBeanName;
	}

	@Override
	public String getExpression() {
		return this.expression;
	}
}

weaving设计

织入要完成什么

将用户提供的增强功能加到指定方法上,需要我们在框架实现。

织入时机

创建bean实例的时候,完成初始化后,在对其增强

如何确定bean需要增强

对bean的类和方法挨个匹配用户指定的切面,如果有匹配的,那就应该增强

如何实现织入

动态代理

加入扩展点BeanPostProcessor

beanPostProcessor 接口

/**
 * 后置处理器。
 * Bean实例化完毕后及依赖注入完成后触发。
 */
public interface BeanPostProcessor {
	/**
	 * bean初始化前的处理
	 * @param bean
	 * @param beanName
	 * @return
	 * @throws Exception
	 */
	default Object postProcessBeforeInitialization(Object bean, String beanName) throws Exception {
		return bean;
	}

	/**
	 * bean初始化后的处理
	 * @param bean
	 * @param beanName
	 * @return
	 * @throws Exception
	 */
	default Object postProcessAfterInitialization(Object bean, String beanName) throws Exception {
		return bean;
	}
}

定义切面注册接口AdvisorRegistry

AdvisorRegistry接口

/**
 * 通知者注册接口
 */
public interface AdvisorRegistry {
	/**
	 * 注册通知者
	 * @param ad
	 */
	public void registAdvisor(Advisor ad);

	/**
	 * 获得通知者列表
	 * @return
	 */
	public List<Advisor> getAdvisors();
}

定义BeanFactory注册接口BeanFactoryAware

BeanFactoryAware接口

/**
 * bean工厂构建通知接口
 */
public interface BeanFactoryAware extends Aware {
	/**
	 * 接口实现者获得bean工厂方法
	 * @param bf
	 */
	void setBeanFactory(BeanFactory bf);
}

自动代理核心类AdvisorAutoProxyCreator

AdvisorAutoProxyCreator实现AdvisorRegistry、BeanPostProcessor、BeanFactoryAware接口

public class AdvisorAutoProxyCreator implements AdvisorRegistry, BeanPostProcessor, BeanFactoryAware {
	// 通知者列表
	private List<Advisor> advisors;
	// 当前的bean工厂
	private BeanFactory beanFactory;
	
	public AdvisorAutoProxyCreator() {
		this.advisors = new ArrayList<>();
	}
	// 注入通知者,级用户定义的切面内容
	public void registAdvisor(Advisor ad) {
		this.advisors.add(ad);
	}
	// 返回通知者列表
	public List<Advisor> getAdvisors() {
		return advisors;
	}
	
	// aware接口的实现,获得Bean工厂实例
	@Override
	public void setBeanFactory(BeanFactory bf) {
		this.beanFactory = bf;
	}

	/**
	 * Bean初始化后进行增强功能。
	 * 需要在不改变代码的情况实现该功能,则通过代理模式进行增强。
	 * @param bean 需要增强的bean
	 * @param beanName bean名称
	 * @return 最终被增强的的bean,此时的bean已经经过了代理模式的增强。
	 * @throws Throwable
	 */
	public Object postProcessAfterInitialization(Object bean, String beanName) throws Exception {

		// 在此判断bean是否需要进行切面增强,及获得增强的通知实现
		List<Advisor> matchAdvisors = getMatchedAdvisors(bean, beanName);
		// 如需要就进行增强,再返回增强的对象。
		if (CollectionUtils.isNotEmpty(matchAdvisors)) {
			// 通过代理模式进行功能增强
			bean = this.createProxy(bean, beanName, matchAdvisors);
		}
		return bean;
	}

	private List<Advisor> getMatchedAdvisors(Object bean, String beanName) {
		if (CollectionUtils.isEmpty(advisors)) {
			return null;
		}

		// 得到类、所有的方法
		Class<?> beanClass = bean.getClass();
		List<Method> allMethods = this.getAllMethodForClass(beanClass);

		// 存放匹配的Advisor的list
		List<Advisor> matchAdvisors = new ArrayList<>();
		// 遍历Advisor来找匹配的
		for (Advisor ad : this.advisors) {
			if (ad instanceof PointcutAdvisor) {
				if (isPointcutMatchBean((PointcutAdvisor) ad, beanClass, allMethods)) {
					matchAdvisors.add(ad);
				}
			}
		}

		return matchAdvisors;
	}

	private List<Method> getAllMethodForClass(Class<?> beanClass) {
		List<Method> allMethods = new LinkedList<>();
		Set<Class<?>> classes = new LinkedHashSet<>(ClassUtils.getAllInterfacesForClassAsSet(beanClass));
		classes.add(beanClass);
		for (Class<?> clazz : classes) {
			// 通过spring framework提供的工具类找出所有方法,包括从父类继承而来的方法
			Method[] methods = ReflectionUtils.getAllDeclaredMethods(clazz);
			for (Method m : methods) {
				allMethods.add(m);
			}
		}

		return allMethods;
	}

	/**
	 * 判断指定类中的方法是否有符合切点规则的。
	 * @param pa	方面信息,带有切点对象
	 * @param beanClass	指定的类
	 * @param methods	指定类中的所有方法
	 * @return
	 */
	private boolean isPointcutMatchBean(PointcutAdvisor pa, Class<?> beanClass, List<Method> methods) {
		Pointcut p = pa.getPointcut();

		// 首先判断类是否匹配
		if (!p.matchsClass(beanClass)) {
			return false;
		}

		// 再判断是否有方法匹配
		for (Method method : methods) {
			if (p.matchsMethod(method, beanClass)) {
				return true;
			}
		}
		return false;
	}

	/**
	 * 通过AopProxyFactory工厂去完成选择、和创建代理对象的工作。
	 * @param bean
	 * @param beanName
	 * @param matchAdvisors
	 * @return
	 * @throws Exception
	 */
	private Object createProxy(Object bean, String beanName, List<Advisor> matchAdvisors) throws Exception {
		// 默认的代理工厂实现中获得代理工厂实现
		return AopProxyFactory.getDefaultAopProxyFactory()
				// 根据参数信息,选择创建代理工厂具体实现
				.createAopProxy(bean, beanName, matchAdvisors, beanFactory)
				// 从选择的代理工厂中,获得代理对象
				.getProxy();
	}

}

Aop代理创建工厂

AopProxyFactory接口

/**
 * AOP代理接口的工厂模式接口
 */
public interface AopProxyFactory {
	/**
	 * 根据参数获得AOP代理接口的实现
	 * @param bean
	 * @param beanName
	 * @param matchAdvisors
	 * @param beanFactory
	 * @return
	 * @throws Exception
	 */
	AopProxy createAopProxy(Object bean, String beanName, List<Advisor> matchAdvisors, BeanFactory beanFactory)
			throws Exception;

	/**
	 * 获得默认的AopProxyFactory实例
	 * 
	 * @return AopProxyFactory
	 */
	static AopProxyFactory getDefaultAopProxyFactory() {
		return new DefaultAopProxyFactory();
	}
}

默认实现类DefaultAopProxyFactory类

public class DefaultAopProxyFactory implements AopProxyFactory {

	@Override
	public AopProxy createAopProxy(Object bean, String beanName, List<Advisor> matchAdvisors, BeanFactory beanFactory)
			throws Exception {
		// 是该用jdk动态代理还是cglib?
		if (shouldUseJDKDynamicProxy(bean, beanName)) {
			return new JdkDynamicAopProxy(beanName, bean, matchAdvisors, beanFactory);
		} else {
			return new CglibDynamicAopProxy(beanName, bean, matchAdvisors, beanFactory);
		}
	}

	private boolean shouldUseJDKDynamicProxy(Object bean, String beanName) {
		// 如何判断?
		// 这样可以吗:有实现接口就用JDK,没有就用cglib?
		// 请同学们在读spring的源码时看spring中如何来判断的
		return false;
	}

}

Aop代理接口AopProxy

AopProxy接口

/**
 * AOP代理接口,用来创建获得代理对象
 */
public interface AopProxy {
	/**
	 * Create a new proxy object.
	 * <p>
	 * Uses the AopProxy's default class loader (if necessary for proxy
	 * creation): usually, the thread context class loader.
	 * 
	 * @return the new proxy object (never {@code null})
	 * @see Thread#getContextClassLoader()
	 */
	Object getProxy();

	/**
	 * Create a new proxy object.
	 * <p>
	 * Uses the given class loader (if necessary for proxy creation).
	 * {@code null} will simply be passed down and thus lead to the low-level
	 * proxy facility's default, which is usually different from the default
	 * chosen by the AopProxy implementation's {@link #getProxy()} method.
	 * 
	 * @param classLoader
	 *            the class loader to create the proxy with (or {@code null} for
	 *            the low-level proxy facility's default)
	 * @return the new proxy object (never {@code null})
	 */
	Object getProxy(ClassLoader classLoader);

}
jdk动态代理

JdkDynamicAopProxy类

/**
 * JDk动态代理实现
 */
public class JdkDynamicAopProxy implements AopProxy, InvocationHandler {
	private static final Logger logger = LoggerFactory.getLogger(JdkDynamicAopProxy.class);

	private String beanName;	// bean名称
	private Object target;		// bean对象,需要被代理的对象
	private List<Advisor> matchAdvisors;		// 通知列表,需要被增强的一系列功能
	private BeanFactory beanFactory;	// bean工厂

	public JdkDynamicAopProxy(String beanName, Object target, List<Advisor> matchAdvisors, BeanFactory beanFactory) {
		this.beanName = beanName;
		this.target = target;
		this.matchAdvisors = matchAdvisors;
		this.beanFactory = beanFactory;
	}

	/**
	 * InvocationHandler接口的实现。
	 * 进行代理功能增强后返回实际的结果。
	 * @param proxy
	 * @param method
	 * @param args
	 * @return
	 * @throws Throwable
	 */
	@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		// 调用代理增强
		return AopProxyUtils.applyAdvices(target, method, args, matchAdvisors, proxy, beanFactory);
	}

	@Override
	public Object getProxy() {
		return this.getProxy(target.getClass().getClassLoader());
	}

	@Override
	public Object getProxy(ClassLoader classLoader) {
		if (logger.isDebugEnabled()) {
			logger.debug("为" + target + "创建代理。");
		}
		return Proxy.newProxyInstance(classLoader, target.getClass().getInterfaces(), this);
	}

}
cglib动态代理

CglibDynamicAopProxy

/**
 * CGLIB动态代理实现
 */
public class CglibDynamicAopProxy implements AopProxy, MethodInterceptor {
	private static final Logger logger = LoggerFactory.getLogger(CglibDynamicAopProxy.class);
	private static Enhancer enhancer = new Enhancer();

	private String beanName;
	private Object target;

	private List<Advisor> matchAdvisors;

	private BeanFactory beanFactory;

	public CglibDynamicAopProxy(String beanName, Object target, List<Advisor> matchAdvisors, BeanFactory beanFactory) {
		this.beanName = beanName;
		this.target = target;
		this.matchAdvisors = matchAdvisors;
		this.beanFactory = beanFactory;
	}

	@Override
	public Object getProxy() {
		return this.getProxy(target.getClass().getClassLoader());
	}

	@Override
	public Object getProxy(ClassLoader classLoader) {
		if (logger.isDebugEnabled()) {
			logger.debug("为" + target + "创建cglib代理。");
		}
		Class<?> superClass = this.target.getClass();
		enhancer.setSuperclass(superClass);
		enhancer.setInterfaces(this.getClass().getInterfaces());
		enhancer.setCallback(this);
		Constructor<?> constructor = null;
		try {
			constructor = superClass.getConstructor(new Class<?>[] {});
		} catch (NoSuchMethodException | SecurityException e) {

		}
		if (constructor != null) {
			return enhancer.create();
		} else {
			BeanDefinition bd = ((DefaultBeanFactory) beanFactory).getBeanDefinition(beanName);
			return enhancer.create(bd.getConstructor().getParameterTypes(), bd.getConstructorArgumentRealValues());
		}
	}

	/**
	 * 进行方法增强后的代理类方法调用,并获得返回结果。
	 * @param proxy
	 * @param method
	 * @param args
	 * @param methodProxy
	 * @return
	 * @throws Throwable
	 */
	@Override
	public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
		return AopProxyUtils.applyAdvices(target, method, args, matchAdvisors, proxy, beanFactory);
	}

}

Aop执行处理工具类

AopProxyUtils

/**
 * AOP代理工具类
 */
public class AopProxyUtils {

	/**
	 * 对方法应用advices增强,获得最终返回结果。
	 * 
	 * @param target bean对象,需要被增强的对象
	 * @param method	需要被增强的方法
	 * @param args	增强方法的参数
	 * @param matchAdvisors	匹配到的切面
	 * @param proxy	bean对象功能增强后的代理对象
	 * @param beanFactory ioc容器
	 * @return 方法增强后的返回结果
	 * @throws Throwable
	 */
	public static Object applyAdvices(Object target, Method method, Object[] args, List<Advisor> matchAdvisors,
                                      Object proxy, BeanFactory beanFactory) throws Throwable {
		// 这里要做什么?
		// 1、获取要对当前方法进行增强的advice Bean列表
		List<Object> advices = AopProxyUtils.getShouldApplyAdvices(target.getClass(), method, matchAdvisors,
				beanFactory);
		// 2、如有增强的advice,责任链式增强执行
		if (CollectionUtils.isEmpty(advices)) {
			return method.invoke(target, args);
		} else {
			// 责任链式执行增强
			AopAdviceChainInvocation chain = new AopAdviceChainInvocation(proxy, target, method, args, advices);
			return chain.invoke();
		}
	}

	/**
	 * 获取与方法匹配的切面的advices Bean对象列表
	 * 
	 * @param beanClass
	 * @param method
	 * @param matchAdvisors
	 * @param beanFactory
	 * @return
	 * @throws Exception
	 */
	public static List<Object> getShouldApplyAdvices(Class<?> beanClass, Method method, List<Advisor> matchAdvisors,
                                                     BeanFactory beanFactory) throws Throwable {
		if (CollectionUtils.isEmpty(matchAdvisors)) {
			return null;
		}
		List<Object> advices = new ArrayList<>();
		for (Advisor ad : matchAdvisors) {
			if (ad instanceof PointcutAdvisor) {
				if (((PointcutAdvisor) ad).getPointcut().matchsMethod(method, beanClass)) {
					advices.add(beanFactory.getBean(ad.getAdviceBeanName()));
				}
			}
		}

		return advices;
	}

}

责任链模式处理所有advice

AopAdviceChainInvocation类

/**
 * AOP通知链调用类
 */
public class AopAdviceChainInvocation {
	
	// AOP调用链执行方法
	private static Method invokeMethod;
	static {
		try {
			invokeMethod = AopAdviceChainInvocation.class.getMethod("invoke", null);
		} catch (NoSuchMethodException | SecurityException e) {
			e.printStackTrace();
		}
	}

	private Object proxy;	// 代理类对象
	private Object target;	// 目标类对象
	private Method method;	// 调用执行的对象方法
	private Object[] args;	// 执行方法的参数
	private List<Object> advices;	// 方法被增强的功能-通知列表

	public AopAdviceChainInvocation(Object proxy, Object target, Method method, Object[] args, List<Object> advices) {
		this.proxy = proxy;
		this.target = target;
		this.method = method;
		this.args = args;
		this.advices = advices;
	}

	// 责任链执行记录索引号
	private int i = 0;

	public Object invoke() throws Throwable {
		if (i < this.advices.size()) {
			Object advice = this.advices.get(i++);
			if (advice instanceof MethodBeforeAdvice) {
				// 执行前置增强
				((MethodBeforeAdvice) advice).before(method, args, target);
			} else if (advice instanceof MethodInterceptor) {
				// 执行环绕增强和异常处理增强。注意这里给入的method 和 对象 是invoke方法和链对象
				return ((MethodInterceptor) advice).invoke(invokeMethod, null, this);
			} else if (advice instanceof AfterReturningAdvice) {
				// 当是后置增强时,先得得到结果,再执行后置增强逻辑
				Object returnValue = this.invoke();
				((AfterReturningAdvice) advice).afterReturning(returnValue, method, args, target);
				return returnValue;
			}
			return this.invoke();	// 回调,遍历完advices列表
		} else {
			return method.invoke(target, args);
		}
	}

}

测试

测试类

public class AopTest {

    static PreBuildBeanFactory bf = new PreBuildBeanFactory();

    @Test
    public void testCirculationDI() throws Throwable {

        GenericBeanDefinition bd = new GenericBeanDefinition();
        bd.setBeanClass(Lad.class);
        List<Object> args = new ArrayList<>();
        args.add("sunwukong");
        args.add(new BeanReference("baigujing"));
        bd.setConstructorArgumentValues(args);
        bf.registerBeanDefinition("swk", bd);

        bd = new GenericBeanDefinition();
        bd.setBeanClass(MagicGril.class);
        args = new ArrayList<>();
        args.add("baigujing");
        bd.setConstructorArgumentValues(args);
        bf.registerBeanDefinition("baigujing", bd);

        bd = new GenericBeanDefinition();
        bd.setBeanClass(Renminbi.class);
        bf.registerBeanDefinition("renminbi", bd);

        // 前置增强advice bean注册
        bd = new GenericBeanDefinition();
        bd.setBeanClass(MyBeforeAdvice.class);
        bf.registerBeanDefinition("myBeforeAdvice", bd);

        // 环绕增强advice bean注册
        bd = new GenericBeanDefinition();
        bd.setBeanClass(MyMethodInterceptor.class);
        bf.registerBeanDefinition("myMethodInterceptor", bd);

        // 后置增强advice bean注册
        bd = new GenericBeanDefinition();
        bd.setBeanClass(MyAfterReturningAdvice.class);
        bf.registerBeanDefinition("myAfterReturningAdvice", bd);

        // 往BeanFactory中注册AOP的BeanPostProcessor
        AdvisorAutoProxyCreator aapc = new AdvisorAutoProxyCreator();
        bf.registerBeanPostProcessor(aapc);
        // 向AdvisorAutoProxyCreator注册Advisor
        aapc.registAdvisor(
                new AspectJPointcutAdvisor("myBeforeAdvice", "execution(* v2.di.MagicGril.*(..))"));
        // 向AdvisorAutoProxyCreator注册Advisor
        aapc.registAdvisor(
                new AspectJPointcutAdvisor("myMethodInterceptor", "execution(* v2.di.Lad.say*(..))"));
        // 向AdvisorAutoProxyCreator注册Advisor
        aapc.registAdvisor(new AspectJPointcutAdvisor("myAfterReturningAdvice",
                "execution(* v2.di.Renminbi.*(..))"));

        bf.preInstantiateSingletons();

        System.out.println("-----------------myBeforeAdvice---------------");
        MagicGril gril = (MagicGril) bf.getBean("baigujing");
        gril.getFriend();
        gril.getName();
        
        System.out.println("----------------myMethodInterceptor----------------");
        Boy boy = (Boy) bf.getBean("swk");
        boy.sayLove();
        
        System.out.println("-----------------myAfterReturningAdvice---------------");
        Renminbi rmb = (Renminbi) bf.getBean("renminbi");
        rmb.pay();
    }
}

通知类

public class MyAfterReturningAdvice implements AfterReturningAdvice {
    @Override
    public void afterReturning(Object returnValue, Method method, Object[] args, Object target) {
        System.out.println(this + " 对 " + target + " 做了后置增强,得到的返回值=" + returnValue);
    }
}

public class MyBeforeAdvice implements MethodBeforeAdvice {

    @Override
    public void before(Method method, Object[] args, Object target) {
        System.out.println(this + " 对 " + target + " 进行了前置增强!");
    }
}
public class MyMethodInterceptor implements MethodInterceptor {
    @Override
    public Object invoke(Method method, Object[] args, Object target) throws Throwable {
        System.out.println(this + "对 " + target + "进行了环绕--前增强");
        Object ret = method.invoke(target, args);
        System.out.println(this + "对 " + target + "进行了环绕 --后增强。方法的返回值为:" + ret);
        return ret;
    }
}

运行结果

-----------------myBeforeAdvice---------------
2021-01-20 10:32:41.772 DEBUG main CglibDynamicAopProxy - 为MagicGril{name='baigujing'}创建cglib代理。
v3.aop.aspectj.advice.MyBeforeAdvice@3c72f59f 对 MagicGril{name='baigujing'} 进行了前置增强!
v3.aop.aspectj.advice.MyBeforeAdvice@3c72f59f 对 MagicGril{name='baigujing'} 进行了前置增强!
----------------myMethodInterceptor----------------
2021-01-20 10:32:41.817 DEBUG main CglibDynamicAopProxy - 为v2.di.Lad@77167fb7创建cglib代理。
调用了含有MagicGril参数的构造方法
v3.aop.aspectj.advice.MyMethodInterceptor@7a4ccb53对 edu.dongnao.courseware.aop.AopAdviceChainInvocation@309e345f进行了环绕--前增强
I love you, my gril! MagicGril{name='baigujing'}
v3.aop.aspectj.advice.MyMethodInterceptor@7a4ccb53对 edu.dongnao.courseware.aop.AopAdviceChainInvocation@309e345f进行了环绕 --后增强。方法的返回值为:null
-----------------myAfterReturningAdvice---------------
2021-01-20 10:32:41.822 DEBUG main CglibDynamicAopProxy - 为v2.di.Renminbi@18ce0030创建cglib代理。
使用人民币成功进行了支付
v3.aop.aspectj.advice.MyAfterReturningAdvice@4df50bcc 对 v2.di.Renminbi@18ce0030 做了后置增强,得到的返回值=null