您的位置:首页 > 运维架构

AOP切面管理日志的两种方式

2017-09-16 21:20 274 查看
最近想看一下切面编程,然后之前文章里边转载过一篇自定义注解的原理,在今天这篇文章里边,将会使用自定义注解应用到管理日志里边,当然这个只是一个简单的demo,具体的向数据库插入日志,这个自己在项目中使用到的时候,new实体,然后对应地方执行操作就行了。。。

先简单介绍几个概念:

 AOP配置元素 | 描述 

------------ | -------------

`<aop:advisor>` | 定义AOP通知器

`<aop:after>`  | 定义AOP后置通知(不管该方法是否执行成功)

`<aop:after-returning>` | 在方法成功执行后调用通知

`<aop:after-throwing>` | 在方法抛出异常后调用通知

`<aop:around>` | 定义AOP环绕通知

`<aop:aspect>` | 定义切面

`<aop:aspect-autoproxy>` | 定义`@AspectJ`注解驱动的切面

`<aop:before>` | 定义AOP前置通知

`<aop:config>` | 顶层的AOP配置元素,大多数的<aop:*>包含在<aop:config>元素内

`<aop:declare-parent>` | 为被通知的对象引入额外的接口,并透明的实现

`<aop:pointcut>` | 定义切点

上边的是xml配置里边的相关概念,但是采用注解方式,意思跟上边一样。

1.注解方式,顺便提一下自定义注解,在方法上加上自定义注解,可以让你知道程序知道这个方法是干嘛用的,直接看代码:

注解类:

package com.yuan.aspect;

import java.lang.reflect.Method;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

import com.yuan.aspect.annotation.Hello;

