动吧加强

AOP

是一种设计思想(mvc分层架构设计思想,链接池池化思想,ioc控制反转思想,oop面向对象思想),强调的是一个服务增益的思想,面向切面编程。
当咱们写一个类,系统底层帮咱们生成一个子类,这种方法就叫作代理。如今默认是cglib代理spring

aop相关术语

切面(aspect):咱们会写一个类,基于这个类构建的对象就是切面对象,这个类写的时候会用@Aspect描述,用这个注解描述的类称之为切面类
通知(Advice):在切面某个特定的点上要执行的动做称之为通知
链接点(joinpoint):通常指向被拦截到的目标方法,就是要为哪一个方法作扩展
好比,坐地铁,要作安检,安检的动做就是通知,安检的地方就能够看作是切面(封装了链接点和通知方法的对象),正在安检的点就能够看作是链接点,一堆安检点就叫作切入点数据库

配置

image

业务描述

基于项目中的核心业务,添加简单的日志操做,借助SLF4J日志API输出目标方法的执行时长。
记录日志,为了防止重复性的编写,在方法执行前记录一下时间,在方法结束后再记录一下时间,时间相减就是目标方法执行时间编程

建立

首先在com.cy.pj.common.aspect包下建立SysLogAspect类
image
Aspect 注解描述的类为spring aop中的一个切面类型,此类型能够定义:1)切入点(PointCut)方法 (能够是多个):要进行功能拓展的一些点
2)通知(Advice)方法 (能够是多个):封装了扩展功能的一个或多个方法(在切入点方法以前或以后要执行的方法)。
@Pointcut 注解描述的方法为切入点方法,注解中定义的内容为切入点表达式(能够有多种形式)缓存

1)bean(bean名称) 切入点表达式,这个表达式中的名字为spring容器中管理的一个bean名字。
2)bean表达式是一种粗粒度的切入点表达式,这种表达式定义的切入点表示bean中的全部方法都是未来要切入扩展功能的一些方法(目标方法)。在当前应用中,sysUserServiceImpl这个名字对应的bean中全部方法的集合为切入点。

ProceedingJoinPoint(链接点),链接点对象,此对象封装了要执行的目标方法信息。调用目标方法,这个链接点是上面切入点方法其中的一个方法(正在执行的方法),只有环绕通知@Around描述的方法才可使用ProceedingJoinPoint参数,只要是环绕,方法参数必须是Object。
@Around 描述的方法为一个通知方法,这个通知咱们称之为环绕通知,能够在目标方法执行以前或以后作服务增益。在环绕通知方法咱们能够本身控制目标方法的调用。
在@Around注解里使用上面的切入点就在参数中添加方法。
启动执行,看控制台
从客户端发送一个请求,发送到服务器端,是springmvc中的c controller,image
这个类是SysYserServuceImpl的子类,这个是底层写的(CGLIB
代理),最后是代理对象调用切面对象的around方法。
在yml文件添加一行配置imagetomcat

切面通知执行顺序

image
在aspect包下添加SysTimeAspect方法
image服务器

练习

定义一个异常监控切面,对目标页面方法进行异常监控,并以日志信息的
形式输出异常,之后能够写报警的
在aspect包下建立SysExceptionAspect类image架构

练习

定义一Cache相关切面,使用注解表达式定义切入点,并使用此注解对须要使用cache的业务方法进行描述部门里的查询方法
第一步:在annotation包下添加RequiredCache方法注解image
第二步:定义SysCacheAspect切面对象。在aspect包下添加SysCacheAspect方法image
第三步:使用@RequiredCache注解对部门查询进行描述。imagemvc

从新添加一个需求

当把数据库里的数据更新或删除的时候,cache里要清空。
因此要在部门方法上添加一个@doClearCache注解框架

概览

@Aspect:切面 @Pointcut:切入点 @Advice:通知方法 @JoinPoint:链接点 @Order:优先级异步

小节

以AOP方式记录项目中的用户行为信息,并将其存储到数据库
能够逆向思惟,先想怎么存储到数据库

dao层

首先在SysLogDao接口添加int insertObject(SysLog entity);方法,由于当初查询到的就是SysLog,因此如今写也能够这么写,而后写映射文件

service层

在SysLogService接口添加void saveObject(SysLog entity);方法,

实现类

在SysLogServiceImpl类添加saveObject方法image
当访问用户管理要抓取日志,因此要定义切面,在SysLogAspect类中添加将用户行为信息写入到数据库的方法saveUserLog(jp,(t2-t1)); 和saveUserLog方法image
ip须要添加一个工具类,把IPUtils类添加在utils包下。
操做名经过写一个注解RequiredLog,注解里添加一个String value() default "operation";,而后在SysUSerServiceImpl类中findPageObjects方法上添加@RequiredLog(value="分页查寻")注解,那怎么获取操做名呢,得获取这个注解,那怎么获取注解呢,须要先获取这个方法,要想取到这个方法要先取到这个类,只有经过类的字节码对象才能找到方法对象,经过方法对象找到注解对象,经过注解对象就能找到这个值了。因此才有1.3,1.3.1,1.3.2,1.3.3
测试!


Aop事务

事务(Transaction)是一个业务,是一个不可分割的逻辑工做单元,基于事务能够更好的保证业务的正确性。事务具有ACID特性

事务控制

在SysUserServiceImpl类中saveObject方法上添加@Transactional注解,就进行了回滚事务,这个对象由DataSourceTransactionManager管理,此注解也能够定义在类上

事务传播特性

未来但愿此业务方法参与到其余事务中执行,传播特性设置为Propagation.REQUIRED,但愿此业务方法是种运行在一个独立的事务,传播特性设置为Propagation.REQUIRES_NEW。
在SysLogServiceImpl类中saveObject方法上添加@Transactional(propagation = Propagation.REQUIRES_NEW)。


AOP 异步操做实现

假如写日志的操做是一个耗时的动做怎么办,好比在SysLogServiceImpl类中saveObject方法上添加try {Thread.sleep(1000);}catch(Exception e) {},而后启动点击用户管理发现也须要等待,说明查询也被阻塞,能够获取一下线程名进行分析,在UserServiceImpl里的查询也获取一下线程名,发现两个方法是同一个线程,之后但愿不能被阻塞,可让写日志单独开一个线程。方案一能够在SysLogAspect类里new一个线程,可是有弊端,由于大量建立线程内存很快会被耗尽,也是比较耗时。因此靠spring的异步了。

异步

首先要在启动类添加 @EnableAsync //spring容器启动时底层会建立线程池,他不属于tomcat,而后在SysLogServiceImpl类上saveObject方法上添加一个@Async注解。
咱们能够本身对spring框架提供的线程池进行一些简易配置。Demo:image
而后在yml能够作一些简单的配置image


Cache操做实现

配置实现,在启动类中添加@EnableCaching注解,而后在SysMenuServiceImpl类中findObjects方法上添加@Cacheable(value = "menuCache")//次注解描述的方法为一个缓存切入点方法。
可是当更新时也要清缓存,因此要在updateObject方法上添加@CacheEvict(value = "menuCache",allEntries = true,beforeInvocation = false),value中的名字要相同,allEntries表示清楚全部


aop原型设计

相关文章
相关标签/搜索