AOP
是一种设计思维(mvc分层架构设计思维,连接池池化思维,ioc管制反转思维,oop面向对象思维),强调的是一个服务增益的思维,面向切面编程。
当咱们写一个类,零碎底层帮咱们生成一个子类,这种办法就叫做代理。当初默认是cglib代理
aop相干术语
切面(aspect):咱们会写一个类,基于这个类构建的对象就是切面对象,这个类写的时候会用@Aspect形容,用这个注解形容的类称之为切面类
告诉(Advice):在切面某个特定的点上要执行的动作称之为告诉
连接点(joinpoint):个别指向被拦挡到的指标办法,就是要为哪个办法做扩大
比方,坐地铁,要做安检,安检的动作就是告诉,安检的中央就可以看做是切面(封装了连接点和告诉办法的对象),正在安检的点就可以看做是连接点,一堆安检点就叫做切入点
配置
业务形容
基于我的项目中的外围业务,增加简略的日志操作,借助SLF4J日志API输入指标办法的执行时长。
记录日志,为了避免重复性的编写,在办法执行前记录一下工夫,在办法完结后再记录一下工夫,工夫相减就是指标办法执行工夫
创立
首先在com.cy.pj.common.aspect包下创立SysLogAspect类
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,
这个类是SysYserServuceImpl的子类,这个是底层写的(CGLIB
代理),最初是代理对象调用切面对象的around办法。
在yml文件增加一行配置。
切面告诉执行程序
在aspect包下增加SysTimeAspect办法
练习
定义一个异样监控切面,对指标页面办法进行异样监控,并以日志信息的
模式输入异样,当前能够写报警的
在aspect包下创立SysExceptionAspect类
练习
定义一Cache相干切面,应用注解表达式定义切入点,并应用此注解对须要应用cache的业务办法进行形容部门里的查询方法
第一步:在annotation包下增加RequiredCache办法注解
第二步:定义SysCacheAspect切面对象。在aspect包下增加SysCacheAspect办法
第三步:应用@RequiredCache注解对部门查问进行形容。
从新增加一个需要
当把数据库里的数据更新或删除的时候,cache里要清空。
所以要在部门办法上增加一个@doClearCache注解
概览
@Aspect:切面 @Pointcut:切入点 @Advice:告诉办法 @JoinPoint:连接点 @Order:优先级
大节
以AOP形式记录我的项目中的用户行为信息,并将其存储到数据库
能够逆向思维,先想怎么存储到数据库
dao层
首先在SysLogDao接口增加int insertObject(SysLog entity);办法,因为当初查问到的就是SysLog,所以当初写也能够这么写,而后写映射文件
service层
在SysLogService接口增加void saveObject(SysLog entity);办法,
实现类
在SysLogServiceImpl类增加saveObject办法
当拜访用户治理要抓取日志,所以要定义切面,在SysLogAspect类中增加将用户行为信息写入到数据库的办法saveUserLog(jp,(t2-t1)); 和saveUserLog办法
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:
而后在yml能够做一些简略的配置。
Cache操作实现
配置实现,在启动类中增加@EnableCaching注解,而后在SysMenuServiceImpl类中findObjects办法上增加@Cacheable(value = "menuCache")//次注解形容的办法为一个缓存切入点办法。
然而当更新时也要清缓存,所以要在updateObject办法上增加@CacheEvict(value = "menuCache",allEntries = true,beforeInvocation = false),value中的名字要雷同,allEntries示意分明所有