@Aspect
@Component
public class SpringAspectTest {

@Pointcut("execution(* com.yuan.service.impl.TeacherImpl.*(..))")
public void serviceLogAspect() {
}

@Before("serviceLogAspect()")
public void doBefore(JoinPoint joinPoint) {
System.out.println("apo-aspect start------------------------");
}

@After("serviceLogAspect()")
public void doAfter(JoinPoint joinPoint) {
try {
String className = joinPoint.getTarget().getClass().getName();
String methodName = joinPoint.getSignature().getName();
System.out.println("切点:" + joinPoint);
System.out.println("类名:" + className);
System.out.println("方法名:" + methodName);
Object[] arguments = joinPoint.getArgs(); // 参数
String param = className + "." + methodName + ":";
for (int i = 0; i < arguments.length; i++) {
if (arguments[i] != null && !"".equals(arguments[i])
&& !"null".equals(arguments[i])) {
param += "参数[" + i + "]:" + arguments[i].toString();
}
}
// 开始自定义注解
Class clz = Class.forName(className);// 获得我们需要解析注解的类
// 解析Method
// 获得类中所有方法
Method[] methods = clz.getMethods();
for (Method m : methods) {
if (m.getName().equals(methodName)) {
Class[] clazzs = m.getParameterTypes();
if (clazzs.length == arguments.length) {
String methodType = m.getAnnotation(Hello.class)
.methodType();
String methodName1 = m.getAnnotation(Hello.class)
.methodName();
System.out.println("注解类型:" + methodType);
System.out.println("注解名字:" + methodName1);
break;
}
}
}
System.out.println("param:" + param);
System.out.println("apo-aspect end------------------------");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}

/* 执行成功后通知 */
@AfterReturning("serviceLogAspect()")
public void doAfterReturning() {
System.out.println("方法成功执行后通知 日志记录");
}

/* 抛出异常后通知,可以打印到日志里边,或者存入数据库里边 */
@AfterThrowing(pointcut = "serviceLogAspect()", throwing = "e")
public void doAfterThrowing(JoinPoint joinPoint, Throwable e) {
try {
String className = joinPoint.getTarget().getClass().getName();
String methodName = joinPoint.getSignature().getName();
System.out.println("切点:" + joinPoint);
System.out.println("类名:" + className);
System.out.println("方法名:" + methodName);
Object[] arguments = joinPoint.getArgs(); // 参数
String param = className + "." + methodName + ":";
for (int i = 0; i < arguments.length; i++) {
if (arguments[i] != null && !"".equals(arguments[i])
&& !"null".equals(arguments[i])) {
param += "参数[" + i + "]:" + arguments[i].toString();
}
}
// 开始自定义注解
Class clz = Class.forName(className);// 获得我们需要解析注解的类
String methodType = "";
String methodName1 = "";
// 解析Method
// 获得类中所有方法
Method[] methods = clz.getMethods();
for (Method m : methods) {
if (m.getName().equals(methodName)) {
Class[] clazzs = m.getParameterTypes();
if (clazzs.length == arguments.length) {
methodType = m.getAnnotation(Hello.class).methodType();
methodName1 = m.getAnnotation(Hello.class).methodName();
System.out.println("注解类型:" + methodType);
System.out.println("注解名字:" + methodName1);
break;
}
}
}
System.out.println("param:" + param);
System.out.println("=====异常通知开始=====");
System.out.println("异常代码:" + e.getClass().getName());
System.out.println("异常信息:" + e.getMessage());
System.out.println("异常方法:"
+ (joinPoint.getTarget().getClass().getName() + "."
+ joinPoint.getSignature().getName() + "()") + "."
+ methodName);
} catch (ClassNotFoundException e1) {
e.printStackTrace();
}
}
}


service方法层:

package com.yuan.service.impl;

import java.util.List;

import javax.annotation.Resource;

import org.springframework.stereotype.Service;

import com.yuan.aspect.annotation.Hello;
import com.yuan.dao.TeacherDao;
import com.yuan.entity.Teacher;
import com.yuan.entity.query.TeacherQuery;
import com.yuan.service.TeacherService;

@Service(value = "teacherService")
public class TeacherServiceImpl implements TeacherService {

@Resource
private TeacherDao teacherDao;

@Override
@Hello(methodType = "查询操作", methodName = "查询所有老师")
public List<teacher> queryAll() {
return teacherDao.queryAll();
}

@Override
@Hello(methodType = "查询操作", methodName = "查询所有老师")
public List<teacher> getTeacherList(TeacherQuery teacherQuery) {
return teacherDao.getTeachetList(teacherQuery);
}

@Override
@Hello(methodType = "查询操作", methodName = "查询老师总记录数")
public Integer getTeacherCount(TeacherQuery teacherQuery) {
return teacherDao.getCountByQuery(teacherQuery);
}

@Override
public int delete(String id) {
// TODO Auto-generated method stub
return 0;
}

@Override
public int update(Teacher t) {
// TODO Auto-generated method stub
return 0;
}

@Override
public Teacher getInfoById(String id) {
// TODO Auto-generated method stub
return null;
}

@Override
public int add(Teacher t) {
// TODO Auto-generated method stub
return 0;
}
}
</teacher></teacher>


2.xml方式

<!--日志拦截配置-->
<bean id="logInterceptor" class="com.yuan.fliter.LogInterceptor">
<aop:config>
<aop:aspect id="exceptionAspect" ref="logInterceptor" order="2">
<aop:pointcut id="businessService" expression="(execution(* com.yuan..service..*.*(..)))">
<aop:after-throwing pointcut-ref="businessService" method="doThrowing" throwing="ex">
<aop:after pointcut-ref="businessService" method="operationLog">
</aop:after></aop:after-throwing></aop:pointcut></aop:aspect>
</aop:config>
</bean>


LogInterceptor代码:

package com.yuan.fliter;

import org.aspectj.lang.JoinPoint;

/**
* 日志拦截器
* @author yhl
*
*/
public class LogInterceptor {

public void operationLog(JoinPoint joinPoint){
String className = joinPoint.getTarget().getClass().getName();
String methodName = joinPoint.getSignature().getName();
System.out.println("切点:"+joinPoint);
System.out.println("类名:"+className);
System.out.println("方法名:"+methodName);
Object[] arguments = joinPoint.getArgs(); //参数
String param = className + "." + methodName + ":";
for (int i = 0; i < arguments.length; i++) {
if(arguments[i]!=null&&!"".equals(arguments[i])&&!"null".equals(arguments[i])){
param += "参数[" + i + "]:" + arguments[i].toString();
}
}
System.out.println("param:"+param);
System.out.println("apo-aspect end------------------------");
}

public void doThrowing(JoinPoint jp, Throwable ex){
System.out.printf("类名:"+jp.getTarget().getClass().getName()+"    方法名:"+jp.getSignature().getName(),ex);
}

}


最后附上一张执行后的结果:



参考文章:
http://www.cnblogs.com/jianjianyang/p/49 adc8
10851.html#top
http://www.cnblogs.com/flowwind/p/4782606.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: