发表于: 2018-04-04 12:34:52

1 637


今天完成的任务:

(1)写了一个比较弱智的脚本。。。算是可以把我放进去的war包自动部署了(期间我还不小心删了我的tomcat和tomcat中的webapps文件夹,现在文件夹里面的错误页面跳转都没了,而且我自己也没捕获异常,深入的脚本就暂时不做了。赶赶任务进度)

(2)centos7上安装resin,下的是rpm包,用rpm-ivh解压之后发现没有文件,原因是我之前装过一次被我手动删了但是程序还认为我有文件夹,用rpm指令删除之后可以顺利安装。

如果不指定安装的话会这样给你安装到4个不同的地方,这时候进入resin/bin执行resin.sh -start指令会显示在resin/conf下找不到resin.xml,原来是脚本文件会自动找当前文件夹下的conf文件,那就把/etc/resin下的文件夹移动过来放到新的conf文件夹下,OK,可以运行,也可以看到resin成功的监听到了端口。

resin启动脚本,不然每次都要cd到webapps里面真的很麻烦,然后部署项目,有报错:

500错误,检查了一遍代码,应该没错,放到tomcat上运行,正常,那么看到这个报错信息我还以为是之前打的jetty的jar包不兼容,那么把pom中的jetty注释掉再把jar包删掉重新打包,放上去,仍然报错。

这就很郁闷。

(3)面向切面编程(AOP)对控制层和DB进行切入输出反应时间

这里我用自己的话来描述一下面向切面编程吧,毕竟网上的资料很多

如果把java一个程序看成是一个过程的话,那么这个过程基本都是纵向的,因为涉及到了继承、多态,如果你想使用其他类中的一个方法,也要先构造实体对象来引用,这种纵向的紧密相连使得我们无法做到在业务逻辑中做一些自己想做的事情(比如输出日志),如果非要完成日志输出,那么最笨的方法是在每个控制器的每个方法前后加入logger.info,当然你说可以不这么麻烦,可以建一个日志输出的类,到时候使用输出类中的方法即可,不过这也是需要去进行逻辑判断的,而属于面向对象编程的面向切面编程给我们提供了一种这样简便的方法,即只要写出一个切面组件类,告诉spring容器这是一个@Aspect,再使用bean注入到容器中。

那么这个切面组件中我们需要写一些什么呢,首先要指定pointcut(切入点),切入点声明了这个切面组件要对哪个类或者类中的哪个方法进行切面处理,拿我写的代码举例,如果我要获得DB处理时间,我就需要指定我的dao接口层为pointcut:

@Pointcut("execution(* mapper.StudentMapper.*(..))")

这种写法是指定了studentmappper下的所有方法为切入点,即每次执行方法都会进行通知。

那么什么叫通知,我觉得叫增强也更为合理,在切入点的类或方法执行的过程中输入你想执行的语句 (这个过程也就是编织),在不改变原类的情况下增强了类中的语句(日志输出方面就是增强了日志的输出),通知有5~6种吧,我只试着用了一下@before @after @around

@before即在切入点之前通知,@after即在切入点之后通知,@around会做两次通知,这里详细说明一下@around用法,在使用@around时必须:

ProceedingJoinPoint

声明这样一个变量,它是JoinPoint的子类:

public Object Time(ProceedingJoinPoint proceedingJoinPoint){
// proceedingJoinPoint封装了连接点的详细信息
   // proceed,执行目标方法 method.invoke
   Object object = null;
Object[] args = proceedingJoinPoint.getArgs();
System.out.println("测试");
long start = System.currentTimeMillis();
try {
// method.invoke
       // 目标方法执行完成后会有返回值,这个返回值一定return出去
       object = proceedingJoinPoint.proceed(args);
} catch (Throwable throwable) {
logger.error("环绕增强出错",throwable);
}
long end = System.currentTimeMillis();
MethodSignature methodSignature = (MethodSignature)proceedingJoinPoint.getSignature();
String methodname = methodSignature.getDeclaringTypeName()+"."+methodSignature.getName();
logger.info("处理方法为:"+methodname+"   处理时间为:"+(end-start)+"毫秒");
return  object;
}

这里实际上就是执行了切入点中的方法,以此来区分环绕通知的前后,而方法有一个返回值必须return,我在代码中已经写的很详细了,再说一点就是:

proceedingJoinPoint.getSignature().getName():

这样可以获得切入点执行方法的方法名,这一点参考了网上的一篇教程。

我这里使用了@AspectJ,就不用再配置bean而是让spring进行自动搜索装配:

  <aop:aspectj-autoproxy/>
<!--自动搜索切面类-->
 <context:component-scan base-package="aop"/>
<!--@Aspect支持,支持非接口类-->
 <aop:aspectj-autoproxy proxy-target-class="true"/>
</beans>

今天遇到的问题:

resin不能部署程序,编写aop的时候提示找不到around类,我一直以为是jar包出错,没想到是因为我spring框架版本太高 全都是5.0.1,改回4.3X版本之后AOP问题解决,顺便resin也一起解决了,一个版本惹了这么多祸,下次要多留个心眼。

还有个未解决的问题,网上说

<aop:aspectj-autoproxy proxy-target-class="true"/>

一旦这里改为true之后切入点就可以指定非接口的类(如果为false则只能对接口类实现切入,如果为true则使用cglib库实现动态代理,两种原理区别很大,我只是大致了解了一下),然而实际操作过程中发现就算指定为true我仍然无法指定我的控制器为pointcut(如果指定的话不会报错但是控制台和日志均无输出),尝试修改多次依然失败,不知道哪里出了问题。

这是接口类环绕通知,是成功了的。不过这个c3p0连接池的日志输出有点烦,另外不知道怎么用脚本把我的统计时间数据从日志里面拿出来做计算(可以实现么。。resin的配置文件由于时间还没研究,不太懂)

今天的收获:

学习了面向切面编程思想(解耦合),在resin上部署了程序。

明天的任务:

研究resin配置文件,看看能不能解决一下控制器不能被环绕增强的BUG,提交任务三(胡说)


返回列表 返回列表
评论

    分享到