发表于: 2017-07-26 21:20:01

1 1011


一.今天完成的主要事情

1.学习spring aop的相关知识,用spring aop在项目中打日志

首先,要配置好log4j.properties中的输出目录,之前一直在本地打得日志,所以用相对日志目录设置随意没有问题,但是在服务器上,日志的路径和在本地上不同,今天就出现了在本地能够输出日志,但是在服务器上就不行,最后,用绝对路径解决了这个问题,如图:

aop,面向切面编程,是一种思想,把所有和业务主体逻辑无关的但又必不可少的事物抽取出来,单独管理,然后在需要的时候插入进去,这样,既方便我们管理,又不会在业务逻辑中编写太多无关的代码.比如说,一个service中封装了很多对数据库操作的方法,如果我们想要计算访问数据库所耗费的时间,那么就要通过记录日志来完成,在没有springaop时,我们可能需要在每一个方法中都编写记录日志代码,然后通过日志来看访问数据库所耗费的时间,这样如果我们观察日志的方式有所改变,那么我们需要更改源代码,非常不方便.但是有了springaop之后,我们可以通过配置文件告诉spring框架什么时候在哪里打什么样的日志,spring会自动执行打日志的操作,这样首先是程序员要编写的重复代码大大减少,其次是处理事物非常灵活,只需要更改配置文件即可,不用反复修改代码.

上一个demo说明

首先是工程目录,其中User是简单的POJO模型,UserDao是接口,UserDaoImpl是接口实现,假设是我们的主要的业务逻辑实现的地方,LogAdvice定义了切面中的通知方法

部分UserDaoImpl实现代码,业务很简单,就是简单的打印一句话,表示已经执行

LogAdvice类代码,主要定义通知的类型和具体的方法

public class LogAdvice {

public void before(){

System.out.println("这是一个前置通知!!");

}

public void after(){

System.out.println("这是一个后置通知!!(遇到异常不通知)");

}


//环绕方法比较特殊,需要传入一个参数,该参数通过pjp.proceed执行要加入通知的方法

public Object around(ProceedingJoinPoint pjp) throws Throwable{    

System.out.println("这是一个环绕通知!!(方法执行前)");

Object obj = pjp.proceed();

System.out.println("这是一个环绕通知!!(方法执行后)");

return obj;

}

public void afterException(){

System.out.println("这是一个异常通知!!");

}

public void afterAdvice(){

System.out.println("这是一个后置通知!!(遇到异常通知!)");

}

}

beans.xml文件,主要配置使用的通知的对象,通知方式,定义目标对象

主函数

运行结果:

可以看到,虽然我们在实现类中没有添加一行代码,但是却可以在我们想要切入的方法前后输出一些语句,在实际开发中,我们只要把输出语句换成需要的功能即可.

网上找到的关于springaop的基本术语.

Joinpoint(连接点):所谓连接点是指那些被拦截到的点。在spring中,这些点指的是方法,因为spring只支持方法类型的连接点. 在demo中,UserDaoImpl实现类中的所有方法都可以说是Joinpoint

Pointcut(切入点):所谓切入点是指我们要对哪些Joinpoint进行拦截的定义.Pointcut就是Joinpoint中已经确定的要拦截的方法,在本例中也是UserDaoImpl的所有方法 

Advice(通知/增强):所谓通知是指拦截到Joinpoint之后所要做的事情就是通知.通知分为前置通知,后置通知,异常通知,最终通知,环绕通知(切面要完成的功能,本例中时LogAdvice中的方法)

 Introduction(引介):引介是一种特殊的通知在不修改类代码的前提下, Introduction可以在运行期为类动态地添加一些方法或Field.(在本例中没有用到,暂时还没搞清楚作用和用法)

 Target(目标对象):代理的目标对象(就是UserDaoImpl) 

Weaving(织入):是指把增强应用到目标对象来创建新的代理对象的过程. spring采用动态代理织入,而AspectJ采用编译期织入和类装在期织入 

Proxy(代理):一个类被AOP织入增强后,就产生一个结果代理类 

Aspect(切面): 是切入点和通知(引介)的结合

2.查看Resin日志,统计访问DB的时间,controller的时间

如何统计访问DB的时间,想法是在执行sql语句前后分别记录时间,然后相减得出访问DB时间,而controller的时间也是如此,这个通过springaop的环绕通知就可以实现.

代码中增加一个通知类,通知方法如下:

public class LogAdvice {

public Object around(ProceedingJoinPoint pjp) throws Throwable{

//获取执行的方法的标签

Signature getSignature = pjp.getSignature();

//记录执行前的时间

long startTime = System.currentTimeMillis();

Object obj = pjp.proceed();

//记录执行后的时间

long endTime = System.currentTimeMillis();

Long times = endTime - startTime;

Log.loggerCreate(LogLevel.WARN, "执行 "+ getSignature.toString() +" 用时: " + times.toString() + "ms");

return obj;

}

}

配置文件中添加一些配置,添加的内容基本和上面的demo相同,只是通知方式只有一种.完成后部署至resin服务器,可以在resin的日志中看到统计如下:

二.明天计划的事情

1.完成最后两个task

2.根据验收标准做调整

3.如果有时间,回答深度思考,争取明天后天结束任务三

三.遇到的问题

暂无

四.收获

了解并实现springaop的基本用法,真的非常好用


返回列表 返回列表
评论

    分享到