当前位置: 首页 > news >正文

图片生成二维码南京广告宣传公司seo

图片生成二维码,南京广告宣传公司seo,建设工程有限公司是干什么的,制作网站流程图Spring源码阅读目录 第一部分——IOC篇 第一章 Spring之最熟悉的陌生人——IOC 第二章 Spring之假如让你来写IOC容器——加载资源篇 第三章 Spring之假如让你来写IOC容器——解析配置文件篇 第四章 Spring之假如让你来写IOC容器——XML配置文件篇 第五章 Spring之假如让你来写…Spring源码阅读目录 第一部分——IOC篇 第一章 Spring之最熟悉的陌生人——IOC 第二章 Spring之假如让你来写IOC容器——加载资源篇 第三章 Spring之假如让你来写IOC容器——解析配置文件篇 第四章 Spring之假如让你来写IOC容器——XML配置文件篇 第五章 Spring之假如让你来写IOC容器——BeanFactory和FactoryBean 第六章 Spring之假如让你来写IOC容器——Scope和属性填充 第七章 Spring之假如让你来写IOC容器——属性填充特别篇SpEL表达式 第八章 Spring之假如让你来写IOC容器——拓展篇 第九章 Spring之源码阅读——环境搭建篇 第十章 Spring之源码阅读——IOC篇 第二部分——AOP篇 第十一章 Spring之不太熟的熟人——AOP 第十二章 Spring之不得不了解的内容——概念篇 第十三章 Spring之假如让你来写AOP——AOP联盟篇 第十四章 Spring之假如让你来写AOP——雏形篇 第十五章 Spring之假如让你来写AOP——Joinpoint连接点篇 第十六章 Spring之假如让你来写AOP——Pointcut切点篇 第十七章 Spring之假如让你来写AOP——Advice通知上篇 第十八章 Spring之假如让你来写AOP——Advice通知下篇 第十九章 Spring之假如让你来写AOP——番外篇Spring早期设计 第二十章 Spring之假如让你来写AOP——Aspect切面篇 第二十一章 Spring之假如让你来写AOP——Weaver织入器篇 第二十二章 Spring之假如让你来写AOP——Target Object目标对象篇 文章目录 Spring源码阅读目录第一部分——IOC篇第二部分——AOP篇 前言尝试动手写IOC容器第十六版 AOP雏形哪些地方可以增强如何找到这些地方找到后要怎么增强多个增强如何管理如何对其进行增强 总结 前言 对于Spring一直都是既熟悉又陌生说对它熟悉吧平时用用没啥问题但面试的时候被问的一脸懵逼就很尴尬都不好意思在简历上写着熟悉Spring了 所以决定花点时间研究研究Spring的源码。主要参考的书籍是《Spring源码深度解析第2版》、《Spring揭秘》、《Spring技术内幕深入解析Spring架构与设计原理第2版》 书接上回在上篇 第十三章 Spring之假如让你来写AOP——AOP联盟篇 中A君 先把 AOP联盟 规范的接口定义好了。接下来看看 A君 会有什么骚操作吧 尝试动手写IOC容器 出场人物A君苦逼的开发、老大项目经理 背景老大要求A君在一周内开发个简单的 IOC容器 前情提要 昨天A君 定义了 AOP联盟 规范的接口 。。。 第十六版 AOP雏形 俗话说人无远虑必有近忧。 这句话用来描述 A君 此时的状态再合适不过了。 A君 现在 看着这一堆接口一脸懵逼这要怎么继续。纠结了良久A君 按照之前的思路走 哪些地方可以增强如何找到这些地方找到后要怎么增强多个增强如何管理如何对其进行增强 哪些地方可以增强 目标既然已经确定A君 开始着手准备实现 Joinpoint连接点 相关内容。按照之前 A君 了解到的知识Joinpoint连接点 就是定义 AOP 对目标对象可以增强的地方。 A君 的计划是实现方法增强即可也就是 Joinpoint连接点 就是方法即需要实现 MethodInvocation 接口这点不再有任何疑虑。确定完需要实现的接口接着还要确定一下类需要实现的功能这不经让 A君 一阵皱眉。Joinpoint连接点 无疑是方法执行的地方如果仅仅执行目标方法显然不够。需要加上 Advice通知那么有多个 Advice通知 怎么解决 思来想去A君 决定让 Joinpoint连接点 接收所有 Advice通知 然后通过链式调用去执行每一个 Advice通知。思路清晰后A君 撸袖子开干定义 ReflectiveMethodInvocation 类代码如下 import com.hqd.ch03.v16.aopalliance.intercept.MethodInterceptor; import com.hqd.ch03.v16.aopalliance.intercept.MethodInvocation;import javax.annotation.Nonnull; import javax.annotation.Nullable; import java.lang.reflect.AccessibleObject; import java.lang.reflect.Method; import java.util.List;/*** 连接点类用以执行通知及目标方法*/ public class ReflectiveMethodInvocation implements MethodInvocation {private Object proxy;private Method method;private Object[] args;private ListMethodInterceptor mis;private int currentInterceptorIndex -1;public ReflectiveMethodInvocation(Object proxy, Method method,Object[] args, ListMethodInterceptor mis) {this.proxy proxy;this.method method;this.args args;this.mis mis;}NonnullOverridepublic Method getMethod() {return method;}NonnullOverridepublic Object[] getArguments() {return args;}NullableOverridepublic Object proceed() throws Throwable {/*** 链式调用通知*/if (mis.size() - 1 currentInterceptorIndex) {return getMethod().invoke(proxy, args);}MethodInterceptor methodInterceptor this.mis.get(currentInterceptorIndex);return methodInterceptor.invoke(this);}NullableOverridepublic Object getThis() {return proxy;}NonnullOverridepublic AccessibleObject getStaticPart() {return null;} }如何找到这些地方 “现在 Joinpoint连接点 有了还需要一个可以找到对应 Joinpoint连接点 的 Pointcut切点 ” A君 思忖。对于 Pointcut切点A君 之前用 Spring 也有接触过类似于execution( .test(…)) 这块内容 Spring 也并非自己实现而是使用 AspectJ。想到这里A君 决定也站在巨人的肩膀上使用 AspectJ 实现对应的 Joinpoint连接点 匹配。那么 Pointcut切点 的就简单了接收对应的表达式调用 AspectJ 进行匹配即可。捋清楚之后A君 开始撸代码定义 AspectJExpressionPointcut 类其代码如下 import org.aspectj.weaver.tools.PointcutExpression; import org.aspectj.weaver.tools.PointcutParameter; import org.aspectj.weaver.tools.PointcutParser; import org.aspectj.weaver.tools.PointcutPrimitive;import javax.annotation.Nullable; import java.util.HashSet; import java.util.Set;/*** 切点表达式匹配*/ public class AspectJExpressionPointcut {private static final SetPointcutPrimitive SUPPORTED_PRIMITIVES new HashSet();static {/*** 定义 AspectJ 匹配器*/SUPPORTED_PRIMITIVES.add(PointcutPrimitive.EXECUTION);SUPPORTED_PRIMITIVES.add(PointcutPrimitive.ARGS);SUPPORTED_PRIMITIVES.add(PointcutPrimitive.REFERENCE);SUPPORTED_PRIMITIVES.add(PointcutPrimitive.THIS);SUPPORTED_PRIMITIVES.add(PointcutPrimitive.TARGET);SUPPORTED_PRIMITIVES.add(PointcutPrimitive.WITHIN);SUPPORTED_PRIMITIVES.add(PointcutPrimitive.AT_ANNOTATION);SUPPORTED_PRIMITIVES.add(PointcutPrimitive.AT_WITHIN);SUPPORTED_PRIMITIVES.add(PointcutPrimitive.AT_ARGS);SUPPORTED_PRIMITIVES.add(PointcutPrimitive.AT_TARGET);}/*** 切点表达式*/private String expression;private String[] pointcutParameterNames new String[0];private Class?[] pointcutParameterTypes new Class?[0];public AspectJExpressionPointcut(String expression) {this.expression expression;}public PointcutExpression buildPointcutExpression() {PointcutParser parser initializePointcutParser(Thread.currentThread().getContextClassLoader());PointcutParameter[] pointcutParameters new PointcutParameter[this.pointcutParameterNames.length];/*** 匹配对应的参数*/for (int i 0; i pointcutParameters.length; i) {pointcutParameters[i] parser.createPointcutParameter(this.pointcutParameterNames[i], this.pointcutParameterTypes[i]);}return parser.parsePointcutExpression(getExpression(),null, pointcutParameters);}/*** 初始化切点匹配器** param classLoader* return*/private PointcutParser initializePointcutParser(Nullable ClassLoader classLoader) {PointcutParser parser PointcutParser.getPointcutParserSupportingSpecifiedPrimitivesAndUsingSpecifiedClassLoaderForResolution(SUPPORTED_PRIMITIVES, classLoader);return parser;}public String getExpression() {return this.expression;} }找到后要怎么增强 注此处理解有误Spring 应该由于历史原因才有不同的实现。这里大家别信看个乐呵。后边有专门的篇章解释 在找到 Joinpoint连接点 之后接下来要解决的就是怎么增强目标方法 。 前置、后置、环绕、异常增强 这些都是耳熟能详的词但是实现上却有些不一样。首先是 Before Advice前置通知 和 After Returning Advice这两个可以直接调用增强方法不需要特殊的操作而 After Throwing Advice、After (Finally) Advice、 Around Advice环绕通知 却不一样需要对方法进行更细致的操作。故而 A君 把他们分成两种Before Advice前置通知 和 After Returning Advice 直接拓展 Advice 接口A君 照猫画虎定义一个 BeforeAdvice 接口作为 Before Advice前置通知 的标记接口代码如下 import com.hqd.ch03.v16.aopalliance.aop.Advice;/*** 前置通知标记接口*/ public interface BeforeAdvice extends Advice {} 只有标记接口显然是干不了任何事的所以还需要定义一个真正干活的接口—— MethodBeforeAdvice代码如下 import javax.annotation.Nullable; import java.lang.reflect.Method;public interface MethodBeforeAdvice extends BeforeAdvice {void before(Method method, Object[] args, Nullable Object target) throws Throwable; }接口有了按照惯例接下来就是具体实现了不急不急。A君 经过一番观察发现这些 Advice通知 都是一个套路虽然有分前后置但是都是先确定 Pointcut切点 是否匹配在执行相应的方法。咦有公共代码那么他就要来了没错就是他——抽象类。A君 定义 AbstractAspectJAdvice 类代码如下 import com.hqd.ch03.v16.aopalliance.aop.Advice;import javax.annotation.Nonnull; import java.lang.reflect.Method;public abstract class AbstractAspectJAdvice implements Advice {private Method aspectJAdviceMethod;private Object aspect;private AspectJExpressionPointcut pointcut;public AbstractAspectJAdvice(AspectJExpressionPointcut pointcut, Method aspectJAdviceMethod, Object aspect) {this.aspectJAdviceMethod aspectJAdviceMethod;this.aspect aspect;this.pointcut pointcut;}protected void invokeAdviceMethod(Nonnull Method method) {if (match(method)) {try {aspectJAdviceMethod.invoke(aspect);} catch (Exception e) {throw new RuntimeException(e);}}}/*** 判断是否匹配** param method* return*/protected boolean match(Method method) {return pointcut.buildPointcutExpression().matchesMethodExecution(method).alwaysMatches();} }提取完公共代码接下来就要回到正题——实现 MethodBeforeAdvice。不过这玩意确实也没有什么东西直接调用父类方法即可。A君 定义 AspectJMethodBeforeAdvice 类代码如下 import com.hqd.ch03.v16.aop.framework.MethodBeforeAdvice;import javax.annotation.Nullable; import java.lang.reflect.Method;public class AspectJMethodBeforeAdvice extends AbstractAspectJAdvice implements MethodBeforeAdvice {public AspectJMethodBeforeAdvice(AspectJExpressionPointcut pointcut, Method aspectJAdviceMethod, Object aspect) {super(pointcut, aspectJAdviceMethod, aspect);}Overridepublic void before(Method method, Object[] args, Nullable Object target) throws Throwable {invokeAdviceMethod(method);} } “咦不太对劲。” A君 警觉。在定义 ReflectiveMethodInvocation 类时A君 要求通知必须要时 MethodInterceptor 类型因为只有类型为 MethodInterceptor 整个链式调用才能玩的动而 AspectJMethodBeforeAdvice 显然不是。没办法套个马甲把于是乎A君 有定义了一个 MethodBeforeAdviceInterceptor 类适配器随便了。代码如下 import com.hqd.ch03.v16.aop.framework.BeforeAdvice; import com.hqd.ch03.v16.aop.framework.MethodBeforeAdvice; import com.hqd.ch03.v16.aopalliance.intercept.MethodInterceptor; import com.hqd.ch03.v16.aopalliance.intercept.MethodInvocation; import lombok.AllArgsConstructor;import javax.annotation.Nonnull; import javax.annotation.Nullable;AllArgsConstructor public class MethodBeforeAdviceInterceptor implements MethodInterceptor, BeforeAdvice {private final MethodBeforeAdvice advice;NullableOverridepublic Object invoke(Nonnull MethodInvocation mi) throws Throwable {advice.before(mi.getMethod(), mi.getArguments(), mi.getThis());return mi.proceed();} }OK搞定。这么一来 Joinpoint连接点 的链式调用就玩的转了。接下来 AfterReturningAdvice 也是同理限于篇幅A君 就不再列举了 After Throwing Advice、After (Finally) Advice 这类通知需要对方法进行更精细的控制所以需要实现 MethodInterceptor而不是直接实现 Advice。A君 先对 After (Finally) Advice 进行实现见名知意这个应该是在 finally 代码块里面实现的 A君 定义 AspectJAfterAdvice 类代码如下 import com.hqd.ch03.v16.aop.framework.AfterAdvice; import com.hqd.ch03.v16.aopalliance.intercept.MethodInterceptor; import com.hqd.ch03.v16.aopalliance.intercept.MethodInvocation;import javax.annotation.Nonnull; import javax.annotation.Nullable; import java.lang.reflect.Method;public class AspectJAfterAdvice extends AbstractAspectJAdvice implements MethodInterceptor, AfterAdvice {public AspectJAfterAdvice(AspectJExpressionPointcut pointcut, Method aspectJAdviceMethod, Object aspect) {super(pointcut, aspectJAdviceMethod, aspect);}NullableOverridepublic Object invoke(Nonnull MethodInvocation mi) throws Throwable {try {return mi.proceed();} finally {invokeAdviceMethod(mi.getMethod());}} }After Throwing Advice 自然就是在 catch 代码块执行了只有异常时才执行代码类似A君 也不列举了 多个增强如何管理 管理 Advice通知 这部分内容就比较好实现了无非定义一个管理类可以对 Advice通知 进行增删查改排序就行了这玩意难不倒 A君A君 直接定义 AdvisedSupport 类让它对 Advice通知 进行管理代码如下 import com.hqd.ch03.v16.aopalliance.intercept.MethodInterceptor; import org.apache.commons.collections4.CollectionUtils;import java.util.ArrayList; import java.util.Collection; import java.util.List;/*** advice管理类*/ public class AdvisedSupport {private ListMethodInterceptor advisors new ArrayList();public void addAdvisors(CollectionMethodInterceptor advisors) {if (CollectionUtils.isNotEmpty(advisors)) {this.advisors.addAll(advisors);}}public void addAdvisor(MethodInterceptor advisor) {if (advisor ! null) {this.advisors.add(advisor);}}public ListMethodInterceptor getAdvisors() {return advisors;} }如何对其进行增强 现在万事俱备只剩最后一部分内容了如何把通知和目标方法进行关联先创建代理对象这一步毋庸置疑。但是要怎么对代理对象进行增强嘿嘿这个简单老套路套个马甲就行了。给代理类添加个默认的拦截器让它去执行整个通知链路。思量完毕A君 先定义 ProxyFactory 类作为代理工厂用以创建代理对象并创建默认的方法拦截器。代码如下 import lombok.AllArgsConstructor; import net.sf.cglib.proxy.Callback; import net.sf.cglib.proxy.Enhancer; import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy;import java.io.Serializable; import java.lang.reflect.Method;AllArgsConstructor public class ProxyFactory extends AdvisedSupport {private Class? superClass;private Object target;private Method method;public Object getProxy() {Enhancer enhancer new Enhancer();enhancer.setSuperclass(superClass);/*** 添加默认拦截器执行增强*/enhancer.setCallbacks(new Callback[]{new DynamicAdvisedInterceptor(this, target, method)});return enhancer.create();}AllArgsConstructorprivate static class DynamicAdvisedInterceptor implements MethodInterceptor, Serializable {private AdvisedSupport advisedSupport;private Object target;private Method method;Overridepublic Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {ReflectiveMethodInvocation rmi new ReflectiveMethodInvocation(target, this.method, null, advisedSupport.getAdvisors());return rmi.proceed();}} } 至此A君 所有的步骤都已经实现了现在需要测试一下来验证自己的努力的成果。测试代码如下 Testpublic void v16() throws Throwable {System.out.println(############# 第十六版aop雏形 #############);AspectJExpressionPointcut pointcut new AspectJExpressionPointcut(execution(* *.test(..)));Object ap new AopBean();Method method AopBean.class.getDeclaredMethod(test);AopTest aop new AopTest();Method beforeTest aop.getClass().getDeclaredMethod(beforeTest);Method afterTest aop.getClass().getDeclaredMethod(afterTest);Method afterReturnTest aop.getClass().getDeclaredMethod(afterReturnTest);ListMethodInterceptor list new ArrayList();//前置通知AspectJMethodBeforeAdvice aspectJMethodBeforeAdvice new AspectJMethodBeforeAdvice(pointcut, beforeTest, aop);MethodBeforeAdviceInterceptor methodBeforeAdviceInterceptor new MethodBeforeAdviceInterceptor(aspectJMethodBeforeAdvice);list.add(methodBeforeAdviceInterceptor);//后置通知list.add(new AspectJAfterAdvice(pointcut, afterTest, aop));//返回通知AspectJAfterReturningAdvice aspectJAfterReturningAdvice new AspectJAfterReturningAdvice(pointcut, afterReturnTest, aop);list.add(new AfterReturningAdviceInterceptor(aspectJAfterReturningAdvice));ProxyFactory proxyFactory new ProxyFactory(AopBean.class, ap, method);proxyFactory.addAdvisors(list);AopBean proxy (AopBean) proxyFactory.getProxy();proxy.test();从结果来看是符合预期的A君 打算先给 老大 看下毕竟 老大 有自己的想法不是个好糊弄的主。今天先到这里A君 上传代码准备下班咯 总结 正所谓树欲静而风不止欲知后事如何请看下回分解(✪ω✪)
http://www.w-s-a.com/news/159656/

相关文章:

  • 广州番禺网站公司v2017网站开发
  • 微信公众号怎么做微网站wordpress和dz
  • 西部数码网站管理助手 301福州搜索优化实力
  • 响应式网站介绍页面模板功能找不到
  • 公司网站如何seo自己做资讯网站
  • 天津网站建设软件开发招聘企业信用信息查询公示系统上海
  • 网站备案中做正品的网站
  • 网站建设0基础学起青海企业网站开发定制
  • 网站定制项目上海快速建站
  • 大型视频网站建设方案东莞企业网站建设开发
  • 西安php网站制作可以用AI做网站上的图吗
  • 网站开发工程师和前端企业网络推广公司
  • 泉州开发网站的公司有哪些电脑网页翻译
  • 河北省建设机械会网站首页刚做的网站怎么收录
  • 什么网站专门做自由行的framework7做网站
  • 网页设计与网站建设书籍包头住房与城乡建设局网站
  • 重庆网站建设平台免费猎头公司收费收费标准和方式
  • 形象设计公司网站建设方案书打开一个不良网站提示创建成功
  • 网站手机页面如何做网站关键字 优帮云
  • 免费的黄冈网站有哪些下载软件系统软件主要包括网页制作软件
  • 企业微站系统重庆高端网站建设价格
  • 有没有做衣服的网站吗网站自适应开发
  • 青海省制作网站专业专业定制网吧桌椅
  • 网站开发的项目17岁高清免费观看完整版
  • 手机网站建设多少钱一个门网站源码
  • 重庆 网站开发天津住房和城乡建设厅官方网站
  • 泰安高级网站建设推广厦门高端网站建设定制
  • jsp网站开发引用文献手机seo排名
  • 创建一家网站如何创设计网页的快捷网站
  • 1688代加工官方网站h5开发教程