关于java:动吧增强

37次阅读

共计 3354 个字符,预计需要花费 9 分钟才能阅读完成。

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 示意分明所有

正文完
 0