一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - springMVC自定義注解,用AOP來實現日志記錄的方法

springMVC自定義注解,用AOP來實現日志記錄的方法

2021-03-25 10:58沒有桃子的阿貍 Java教程

下面小編就為大家分享一篇springMVC自定義注解,用AOP來實現日志記錄的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧

需求背景

最近的一個項目,在項目基本完工的階段,客戶提出要將所有業務操作的日志記錄到數據庫中,并且要提取一些業務的關鍵信息(比如交易單號)體現在日志中。

為了保證工期,在查閱了資料以后,決定用AOP+自定義注解的方式來完成這個需求。

準備工作

自定義注解需要依賴的jar包有 aspectjrt-XXX.jar ,aspectjweaver-XXX.jar,XXX代表版本號。

自定義注解

在項目下單獨建立了一個log包,來存放日志相關的內容

?
1
2
**.common.log.annotation //自定義注解存放位置
**.common.log.aop     //aop工具類存放位置

在annotation包下面新建自定義注解類:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
package **.common.log.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
public @interface XXXOperateLog {
  /**
   * 操作類型描述
   * @return
   */
  String operateTypeDesc() default "";
  /**
   * 操作類型
   * @return
   */
  long operateType() default -1;
  /**
   * 模塊編碼
   * @return
   */
  String moudleCode() default "M30";
  /**
   * 模塊名稱
   * @return
   */
  String moudleName() default "XX模塊";
  /**
   * 業務類型
   * @return
   */
  String bussType() default "";
  /**
   * 業務類型描述
   * @return
   */
  String bussTypeDesc() default "";
}

