什么是AOP:
个人理解是 把系统性的编程工做封装起来 =》我给这个取个名字叫 “Aspect”,而后经过AOP技术把它切进咱们的业务逻辑代码 =》 “业务“html
这样的好处:
“Aspect” 和 “业务” 相互独立,既可让“业务” 用到了 “Aspect” 又让2者互相独立不耦合,多个“业务”也能复用 同一份“Aspect”git
举一个最实用的例子 Transaction 事物
咱们常常会在业务代码上使用Transaction事物,好比使用TransactionScope:github
下面的测试代码用到了我在维护的一个开源ORM框架编程
https://github.com/yuzd/AntData.ORMmvc
示例业务代码:框架
上面的代码 就是 插入一个学校到db 而后拿到主键 赋值给 person 再insert到db。 在同一个事物里面 要么school 和person 同时插入db 要么都失败。异步
实际业务代码确定比这个要复杂的多了,好比多个方法在一个事物里面等我这里就举最简单的例子。post
那么若是每段业务逻辑都这么写的话 会形成重复性代码不少,下面咱们就尝试用AOP面向对切的思想去优化测试
思考怎样的方式才是我想要的
示例代码:优化
如上图: 我在须要用到事物的方法上面打了一个 EnableTransactionScope 标签 这样遇到业务方法须要用事物包裹的话 均可以打上这个标签
假如要实现这样的话 得实现如下几点:
- 我须要代理类,由于只有代理类才能给业务代码作些手脚(织入咱们想要的逻辑包裹)
- 我须要一个DI容器,由于将实例的生成交给DI容器了会很方面的生成代理类
- 我但愿只是打打标签就能实现以上这些,这样可视化最好,也方便
朝着目标去实现它 Just Do It
1. 使用Autofac 这款DI容器 配合 Autofac.Extras.DynamicProxy 库
这2个库都是autofac旗下现成的开源产品,有了这2个库 就知足我上面提到的需求1和需求2
第3点看来得亲自动手了
𪠽𪠽𪠽𪠽~~
这个组件是我维护的一个开源的autofac扩展库,用来实现打打标签 就能实现一些复杂的配置!
2. 如何使用 Autofac.Annotation 帮助实现AOP面向切面编程
先简单来个示例代码:
更多示例请查阅:https://github.com/yuzd/Autofac.Annotation
3. 使用织入来实现TransactionScope切面
新建一个class以下继承PointcutAttribute 并实现方法: 注意:因为是异步环境 必须使用 new TransactionScope(TransactionScopeAsyncFlowOption.Enabled)
只须要在在须要事物包裹的方法上打上这个标签 [EnableTransactionScope] 以下图:
总结
使用Autofac.Annotation组件能够很方便的让咱们在业务代码中使用AOP切面,能够自定义实现切入的位置(前置,后置,仍是Arround等)
参考上面代码,
- 打了Componet标签就把类注入到autofac容器了
- 打了Aspect标签就表明该类须要autofac帮我生成代理类
- 方法上面打了指定的标签(前置,后置,环绕,PointCut四种)表明要织入的逻辑
织入类型 | 实现规则 | 说明 |
---|---|---|
前置织入 | 继承AspectBeforeAttribute | 在进入业务代码以前先执行【前置织入逻辑-》业务代码】 |
后置织入 | 继承AspectAfterAttribute | 在业务代码执行以后执行(即便有异常)【业务代码-》后置织入逻辑】 |
环绕织入 | 继承AspectAroundAttribute | 在业务代码以前和以前都执行【前置织入逻辑-》业务代码-》后置织入逻辑】 |
PointCut织入 | 继承PointcutAttribute | 掌控业务代码的执行权,这种最灵活【本文的TransactionScope功能就得用到它】 |