MiniSpring框架学习笔记-AutoProxyCreator如何自动添加动态代理20. AutoProxyCreator如何自动添加动态代理一、先看最终配置二、为什么使用 BeanPostProcessor三、先把自动代理处理器注册进容器四、实现 BeanNameAutoProxyCreator五、容器最终保存的到底是什么六、验证自动代理七、当前教学实现的边界小结教程https://github.com/YaleGuo/minis极客时间手把手带你写一个 MiniSpring前言本节的主线就是将之前由写在XML里面的代理匹配模式直接写明action类这个需要代理)改成在IOC容器创建Bean的时候通过Bean后置处理器增强通过Bean的名字去匹配带着这个思路去看很容易明白。20. AutoProxyCreator如何自动添加动态代理上一节中我们已经能用Pointcut批量匹配需要增强的方法。不过哪个 Bean 需要代理仍然要逐个配置beanidrealactionclasscom.chenhai.test.Action1/beanidactionclasscom.chenhai.aop.ProxyFactoryBeanpropertytypejava.lang.Objectnametargetrefrealaction/propertytypeStringnameinterceptorNamevalueadvisor//bean这种方式代理一个对象没有问题。如果Action1、Action2等一批对象都要使用同一个Advisor就得反复配置ProxyFactoryBean。本节要把“为目标对象组装ProxyFactoryBean”这件事也交给容器。我们只配置一条 Bean 名称规则容器创建 Bean 时自动判断它是否需要代理。一、先看最终配置项目中的beans.xml不再为每个业务对象手写代理工厂而是增加一个BeanNameAutoProxyCreatorbeanidbeforeAdviceclasscom.chenhai.test.MyBeforeAdvice/beanidadvisorclasscom.chenhai.aop.NameMatchMethodPointcutAdvisorpropertytypecom.chenhai.aop.AdvicenameadvicerefbeforeAdvice/propertytypeStringnamemappedNamevaluedo*//beanbeanidautoProxyCreatorclasscom.chenhai.aop.framework.autoproxy.BeanNameAutoProxyCreatorpropertytypeStringnamepatternvalueaction*/propertytypeStringnameinterceptorNamevalueadvisor//beanbeanidactionclasscom.chenhai.test.Action1/beanidaction2classcom.chenhai.test.Action2/这里有两层匹配不要混在一起配置匹配对象作用patternaction*Bean 名称决定哪些 Bean 要创建代理mappedNamedo*方法名称决定代理中的哪些方法要执行通知因此action和action2都会被自动代理调用它们的doAction()、doSomething()时又都会命中do*先执行beforeAdvice。整个过程可以先记成下面这条主线ApplicationContext.refresh() ↓ 提前注册 BeanNameAutoProxyCreator ↓ 容器创建 action / action2 ↓ BeanNameAutoProxyCreator 用 action* 匹配 beanName ↓ 命中后把真实 Bean 包装成 ProxyFactoryBean ↓ getBean() 识别到 FactoryBean调用其 getObject() ↓ ProxyFactoryBean 根据 advisor 创建 JDK 动态代理对象 ↓ 业务代码最终拿到 IAction 代理对象二、为什么使用 BeanPostProcessor创建一个 Bean 时当前 MiniSpring 会依次完成这些步骤实例化 Bean ↓ 填充 XML 属性 ↓ 执行 Aware 回调 ↓ 初始化前处理 ↓ 执行 init-method ↓ 初始化后处理 ↓ 注册单例BeanPostProcessor正好提供了两个可以插入通用逻辑的扩展点publicinterfaceBeanPostProcessor{defaultObjectpostProcessBeforeInitialization(Objectbean,StringbeanName)throwsBeansException{returnbean;}defaultObjectpostProcessAfterInitialization(Objectbean,StringbeanName)throwsBeansException{returnbean;}}这里的post可以理解为“附加处理”不等于只能在初始化之后处理。真正的执行时机要看实现的是postProcessBeforeInitialization()还是postProcessAfterInitialization()。后置处理器还可以返回另一个对象。容器会沿用这个返回值继续执行后面的创建流程并最终把它放入单例池。自动代理正是利用这一点把普通业务 Bean 替换成包装它的ProxyFactoryBean。当前项目在createBean()中调用后置处理器的代码如下privateObjectcreateBean(StringbeanName,BeanDefinitionbeanDefinition)throwsBeansException{try{Class?beanClassClass.forName(beanDefinition.getClassName());ObjectbeaninstantiateBean(beanClass,beanDefinition.getConstructorArgumentValues());if(beanDefinition.isSingleton()){this.earlySingletonObjects.put(beanName,bean);}// 先完成 XML 属性注入。populateBean(beanDefinition,beanClass,bean);// 再回调 BeanFactoryAware 等 Aware 接口。invokeAwareMethods(bean);ObjectprocessedBeanapplyBeanPostProcessorsBeforeInitialization(bean,beanName);if(processedBean!null){beanprocessedBean;}invokeInitMethod(beanDefinition,bean);processedBeanapplyBeanPostProcessorsAfterInitialization(bean,beanName);if(processedBean!null){beanprocessedBean;}returnbean;}catch(BeansExceptione){throwe;}catch(Exceptione){thrownewBeansException(Create bean failed: beanName);}}applyBeanPostProcessorsBeforeInitialization()会按注册顺序调用所有处理器并把前一个处理器的返回值交给下一个处理器publicObjectapplyBeanPostProcessorsBeforeInitialization(ObjectexistingBean,StringbeanName)throwsBeansException{ObjectresultexistingBean;for(BeanPostProcessorbeanProcessor:getBeanPostProcessors()){ObjectcurrentbeanProcessor.postProcessBeforeInitialization(result,beanName);if(currentnull){returnresult;}resultcurrent;}returnresult;}当前项目先注册AutowiredAnnotationBeanPostProcessor再注册 XML 中的自动代理处理器。因此业务对象会先完成Autowired字段注入再由BeanNameAutoProxyCreator包装。三、先把自动代理处理器注册进容器这里有一个先后顺序问题如果普通 Bean 已经创建完了再注册自动代理处理器它就没有机会处理这些 Bean。所以ApplicationContext.refresh()必须先注册BeanPostProcessor再通过onRefresh()预实例化普通单例publicvoidrefresh()throwsBeansException,IllegalStateException{this.startupDateSystem.currentTimeMillis();this.closed.set(false);this.active.set(true);postProcessBeanFactory(getBeanFactory());invokeBeanFactoryPostProcessors(getBeanFactory());// 先注册 BeanPostProcessor。registerBeanPostProcessors(getBeanFactory());initApplicationEventPublisher();registerListeners();// 再预实例化非懒加载单例。onRefresh();finishRefresh();}ClassPathXmlApplicationContext除了注册内置的自动注入处理器还会找出 XML 中声明的所有BeanPostProcessorOverrideprotectedvoidregisterBeanPostProcessors(ConfigurableListableBeanFactorybeanFactory)throwsBeansException{// 内置处理器负责 Autowired 字段注入。beanFactory.addBeanPostProcessor(newAutowiredAnnotationBeanPostProcessor(beanFactory));// XML 中声明的处理器本章会找到 autoProxyCreator。MapString,BeanPostProcessorpostProcessorsbeanFactory.getBeansOfType(BeanPostProcessor.class);for(BeanPostProcessorpostProcessor:postProcessors.values()){beanFactory.addBeanPostProcessor(postProcessor);}}getBeansOfType(BeanPostProcessor.class)会先根据类型找出autoProxyCreator创建它再放入后置处理器列表。因为BeanNameAutoProxyCreator实现了BeanFactoryAware创建过程中容器还会把当前BeanFactory回调给它后面就能按名称查找advisor。四、实现 BeanNameAutoProxyCreatorBeanNameAutoProxyCreator的核心职责只有三步根据pattern匹配beanName排除 AOP 基础设施对象为命中的业务对象组装ProxyFactoryBean。项目中的实现如下packagecom.chenhai.aop.framework.autoproxy;importcom.chenhai.BeansException;importcom.chenhai.aop.Advice;importcom.chenhai.aop.Advisor;importcom.chenhai.aop.AopProxyFactory;importcom.chenhai.aop.DefaultAopProxyFactory;importcom.chenhai.aop.ProxyFactoryBean;importcom.chenhai.beans.factory.BeanFactory;importcom.chenhai.beans.factory.BeanFactoryAware;importcom.chenhai.beans.factory.FactoryBean;importcom.chenhai.beans.factory.config.BeanPostProcessor;importcom.chenhai.util.PatternMatchUtils;/** * 按 Bean 名称自动创建 AOP 代理。 */publicclassBeanNameAutoProxyCreatorimplementsBeanPostProcessor,BeanFactoryAware{// 要代理的 Bean 名称模式例如 action*。privateStringpattern;// 容器中的 Advisor 或 Advice Bean 名称。privateStringinterceptorName;privateBeanFactorybeanFactory;privateAopProxyFactoryaopProxyFactory;publicBeanNameAutoProxyCreator(){this.aopProxyFactorynewDefaultAopProxyFactory();}publicvoidsetPattern(Stringpattern){this.patternpattern;}publicStringgetPattern(){returnthis.pattern;}publicvoidsetInterceptorName(StringinterceptorName){this.interceptorNameinterceptorName;}publicStringgetInterceptorName(){returnthis.interceptorName;}publicvoidsetAopProxyFactory(AopProxyFactoryaopProxyFactory){this.aopProxyFactoryaopProxyFactory;}OverridepublicvoidsetBeanFactory(BeanFactorybeanFactory)throwsBeansException{this.beanFactorybeanFactory;}OverridepublicObjectpostProcessBeforeInitialization(Objectbean,StringbeanName)throwsBeansException{if(!isMatch(beanName,this.pattern)||isInfrastructureBean(bean)){returnbean;}ProxyFactoryBeanproxyFactoryBeannewProxyFactoryBean();proxyFactoryBean.setTarget(bean);proxyFactoryBean.setBeanFactory(this.beanFactory);proxyFactoryBean.setAopProxyFactory(this.aopProxyFactory);proxyFactoryBean.setInterceptorName(this.interceptorName);returnproxyFactoryBean;}/** * Advice、Advisor、FactoryBean 等基础设施对象 * 不能再次成为自动代理目标。 */privatebooleanisInfrastructureBean(Objectbean){returnbeaninstanceofBeanPostProcessor||beaninstanceofFactoryBean||beaninstanceofAdvice||beaninstanceofAdvisor;}protectedbooleanisMatch(StringbeanName,StringmappedName){returnPatternMatchUtils.simpleMatch(mappedName,beanName);}}当beanName是action或action2时action*匹配成功。此时target保存原始业务对象interceptorName保存advisor的名称真正创建代理时再从容器取得这个Advisor。如果没有匹配或者当前对象本身就是BeanPostProcessor、FactoryBean、Advice、Advisor则直接返回原对象。这个判断可以避免把自动代理处理器、代理工厂和通知等基础设施再次包装。五、容器最终保存的到底是什么原始业务对象被自动代理处理器命中后几个对象很容易混淆action 对应的单例 └─ ProxyFactoryBean ├─ target → Action1 原始对象 ├─ interceptorName → advisor └─ getObject() ↓ JDK 生成的 IAction 代理对象 ↓ 方法调用交给 JdkDynamicAopProxy ↓ Advisor → Advice PointcutcreateBean()返回的不是 JDK 代理对象而是自动组装出来的ProxyFactoryBean。getBean()会先把它注册到单例池再调用getObjectForBeanInstance()ObjectbeancreateBean(beanName,beanDefinition);if(beanDefinition.isSingleton()){registerSingleton(beanName,bean);this.earlySingletonObjects.remove(beanName);}returngetObjectForBeanInstance(bean,beanName);getObjectForBeanInstance()发现它实现了FactoryBean才会调用getObject()取得产品对象protectedObjectgetObjectForBeanInstance(ObjectbeanInstance,StringbeanName){if(!(beanInstanceinstanceofFactoryBean)){returnbeanInstance;}FactoryBean?factory(FactoryBean?)beanInstance;returngetObjectFromFactoryBean(factory,beanName);}接下来ProxyFactoryBean.getObject()根据target和advisor创建并缓存 JDK 代理对象OverridepublicObjectgetObject(){returngetSingletonInstance();}privatesynchronizedObjectgetSingletonInstance(){if(this.singletonInstancenull){this.singletonInstancegetProxy(createAopProxy());}returnthis.singletonInstance;}所以需要分清ProxyFactoryBean是容器内部保存的代理工厂JdkDynamicAopProxy是实现InvocationHandler的代理处理器Proxy.newProxyInstance()返回的对象才是业务代码最终拿到的IAction代理对象。六、验证自动代理Action1和Action2都只实现业务接口不需要包含任何 AOP 代码publicclassAction2implementsIAction{OverridepublicvoiddoAction(){System.out.println(real action2 doAction........);}OverridepublicvoiddoSomething(){System.out.println(real action2 doSomething........);}}测试中可以直接判断容器返回的对象是不是 JDK 动态代理ClassPathXmlApplicationContextcontextnewClassPathXmlApplicationContext(beans.xml);IActionaction(IAction)context.getBean(action);IActionaction2(IAction)context.getBean(action2);assertTrue(Proxy.isProxyClass(action.getClass()));assertTrue(Proxy.isProxyClass(action2.getClass()));action.doAction();action.doSomething();action2.doAction();action2.doSomething();由于action*同时命中两个 Beando*又命中两个业务方法所以四次调用都会先执行前置通知再执行真实方法。项目当前的AopAdviceTest同时验证了代理类型和执行顺序。七、当前教学实现的边界当前版本为了把自动代理的主线讲清楚保留了几个简化条件只支持一个 Bean 名称模式和一个interceptorName使用 JDK 动态代理因此目标类必须实现接口自动代理发生在postProcessBeforeInitialization()。最后一点需要特别说明。当前Action1、Action2没有配置init-method所以先包装成ProxyFactoryBean可以正常工作。但在当前createBean()中初始化前处理器一旦返回包装对象后面的init-method也会对这个包装对象执行。更完整的实现通常会在初始化完成后再创建代理并额外处理循环依赖中的早期代理引用。本节先以项目现有代码为准不继续展开这部分生命周期细节。小结这一节把“逐个配置ProxyFactoryBean”改成了“按 Bean 名称自动创建代理”BeanNameAutoProxyCreator决定哪些 Bean 要代理 Pointcut决定代理中的哪些方法要增强 Advice决定具体执行什么增强 ProxyFactoryBean组装并创建代理对象最关键的顺序是先注册自动代理处理器再创建普通 Bean。这样容器在创建action、action2时才能根据action*自动完成包装业务代码仍然只需要面向IAction调用。
MiniSpring框架学习笔记-AutoProxyCreator:如何自动添加动态代理?
MiniSpring框架学习笔记-AutoProxyCreator如何自动添加动态代理20. AutoProxyCreator如何自动添加动态代理一、先看最终配置二、为什么使用 BeanPostProcessor三、先把自动代理处理器注册进容器四、实现 BeanNameAutoProxyCreator五、容器最终保存的到底是什么六、验证自动代理七、当前教学实现的边界小结教程https://github.com/YaleGuo/minis极客时间手把手带你写一个 MiniSpring前言本节的主线就是将之前由写在XML里面的代理匹配模式直接写明action类这个需要代理)改成在IOC容器创建Bean的时候通过Bean后置处理器增强通过Bean的名字去匹配带着这个思路去看很容易明白。20. AutoProxyCreator如何自动添加动态代理上一节中我们已经能用Pointcut批量匹配需要增强的方法。不过哪个 Bean 需要代理仍然要逐个配置beanidrealactionclasscom.chenhai.test.Action1/beanidactionclasscom.chenhai.aop.ProxyFactoryBeanpropertytypejava.lang.Objectnametargetrefrealaction/propertytypeStringnameinterceptorNamevalueadvisor//bean这种方式代理一个对象没有问题。如果Action1、Action2等一批对象都要使用同一个Advisor就得反复配置ProxyFactoryBean。本节要把“为目标对象组装ProxyFactoryBean”这件事也交给容器。我们只配置一条 Bean 名称规则容器创建 Bean 时自动判断它是否需要代理。一、先看最终配置项目中的beans.xml不再为每个业务对象手写代理工厂而是增加一个BeanNameAutoProxyCreatorbeanidbeforeAdviceclasscom.chenhai.test.MyBeforeAdvice/beanidadvisorclasscom.chenhai.aop.NameMatchMethodPointcutAdvisorpropertytypecom.chenhai.aop.AdvicenameadvicerefbeforeAdvice/propertytypeStringnamemappedNamevaluedo*//beanbeanidautoProxyCreatorclasscom.chenhai.aop.framework.autoproxy.BeanNameAutoProxyCreatorpropertytypeStringnamepatternvalueaction*/propertytypeStringnameinterceptorNamevalueadvisor//beanbeanidactionclasscom.chenhai.test.Action1/beanidaction2classcom.chenhai.test.Action2/这里有两层匹配不要混在一起配置匹配对象作用patternaction*Bean 名称决定哪些 Bean 要创建代理mappedNamedo*方法名称决定代理中的哪些方法要执行通知因此action和action2都会被自动代理调用它们的doAction()、doSomething()时又都会命中do*先执行beforeAdvice。整个过程可以先记成下面这条主线ApplicationContext.refresh() ↓ 提前注册 BeanNameAutoProxyCreator ↓ 容器创建 action / action2 ↓ BeanNameAutoProxyCreator 用 action* 匹配 beanName ↓ 命中后把真实 Bean 包装成 ProxyFactoryBean ↓ getBean() 识别到 FactoryBean调用其 getObject() ↓ ProxyFactoryBean 根据 advisor 创建 JDK 动态代理对象 ↓ 业务代码最终拿到 IAction 代理对象二、为什么使用 BeanPostProcessor创建一个 Bean 时当前 MiniSpring 会依次完成这些步骤实例化 Bean ↓ 填充 XML 属性 ↓ 执行 Aware 回调 ↓ 初始化前处理 ↓ 执行 init-method ↓ 初始化后处理 ↓ 注册单例BeanPostProcessor正好提供了两个可以插入通用逻辑的扩展点publicinterfaceBeanPostProcessor{defaultObjectpostProcessBeforeInitialization(Objectbean,StringbeanName)throwsBeansException{returnbean;}defaultObjectpostProcessAfterInitialization(Objectbean,StringbeanName)throwsBeansException{returnbean;}}这里的post可以理解为“附加处理”不等于只能在初始化之后处理。真正的执行时机要看实现的是postProcessBeforeInitialization()还是postProcessAfterInitialization()。后置处理器还可以返回另一个对象。容器会沿用这个返回值继续执行后面的创建流程并最终把它放入单例池。自动代理正是利用这一点把普通业务 Bean 替换成包装它的ProxyFactoryBean。当前项目在createBean()中调用后置处理器的代码如下privateObjectcreateBean(StringbeanName,BeanDefinitionbeanDefinition)throwsBeansException{try{Class?beanClassClass.forName(beanDefinition.getClassName());ObjectbeaninstantiateBean(beanClass,beanDefinition.getConstructorArgumentValues());if(beanDefinition.isSingleton()){this.earlySingletonObjects.put(beanName,bean);}// 先完成 XML 属性注入。populateBean(beanDefinition,beanClass,bean);// 再回调 BeanFactoryAware 等 Aware 接口。invokeAwareMethods(bean);ObjectprocessedBeanapplyBeanPostProcessorsBeforeInitialization(bean,beanName);if(processedBean!null){beanprocessedBean;}invokeInitMethod(beanDefinition,bean);processedBeanapplyBeanPostProcessorsAfterInitialization(bean,beanName);if(processedBean!null){beanprocessedBean;}returnbean;}catch(BeansExceptione){throwe;}catch(Exceptione){thrownewBeansException(Create bean failed: beanName);}}applyBeanPostProcessorsBeforeInitialization()会按注册顺序调用所有处理器并把前一个处理器的返回值交给下一个处理器publicObjectapplyBeanPostProcessorsBeforeInitialization(ObjectexistingBean,StringbeanName)throwsBeansException{ObjectresultexistingBean;for(BeanPostProcessorbeanProcessor:getBeanPostProcessors()){ObjectcurrentbeanProcessor.postProcessBeforeInitialization(result,beanName);if(currentnull){returnresult;}resultcurrent;}returnresult;}当前项目先注册AutowiredAnnotationBeanPostProcessor再注册 XML 中的自动代理处理器。因此业务对象会先完成Autowired字段注入再由BeanNameAutoProxyCreator包装。三、先把自动代理处理器注册进容器这里有一个先后顺序问题如果普通 Bean 已经创建完了再注册自动代理处理器它就没有机会处理这些 Bean。所以ApplicationContext.refresh()必须先注册BeanPostProcessor再通过onRefresh()预实例化普通单例publicvoidrefresh()throwsBeansException,IllegalStateException{this.startupDateSystem.currentTimeMillis();this.closed.set(false);this.active.set(true);postProcessBeanFactory(getBeanFactory());invokeBeanFactoryPostProcessors(getBeanFactory());// 先注册 BeanPostProcessor。registerBeanPostProcessors(getBeanFactory());initApplicationEventPublisher();registerListeners();// 再预实例化非懒加载单例。onRefresh();finishRefresh();}ClassPathXmlApplicationContext除了注册内置的自动注入处理器还会找出 XML 中声明的所有BeanPostProcessorOverrideprotectedvoidregisterBeanPostProcessors(ConfigurableListableBeanFactorybeanFactory)throwsBeansException{// 内置处理器负责 Autowired 字段注入。beanFactory.addBeanPostProcessor(newAutowiredAnnotationBeanPostProcessor(beanFactory));// XML 中声明的处理器本章会找到 autoProxyCreator。MapString,BeanPostProcessorpostProcessorsbeanFactory.getBeansOfType(BeanPostProcessor.class);for(BeanPostProcessorpostProcessor:postProcessors.values()){beanFactory.addBeanPostProcessor(postProcessor);}}getBeansOfType(BeanPostProcessor.class)会先根据类型找出autoProxyCreator创建它再放入后置处理器列表。因为BeanNameAutoProxyCreator实现了BeanFactoryAware创建过程中容器还会把当前BeanFactory回调给它后面就能按名称查找advisor。四、实现 BeanNameAutoProxyCreatorBeanNameAutoProxyCreator的核心职责只有三步根据pattern匹配beanName排除 AOP 基础设施对象为命中的业务对象组装ProxyFactoryBean。项目中的实现如下packagecom.chenhai.aop.framework.autoproxy;importcom.chenhai.BeansException;importcom.chenhai.aop.Advice;importcom.chenhai.aop.Advisor;importcom.chenhai.aop.AopProxyFactory;importcom.chenhai.aop.DefaultAopProxyFactory;importcom.chenhai.aop.ProxyFactoryBean;importcom.chenhai.beans.factory.BeanFactory;importcom.chenhai.beans.factory.BeanFactoryAware;importcom.chenhai.beans.factory.FactoryBean;importcom.chenhai.beans.factory.config.BeanPostProcessor;importcom.chenhai.util.PatternMatchUtils;/** * 按 Bean 名称自动创建 AOP 代理。 */publicclassBeanNameAutoProxyCreatorimplementsBeanPostProcessor,BeanFactoryAware{// 要代理的 Bean 名称模式例如 action*。privateStringpattern;// 容器中的 Advisor 或 Advice Bean 名称。privateStringinterceptorName;privateBeanFactorybeanFactory;privateAopProxyFactoryaopProxyFactory;publicBeanNameAutoProxyCreator(){this.aopProxyFactorynewDefaultAopProxyFactory();}publicvoidsetPattern(Stringpattern){this.patternpattern;}publicStringgetPattern(){returnthis.pattern;}publicvoidsetInterceptorName(StringinterceptorName){this.interceptorNameinterceptorName;}publicStringgetInterceptorName(){returnthis.interceptorName;}publicvoidsetAopProxyFactory(AopProxyFactoryaopProxyFactory){this.aopProxyFactoryaopProxyFactory;}OverridepublicvoidsetBeanFactory(BeanFactorybeanFactory)throwsBeansException{this.beanFactorybeanFactory;}OverridepublicObjectpostProcessBeforeInitialization(Objectbean,StringbeanName)throwsBeansException{if(!isMatch(beanName,this.pattern)||isInfrastructureBean(bean)){returnbean;}ProxyFactoryBeanproxyFactoryBeannewProxyFactoryBean();proxyFactoryBean.setTarget(bean);proxyFactoryBean.setBeanFactory(this.beanFactory);proxyFactoryBean.setAopProxyFactory(this.aopProxyFactory);proxyFactoryBean.setInterceptorName(this.interceptorName);returnproxyFactoryBean;}/** * Advice、Advisor、FactoryBean 等基础设施对象 * 不能再次成为自动代理目标。 */privatebooleanisInfrastructureBean(Objectbean){returnbeaninstanceofBeanPostProcessor||beaninstanceofFactoryBean||beaninstanceofAdvice||beaninstanceofAdvisor;}protectedbooleanisMatch(StringbeanName,StringmappedName){returnPatternMatchUtils.simpleMatch(mappedName,beanName);}}当beanName是action或action2时action*匹配成功。此时target保存原始业务对象interceptorName保存advisor的名称真正创建代理时再从容器取得这个Advisor。如果没有匹配或者当前对象本身就是BeanPostProcessor、FactoryBean、Advice、Advisor则直接返回原对象。这个判断可以避免把自动代理处理器、代理工厂和通知等基础设施再次包装。五、容器最终保存的到底是什么原始业务对象被自动代理处理器命中后几个对象很容易混淆action 对应的单例 └─ ProxyFactoryBean ├─ target → Action1 原始对象 ├─ interceptorName → advisor └─ getObject() ↓ JDK 生成的 IAction 代理对象 ↓ 方法调用交给 JdkDynamicAopProxy ↓ Advisor → Advice PointcutcreateBean()返回的不是 JDK 代理对象而是自动组装出来的ProxyFactoryBean。getBean()会先把它注册到单例池再调用getObjectForBeanInstance()ObjectbeancreateBean(beanName,beanDefinition);if(beanDefinition.isSingleton()){registerSingleton(beanName,bean);this.earlySingletonObjects.remove(beanName);}returngetObjectForBeanInstance(bean,beanName);getObjectForBeanInstance()发现它实现了FactoryBean才会调用getObject()取得产品对象protectedObjectgetObjectForBeanInstance(ObjectbeanInstance,StringbeanName){if(!(beanInstanceinstanceofFactoryBean)){returnbeanInstance;}FactoryBean?factory(FactoryBean?)beanInstance;returngetObjectFromFactoryBean(factory,beanName);}接下来ProxyFactoryBean.getObject()根据target和advisor创建并缓存 JDK 代理对象OverridepublicObjectgetObject(){returngetSingletonInstance();}privatesynchronizedObjectgetSingletonInstance(){if(this.singletonInstancenull){this.singletonInstancegetProxy(createAopProxy());}returnthis.singletonInstance;}所以需要分清ProxyFactoryBean是容器内部保存的代理工厂JdkDynamicAopProxy是实现InvocationHandler的代理处理器Proxy.newProxyInstance()返回的对象才是业务代码最终拿到的IAction代理对象。六、验证自动代理Action1和Action2都只实现业务接口不需要包含任何 AOP 代码publicclassAction2implementsIAction{OverridepublicvoiddoAction(){System.out.println(real action2 doAction........);}OverridepublicvoiddoSomething(){System.out.println(real action2 doSomething........);}}测试中可以直接判断容器返回的对象是不是 JDK 动态代理ClassPathXmlApplicationContextcontextnewClassPathXmlApplicationContext(beans.xml);IActionaction(IAction)context.getBean(action);IActionaction2(IAction)context.getBean(action2);assertTrue(Proxy.isProxyClass(action.getClass()));assertTrue(Proxy.isProxyClass(action2.getClass()));action.doAction();action.doSomething();action2.doAction();action2.doSomething();由于action*同时命中两个 Beando*又命中两个业务方法所以四次调用都会先执行前置通知再执行真实方法。项目当前的AopAdviceTest同时验证了代理类型和执行顺序。七、当前教学实现的边界当前版本为了把自动代理的主线讲清楚保留了几个简化条件只支持一个 Bean 名称模式和一个interceptorName使用 JDK 动态代理因此目标类必须实现接口自动代理发生在postProcessBeforeInitialization()。最后一点需要特别说明。当前Action1、Action2没有配置init-method所以先包装成ProxyFactoryBean可以正常工作。但在当前createBean()中初始化前处理器一旦返回包装对象后面的init-method也会对这个包装对象执行。更完整的实现通常会在初始化完成后再创建代理并额外处理循环依赖中的早期代理引用。本节先以项目现有代码为准不继续展开这部分生命周期细节。小结这一节把“逐个配置ProxyFactoryBean”改成了“按 Bean 名称自动创建代理”BeanNameAutoProxyCreator决定哪些 Bean 要代理 Pointcut决定代理中的哪些方法要增强 Advice决定具体执行什么增强 ProxyFactoryBean组装并创建代理对象最关键的顺序是先注册自动代理处理器再创建普通 Bean。这样容器在创建action、action2时才能根据action*自动完成包装业务代码仍然只需要面向IAction调用。