在aop包下新建XXXOperateLogAop

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
package **.common.log.aop;
import ** ;//省略
@Aspect
@Component
public class XXXOperateLogAop{
  @Autowired
  SystemLogService systemLogService;
   HttpServletRequest request = null;
   Logger logger = LoggerFactory.getLogger(XXXOperateLogAop.class);
  ThreadLocal<Long> time = new ThreadLocal<Long>();
  //用于生成操作日志的唯一標識,用于業務流程審計日志調用
  public static ThreadLocal<String> tag = new ThreadLocal<String>();
  //聲明AOP切入點,凡是使用了XXXOperateLog的方法均被攔截
  @Pointcut("@annotation(**.common.log.annotation.XXXOperateLog)")
  public void log() {
    System.out.println("我是一個切入點");
  }
  /**
   * 在所有標注@Log的地方切入
   * @param joinPoint
   */
  @Before("log()")
  public void beforeExec(JoinPoint joinPoint) {
    time.set(System.currentTimeMillis()); 
    info(joinPoint);
    //設置日志記錄的唯一標識號
    tag.set(UUID.randomUUID().toString());
    request= ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
  }
  @After("log()")
  public void afterExec(JoinPoint joinPoint) {
    MethodSignature ms = (MethodSignature) joinPoint.getSignature();
    Method method = ms.getMethod();
    logger.debug("標記為" + tag.get() + "的方法" + method.getName()
        + "運行消耗" + (System.currentTimeMillis() - time.get()) + "ms"); 
  }
  //在執行目標方法的過程中,會執行這個方法,可以在這里實現日志的記錄
  @Around("log()")
  public Object aroundExec(ProceedingJoinPoint pjp) throws Throwable {
    Object ret = pjp.proceed();
    try {
      Object[] orgs = pjp.getArgs();
      SystemLog valueReturn = null;
      for (int i = 0; i < orgs.length; i++) {
        if(orgs[i] instanceof SystemLog){
          valueReturn = (SystemLog) orgs[i];
        
      
      if(valueReturn==null){
        valueReturn = new SystemLog();
      }
      if(valueReturn!=null&&request!=null){
        MethodSignature ms = (MethodSignature) pjp.getSignature();
        Method method = ms.getMethod();
        //獲取注解的操作日志信息
        XXXOperateLog log = method.getAnnotation(XXXOperateLog.class);
        String businessType = log.bussType();
        String businessDesc = log.bussTypeDesc();
        HashMap requestMap = ServletUtils.getParametersToHashMap(request) ;
        //從參數中尋找業務類型
        if(businessType.equals(""))
        {
          Object objBusinessType = requestMap.get("business_type");
          businessType = objBusinessType == null ? "" : objBusinessType.toString();
        }
        //從執行結果的申請單中找業務類型
        Object apply = request.getAttribute("apply") ;
        if(apply != null){
          JSONObject obj = JSONFactory.toJSONAbstractEntity(apply);
          if(obj != null)
          {
            valueReturn.setOtherDesc("申請單號:"+obj.getString("apply_no"));
            if(businessType.equals(""))
            {
              businessType = obj.getString("business_type");
            }
          }
        }
        //從方法的執行過程參數中找業務類型(一般是手動設置)
        if(businessType.equals(""))
        {
          businessType = (String) request.getAttribute("business_type");
          businessType = businessType == null ? "" : businessType;
        }
        if(!businessType.equals("") && businessDesc.equals(""))
        {
          businessDesc = XXXSysConstant.BUSINESS_TYPE.getName(businessType);
        }
        valueReturn.setBussType(XXXSysConstant.BUSINESS_TYPE.getNumber(businessType));
        valueReturn.setBussTypeDesc(businessDesc);
        valueReturn.setMoudleCode(log.moudleCode());
        valueReturn.setMoudleName(log.moudleName());
        valueReturn.setOperateResult(XXXSysConstant.YesOrNo.YES);
        valueReturn.setOperateType(log.operateType());
        valueReturn.setInputUserId(((UserContext)WebUtils.getSessionAttribute(request, "XXXuserContext")).getSysUser().getId());
        valueReturn.setOperateTypeDesc(log.operateTypeDesc());
        valueReturn.setRequestIp(getRemoteHost(request));
        valueReturn.setRequestUrl(request.getRequestURI());
        valueReturn.setServerIp(request.getLocalAddr());
        valueReturn.setUids(tag.get());
        //保存操作日志
        systemLogService.saveSystemLog(valueReturn);
      }else{
        logger.info("不記錄日志信息");
      }
      //保存操作結果 
    } catch (Exception e) {
      e.printStackTrace();
    }
    return ret;
  }
  //記錄異常日志
  @AfterThrowing(pointcut = "log()",throwing="e")
  public void doAfterThrowing(JoinPoint joinPoint, Throwable e) {
    try {
      info(joinPoint);
      Object[] orgs = joinPoint.getArgs();
      SystemLog valueReturn = null;
      for (int i = 0; i < orgs.length; i++) {
        if(orgs[i] instanceof SystemLog){
          valueReturn = (SystemLog) orgs[i];
        }     
      }
      if(valueReturn==null){
        valueReturn = new SystemLog();
      }
      if(valueReturn!=null&&request!=null){
        MethodSignature ms = (MethodSignature) joinPoint.getSignature();
        Method method = ms.getMethod();
        XXXOperateLog log = method.getAnnotation(XXXOperateLog.class);
        String businessType = log.bussType();
        String businessDesc = log.bussTypeDesc();
        if(businessType.equals(""))
        {
          Object objBusinessType = ServletUtils.getParametersToHashMap(request).get("business_type");
          businessType = objBusinessType == null ? "" : objBusinessType.toString();
          businessDesc = XXXSysConstant.BUSINESS_TYPE.getName(businessType);
        }
        valueReturn.setBussType(XXXSysConstant.BUSINESS_TYPE.getNumber(businessType));
        valueReturn.setBussTypeDesc(businessDesc);
        valueReturn.setMoudleCode(log.moudleCode());
        valueReturn.setMoudleName(log.moudleName());
        valueReturn.setOperateType(log.operateType());
        valueReturn.setOperateTypeDesc(log.operateTypeDesc());
        valueReturn.setInputUserId(((UserContext)WebUtils.getSessionAttribute(request, "XXXuserContext")).getSysUser().getId());
        valueReturn.setOperateResult(XXXSysConstant.YesOrNo.NO);
        String errMes = e.getMessage();
        if(errMes!=null && errMes.length()>800){
          errMes = errMes.substring(0, 800);
        }
        valueReturn.setErrorMessage(errMes);
        valueReturn.setRequestIp(getRemoteHost(request));
        valueReturn.setRequestUrl(request.getRequestURI());
        valueReturn.setServerIp(request.getLocalAddr());
        valueReturn.setUids(tag.get());
        systemLogService.saveSystemLog(valueReturn);
      }else{
        logger.info("不記錄日志信息");
      }
    } catch (Exception e1) {
      e1.printStackTrace();
    }
  }
  private void info(JoinPoint joinPoint) {
    logger.debug("--------------------------------------------------");
    logger.debug("King:\t" + joinPoint.getKind());
    logger.debug("Target:\t" + joinPoint.getTarget().toString());
    Object[] os = joinPoint.getArgs();
    logger.debug("Args:");
    for (int i = 0; i < os.length; i++) {
      logger.debug("\t==>參數[" + i + "]:\t" + os[i].toString());
    }
    logger.debug("Signature:\t" + joinPoint.getSignature());
    logger.debug("SourceLocation:\t" + joinPoint.getSourceLocation());
    logger.debug("StaticPart:\t" + joinPoint.getStaticPart());
    logger.debug("--------------------------------------------------");
  }
  /**
   * 獲取遠程客戶端Ip
   * @param request
   * @return
   */
  private String getRemoteHost(javax.servlet.http.HttpServletRequest request){
    String ip = request.getHeader("x-forwarded-for");
    if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)){
      ip = request.getHeader("Proxy-Client-IP");
    }
    if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)){
      ip = request.getHeader("WL-Proxy-Client-IP");
    }
    if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)){
      ip = request.getRemoteAddr();
    }
    return ip.equals("0:0:0:0:0:0:0:1")?"127.0.0.1":ip;
  
}

