龙空技术网

Spring AOP编程原理和实战应用

后端研发Marion 472

前言:

当前你们对“php aop 实现原理”大体比较珍视,姐妹们都想要分析一些“php aop 实现原理”的相关资讯。那么小编在网摘上搜集了一些对于“php aop 实现原理””的相关资讯,希望大家能喜欢,朋友们快快来了解一下吧!

# AOP编程## 目录

第一章 概述

第二章 AOP使用

第三章 AOP原理

第四章 AOP开源运用

第五章 AOP项目实战

第六章 总结

## 第一章 概述### 1. 编程范式概述

- 1. 面试过程编程

- 2. 面向对象编程

- 3. 函数式编程

- 4. 事件驱动编程

- 5. 面向切面编程

### 2. AOP是什么

- 1. 是一种编程范式,不是编程语言

- 2. 解决特定问题,不能解决所有问题

- 3. 是OOP的补充,不是替代

### 3. AOP的初衷

- 1. DRY : Don' t Repeat Yourself

- 2. SoC : Separation of Concerns

- 水平分离:展示层->服务层->持久层- 垂直分离:模块划分(订单、库存等)- 切面分离:分离功能性需求与非功能性需求### 4. 使用AOP的好处

- 1. 集中处理某一关注点/横切逻辑

- 2. 可以很方便地添加/删除关注点

- 3. 侵入性少,增强代码可读性及可维护性

### 5. AOP的应用场景

- 权限控制

- 缓存控制

- 事务控制

- 审计日志

- 性能监控

- 分布式追踪

- 异常处理

### 6. 支持AOP的编程语言

- Java

- NET

- c/c++

- Ruby

- Python

- PHP

### 7. 举个例子

- 1. 接口权限判断

- 2. 使用AOP注解实现

## 第二章 AOP使用

### ..

主要注解

)/***切面实例*/) @Aspect@Aspect@Componentpublic class SecurityAspect {@AutowiredAspectAuthService authService;注解@Pointcut@Pointcut ( "@annotation(Admin0nly)")public void admin0nly(){Advice@Before("admin0nly()")public void checkAccess(){authService . checkAccess();}
### 1. @AspectJ注解

- @Aspect

- @Pointcut

- @Advice

### 2. 切面表达式介绍- 1. Wildcards(通配符)

-

◆* 匹配任意数量的字符

◆+匹配指定类及其子类

◆.. 一般用于匹配任意数的子包或参数

- 2. Operators(运算符)

- <>&&与操作符

◆|| 或操作符

◆! 非操作符

-

3. designators### 3. 匹配包/类型

- //匹配ProductService类里头的所有方法

@Pointcut ("within ( com. imooc. service. ProductService)")public void matchType(){}

//匹配com. imooc包及子包下所有类的方法

@Pointcut ("within( com. imooc. .*)")public void matchPackage(){}
### 4. 匹配对象
- /*** public class DemoDao implements IDao[]*///匹配AOP对象的目标对象为指定类型的方法,即DemoDao的aop代理对象的方法@Pointcut ( "this ( com. imooc . DemoDao )")public void thisDemo()[]//匹配实现IDao接口的目标对象(而不是aop代理后的对象)的方法,这里即DemoDao的方法@Pointcut ("target ( com. imooc. IDao)")public void targetDemo()f]//匹配所有以Service结尾的bean里头的方法@Pointcut ( "bean (*Service)")public void beanDemo()f]
### 5. 匹配参数
- //匹配任何以find开头而且只有-个Long参 数的方法@Pointcut ( "execution(* *.. find*(Long))")public void argsDemo1() (]//匹配任何只有一个Long参数的方法@Pointcut ("args (Long)")public void argsDemo2()f]//匹配任何以find开头的而且第一个参 数为Long型的方法@Pointcut ("execution(* *.. find*(Long,..))")public void argsDemo3()f]//匹配第-一个参数为Long型的方法@Pointcut ("args (Long,.)")public void argsDemo4()f]
### 6. 匹配注解
- //匹配方法柝注有Admin0nly的注解的方法@Pointcut ("@annotation com. imooc . demo. security. Admin0nly)")public void annoDemo()f]//匹配标注有Beta的类底下的方法,要求的annotation的RetentionPolicy级别为CLASS@Pointcut ("@within( com. google . common. annotations. Beta)")public void annoWithinDemo()l]//匹配柝注有Repository的尖底下的方法,要求的annotation的RetentionPolicy級別カRUNTIME@Pointcut ("@target(org, springf ramework. stereotype. Repository)")public void annoTargetDemo()[]//匹配传入的参数类标注有Reposi tory注解的方法@Pointcut("@args(org, springf ramework. stereotype . Repository)")public void annoArgsDemo()l]
### 7. execution()

- execution(

modifier- pattern?

ret- type -pattern

declaring-type- pattern?

name-pattern(param- pattern)

throws- pattern?

)

### 8. 5种Advice注解

- 1. @Before ,前置通知

2. @ After (finally) ,后置通知,方法执行完之后

3. @AfterReturning ,返回通知,成功执行之后

4. @AfterThrowing ,异常通知,抛出异常之后

5. @ Around , 环绕通知

- @Before

@Pointcut ( "@within( com. imooc . demo . security .NeedSecured)")public void annoTargetVsWithinDemo()@Before( "annoTargetVsWithinDemo() && within( com. imooc..*)")public void demo( )fSystem. out. println( "##########aop by within");throw new Runt imeException("do not proceed") ;
- @After
@After("annoTargetVsWithinDemo() && within( com. imooc..*)")public void afterDemo()fSystem. out. println( "###########after aop by within");]@AfterReturning( "annoTargetVsWithinDemo() && within( com. imooc..*)")public void afterReturning()System. out. print ln( "#########after aop by within");]@AfterThrowing("annoTargetVsWithinDemo() && within( com. imooc..*)")public void AfterThrowing()fSystem. out . print ln( "############after aop by within"); .]
- @Around
@Around ( "annoTargetVsWithinDemo() && within( com. imooc..*)")public Object AfterThrowing(ProceedingJoinPoint pjp) throws Throwable fSystem. out. print ln("#########before ");try (Object result = pjp. proceed(pjp. getArgs());System, out , println( "############return");return result ;] catch (Throwable throwable) [System. out . println("########ex");throw throwable;]finally fSystem. out. println( "###########after");]]
- Advice中的参数及结果绑定
-@Before(value = "annoTargetVsWithinDemo() && within( com. imooc..*) && args(userId)")public void beforeWithArgs (JoinPoint j oinPoint, Long userId)fSystem. out. println("before , args :"+userId);@AfterReturning(value = "annoTargetVsWithinDemo() && within(com. imooc. .*)" , returning = "returnValue" )public void getReulst (Object returnValue)fif( returnValue != null)[System. out. println("after return , result:"+returnValue) ;]
## 第三章 AOP原理### 1. 概述- 1. 原理概述:织入的时机- 1、编译期(AspectU)- 2、类载时(AspectJ 5+)- 3、运行时(Spring AOP)- 2. 静态代理和动态代理

- 静态代理的缺点

- ◆动态代理的两类实现: 基于接口代理与基于继承代理

- ◆两类实现的代表: JDK代理与Cglib代理

### 2. 设计

- 代理模式

- 责任链模式

### 3. 实现

- JDK实现

- JDK实现要点

◆类java.lang.reflect.Proxy◆接口:InvocationHandler◆只能基于接口进行动态代理- Cglib实现

- Cglib实现

public static 0bject getProxy(Class clz, MethodInterceptor interceptor){Enhancer enhancer = new Enhancer();//生成指定类对象的子类,也就是重写类中的业务函数enhancer . setSuperclass(clz);//这里是回调函数,加入intercept()函数enhancer . setCa llback( interceptor);//创建这个子类对象return enhancer . create();}
### 4. JDK与Cglib代理对比

- ◆Cglib基于继承来实现代理,无法对private、static方法进行代理

- ◆JDK只能针对有接口的类的接口方法进行动态代理

- ◆Cglib基于继承来实现代理,无法对static、final类进行代理

### 5. 多个AOP如何叠加?## 第四章 AOP开源运用

### 1. 事务.

- @Transactional

### 2. 安全.

- @PreAuthorize

### 3. 缓存

- @Cacheable

## 第五章 AOP项目实战### 1. 实战案例背景/目标

- ◆商家产品管理系统

- ◆记录产品修改的操作记录

- ◆什么人在什么时间修改了哪些产品的哪些字段修改为什么值

### 2. 实现思路

- ◆利用aspect去拦截增删改方法

- ◆利用反射获取对象的新旧值

- ◆利用@Around的advice去记录操作记录

### 3. 领域模型

### 4. Datalog注解

- @Target(( ElementType . FIELD, ElementType .METHOD, ElementType. TYPE ])@Retent. ion(Retent ionPolicy . RUNTIME)public @interface Datalog [String name();]
### 5. Aspect设计
- @Aspect@Componentpublic class DatalogAspect [private static final Logger logger = LoggerFactory . getLogger(Data logAspect.class);@AutowiredActionDao actionDao;@Pointcut ("execution(public * com. imooc . aop. dao,*. save*(..))")public void save()f]@Pointcut ( "execution(public * com. imooc. aop. dao.*. delete*(..))")public void delete( )[]
### 6. Execution### 7. 小结## 第六章 总结### 1. 使用SpringAop的注意事项/坑

- ◆不宜把重要的业务逻辑放到aop中处理

- ◆无法拦截static、 final方法、 private方法

- ◆无法拦截内部方法调用

### 2. 小结

- ◆合理利用面向切面编程提升代码质量

- ◆掌握SpringAop概念及实现原理

- ◆了解AOP的优缺点及SpringAop的使用局限

## 参考资料

- [探秘Spring AOP]()

标签: #php aop 实现原理 #php aop使用