修改配置文件spring-mvc.xml,添加如下配置

?
1
2
3
4
5
6
7
<!-- 開啟AOP攔截 -->
<aop:aspectj-autoproxy proxy-target-class="true" />
<mvc:annotation-driven />
<!-- 定義Spring描述Bean的范圍 -->
<context:component-scan base-package="**.common.log" >
   <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>

需要注意的是,上述配置必須放在同一個xml文件里面,要么spring-mvc.xml,要么spring-context.xml,否則可能不生效,暫時還未查明是為什么。

注解的使用

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
@XXXOperateLog(
      bussType=XXXSysConstant.BUSINESS_TYPE.YYYY
      ,bussTypeDesc="業務類型描述"
      ,operateType = XXXSysConstant.LogOperateType.QUERY
      ,operateTypeDesc = "操作描述"
  )
  @RequestMapping(value = "/**/**/queryXXXXX4DataGrid.json", method = RequestMethod.POST)
  public void queryXXXXX4DataGrid(HttpServletRequest request, HttpServletResponse arg1, Model model, Writer writer)
  {
    logger.info("==========驗票查詢(出庫)交易信息 開始=====================");
    try {
      //do something for business
    } catch (SystemException se) {
      throw se;
    } catch (BusinessException be) {
      throw be;
    } catch (Exception e) {
      throw new SystemException(e);
    }
  }

以上這篇springMVC自定義注解,用AOP來實現日志記錄的方法就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支持服務器之家。

原文鏈接:http://blog.csdn.net/yang_lover/article/details/53037323

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 国产99在线 | 天天夜夜草草久久伊人天堂 | 男人添女人 | 美女又爽又黄免费 | 91香蕉国产在线观看人员 | 婷婷精品 | 91在线精品视频 | 国内视频一区二区 | 无颜之月全集免费观看 | 无遮掩60分钟从头啪到尾 | 久久视热频国产这里只有精品23 | 精新精新国产自在现拍 | 青青青视频免费线看 视频 青青青青青国产免费手机看视频 | 成人小视频在线免费观看 | 久久久伊人影院 | 日本在线视 | 成人精品视频一区二区在线 | 日本免费一区二区三区a区 日本免费三片在线观看 | 美女靠逼的视频 | 粗又长好猛好爽视频 | 亚洲欧美日韩综合在线播放 | 无码国产成人777爽死在线观看 | 好吊色视频988gao在线观看 | 日本加勒比在线播放 | 国产精品日韩欧美一区二区 | 特级淫片欧美高清视频蜜桃 | 91天堂在线视频 | 国产精品久久久久久久久免费hd | 1377大但人文艺术包子铺 | 3d动漫美女被吸乳羞羞有 | 欧美在线视频免费播放 | 国产福利一区二区在线精品 | 沉沦艳妇杨幂肉体小说 | 无码国产成人777爽死 | 全黄h全肉细节文在线观看 全彩成人18h漫画 | 男人猛进猛出女人下面视频 | 欧美一区精品 | 美女国内精品自产拍在线播放 | 国产激情视频 | 美女跪式抽搐gif动态图 | www日本在线观看 |