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

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

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

服務器之家 - 編程語言 - JAVA教程 - spring AOP自定義注解方式實現日志管理的實例講解

spring AOP自定義注解方式實現日志管理的實例講解

2021-03-25 11:04悟空,你真了不得 JAVA教程

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

今天繼續實現AOP,到這里我個人認為是最靈活,可擴展的方式了,就拿日志管理來說,用Spring AOP 自定義注解形式實現日志管理。廢話不多說,直接開始!!!

關于配置我還是的再說一遍。

在applicationContext-mvc.xml中要添加的

?
1
2
3
4
5
6
7
8
9
10
11
<mvc:annotation-driven />
<!-- 激活組件掃描功能,在包com.gcx及其子包下面自動掃描通過注解配置的組件 -->
<context:component-scan base-package="com.gcx" />
  
<!-- 啟動對@AspectJ注解的支持 -->
<!-- proxy-target-class等于true是強制使用cglib代理,proxy-target-class默認是false,如果你的類實現了接口 就走JDK代理,如果沒有,走cglib代理 -->
<!-- 注:對于單利模式建議使用cglib代理,雖然JDK動態代理比cglib代理速度快,但性能不如cglib -->
<!--如果不寫proxy-target-class="true"這句話也沒問題-->
<aop:aspectj-autoproxy proxy-target-class="true"/>
<!--切面-->
<bean id="systemLogAspect" class="com.gcx.annotation.SystemLogAspect"></bean>

接下來開始編寫代碼。

創建日志類實體

?
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
public class SystemLog {
  private String id;
  private String description;
  private String method;
  private Long logType;
  private String requestIp;
  private String exceptioncode;
  private String exceptionDetail;
  private String params;
  private String createBy;
  private Date createDate;
  public String getId() {
    return id;
  }
  public void setId(String id) {
    this.id = id == null ? null : id.trim();
  }
  public String getDescription() {
    return description;
  }
  public void setDescription(String description) {
    this.description = description == null ? null : description.trim();
  }
  public String getMethod() {
    return method;
  }
  public void setMethod(String method) {
    this.method = method == null ? null : method.trim();
  }
  public Long getLogType() {
    return logType;
  }
  public void setLogType(Long logType) {
    this.logType = logType;
  }
  public String getRequestIp() {
    return requestIp;
  }
  public void setRequestIp(String requestIp) {
    this.requestIp = requestIp == null ? null : requestIp.trim();
  }
  public String getExceptioncode() {
    return exceptioncode;
  }
  public void setExceptioncode(String exceptioncode) {
    this.exceptioncode = exceptioncode == null ? null : exceptioncode.trim();
  }
  public String getExceptionDetail() {
    return exceptionDetail;
  }
  public void setExceptionDetail(String exceptionDetail) {
    this.exceptionDetail = exceptionDetail == null ? null : exceptionDetail.trim();
  }
  public String getParams() {
    return params;
  }
  public void setParams(String params) {
    this.params = params == null ? null : params.trim();
  }
  public String getCreateBy() {
    return createBy;
  }
  public void setCreateBy(String createBy) {
    this.createBy = createBy == null ? null : createBy.trim();
  }
  public Date getCreateDate() {
    return createDate;
  }
  public void setCreateDate(Date createDate) {
    this.createDate = createDate;
  }
}

編寫dao接口

?
1
2
3
4
5
6
7
8
9
10
package com.gcx.dao;
import com.gcx.entity.SystemLog;
public interface SystemLogMapper {
  int deleteByPrimaryKey(String id);
  int insert(SystemLog record);
  int insertSelective(SystemLog record);
  SystemLog selectByPrimaryKey(String id);
  int updateByPrimaryKeySelective(SystemLog record);
  int updateByPrimaryKey(SystemLog record);
}

編寫service層

?
1
2
3
4
5
6
7
8
9
10
11
package com.gcx.service;
import com.gcx.entity.SystemLog;
public interface SystemLogService {
  int deleteSystemLog(String id);
  int insert(SystemLog record);
  
  int insertTest(SystemLog record);
  SystemLog selectSystemLog(String id);
  
  int updateSystemLog(SystemLog record);
}

編寫service實現類serviceImpl

?
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 com.gcx.service.impl;
import javax.annotation.Resource;
import org.springframework.stereotype.Service;
import com.gcx.annotation.Log;
import com.gcx.dao.SystemLogMapper;
import com.gcx.entity.SystemLog;
import com.gcx.service.SystemLogService;
@Service("systemLogService")
public class SystemLogServiceImpl implements SystemLogService {
  @Resource
  private SystemLogMapper systemLogMapper;
  
  @Override
  public int deleteSystemLog(String id) {
    
    return systemLogMapper.deleteByPrimaryKey(id);
  }
  @Override
  
  public int insert(SystemLog record) {
    
    return systemLogMapper.insertSelective(record);
  }
  @Override
  public SystemLog selectSystemLog(String id) {
    
    return systemLogMapper.selectByPrimaryKey(id);
  }
  @Override
  public int updateSystemLog(SystemLog record) {
    
    return systemLogMapper.updateByPrimaryKeySelective(record);
  }
  @Override
  public int insertTest(SystemLog record) {
    
    return systemLogMapper.insert(record);
  }
}

到這里基本程序編寫完畢

下面開始自定義注解

?
1
2
3
4
5
6
7
8
9
10
11
12
package com.gcx.annotation;
import java.lang.annotation.*;
@Target({ElementType.PARAMETER, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Log {
  /** 要執行的操作類型比如:add操作 **/
  public String operationType() default "";
   
  /** 要執行的具體操作比如:添加用戶 **/
  public String operationName() default "";
}

下面編寫切面

?
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
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
package com.gcx.annotation;
import java.lang.reflect.Method;
import java.util.Date;
import java.util.UUID;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import com.gcx.entity.SystemLog;
import com.gcx.entity.User;
import com.gcx.service.SystemLogService;
import com.gcx.util.JsonUtil;
/**
 * @author 楊建
 * @E-mail: email
 * @version 創建時間:2015-10-19 下午4:29:05
 * @desc 切點類
 */
@Aspect
@Component
public class SystemLogAspect {
  //注入Service用于把日志保存數據庫
  @Resource //這里我用resource注解,一般用的是@Autowired,他們的區別如有時間我會在后面的博客中來寫
  private SystemLogService systemLogService;
  
  private static final Logger logger = LoggerFactory.getLogger(SystemLogAspect. class);
  
  //Controller層切點
  @Pointcut("execution (* com.gcx.controller..*.*(..))")
  public void controllerAspect() {
  }
  
  /**
   * 前置通知 用于攔截Controller層記錄用戶的操作
   *
   * @param joinPoint 切點
   */
  @Before("controllerAspect()")
  public void doBefore(JoinPoint joinPoint) {
    System.out.println("==========執行controller前置通知===============");
    if(logger.isInfoEnabled()){
      logger.info("before " + joinPoint);
    }
  
  
  //配置controller環繞通知,使用在方法aspect()上注冊的切入點
   @Around("controllerAspect()")
   public void around(JoinPoint joinPoint){
     System.out.println("==========開始執行controller環繞通知===============");
     long start = System.currentTimeMillis();
     try {
       ((ProceedingJoinPoint) joinPoint).proceed();
       long end = System.currentTimeMillis();
       if(logger.isInfoEnabled()){
         logger.info("around " + joinPoint + "\tUse time : " + (end - start) + " ms!");
       }
       System.out.println("==========結束執行controller環繞通知===============");
     } catch (Throwable e) {
       long end = System.currentTimeMillis();
       if(logger.isInfoEnabled()){
         logger.info("around " + joinPoint + "\tUse time : " + (end - start) + " ms with exception : " + e.getMessage());
       }
     }
   }
  
  /**
   * 后置通知 用于攔截Controller層記錄用戶的操作
   *
   * @param joinPoint 切點
   */
  @After("controllerAspect()")
  public void after(JoinPoint joinPoint) {
 
    /* HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
    HttpSession session = request.getSession(); */
    //讀取session中的用戶
    // User user = (User) session.getAttribute("user");
    //請求的IP
    //String ip = request.getRemoteAddr();
    User user = new User();
    user.setId(1);
    user.setName("張三");
    String ip = "127.0.0.1";
     try {
      
      String targetName = joinPoint.getTarget().getClass().getName();
      String methodName = joinPoint.getSignature().getName();
      Object[] arguments = joinPoint.getArgs();
      Class targetClass = Class.forName(targetName);
      Method[] methods = targetClass.getMethods();
      String operationType = "";
      String operationName = "";
       for (Method method : methods) {
         if (method.getName().equals(methodName)) {
          Class[] clazzs = method.getParameterTypes();
           if (clazzs.length == arguments.length) {
             operationType = method.getAnnotation(Log.class).operationType();
             operationName = method.getAnnotation(Log.class).operationName();
             break;
          }
        }
      }
      //*========控制臺輸出=========*//
      System.out.println("=====controller后置通知開始=====");
      System.out.println("請求方法:" + (joinPoint.getTarget().getClass().getName() + "." + joinPoint.getSignature().getName() + "()")+"."+operationType);
      System.out.println("方法描述:" + operationName);
      System.out.println("請求人:" + user.getName());
      System.out.println("請求IP:" + ip);
      //*========數據庫日志=========*//
      SystemLog log = new SystemLog();
      log.setId(UUID.randomUUID().toString());
      log.setDescription(operationName);
      log.setMethod((joinPoint.getTarget().getClass().getName() + "." + joinPoint.getSignature().getName() + "()")+"."+operationType);
      log.setLogType((long)0);
      log.setRequestIp(ip);
      log.setExceptioncode( null);
      log.setExceptionDetail( null);
      log.setParams( null);
      log.setCreateBy(user.getName());
      log.setCreateDate(new Date());
      //保存數據庫
      systemLogService.insert(log);
      System.out.println("=====controller后置通知結束=====");
    } catch (Exception e) {
      //記錄本地異常日志
      logger.error("==后置通知異常==");
      logger.error("異常信息:{}", e.getMessage());
    }
  }
  
  //配置后置返回通知,使用在方法aspect()上注冊的切入點
   @AfterReturning("controllerAspect()")
   public void afterReturn(JoinPoint joinPoint){
     System.out.println("=====執行controller后置返回通知=====");
       if(logger.isInfoEnabled()){
         logger.info("afterReturn " + joinPoint);
       }
   }
  
  /**
   * 異常通知 用于攔截記錄異常日志
   *
   * @param joinPoint
   * @param e
   */
   @AfterThrowing(pointcut = "controllerAspect()", throwing="e")
   public void doAfterThrowing(JoinPoint joinPoint, Throwable e) {
    /*HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
    HttpSession session = request.getSession();
    //讀取session中的用戶
    User user = (User) session.getAttribute(WebConstants.CURRENT_USER);
    //獲取請求ip
    String ip = request.getRemoteAddr(); */
    //獲取用戶請求方法的參數并序列化為JSON格式字符串
    
    User user = new User();
    user.setId(1);
    user.setName("張三");
    String ip = "127.0.0.1";
    
    String params = "";
     if (joinPoint.getArgs() != null && joinPoint.getArgs().length > 0) {
       for ( int i = 0; i < joinPoint.getArgs().length; i++) {
        params += JsonUtil.getJsonStr(joinPoint.getArgs()[i]) + ";";
      }
    }
     try {
       
       String targetName = joinPoint.getTarget().getClass().getName();
       String methodName = joinPoint.getSignature().getName();
       Object[] arguments = joinPoint.getArgs();
       Class targetClass = Class.forName(targetName);
       Method[] methods = targetClass.getMethods();
       String operationType = "";
       String operationName = "";
       for (Method method : methods) {
         if (method.getName().equals(methodName)) {
           Class[] clazzs = method.getParameterTypes();
           if (clazzs.length == arguments.length) {
             operationType = method.getAnnotation(Log.class).operationType();
             operationName = method.getAnnotation(Log.class).operationName();
             break;
           }
         }
       }
       /*========控制臺輸出=========*/
      System.out.println("=====異常通知開始=====");
      System.out.println("異常代碼:" + e.getClass().getName());
      System.out.println("異常信息:" + e.getMessage());
      System.out.println("異常方法:" + (joinPoint.getTarget().getClass().getName() + "." + joinPoint.getSignature().getName() + "()")+"."+operationType);
      System.out.println("方法描述:" + operationName);
      System.out.println("請求人:" + user.getName());
      System.out.println("請求IP:" + ip);
      System.out.println("請求參數:" + params);
        /*==========數據庫日志=========*/
      SystemLog log = new SystemLog();
      log.setId(UUID.randomUUID().toString());
      log.setDescription(operationName);
      log.setExceptioncode(e.getClass().getName());
      log.setLogType((long)1);
      log.setExceptionDetail(e.getMessage());
      log.setMethod((joinPoint.getTarget().getClass().getName() + "." + joinPoint.getSignature().getName() + "()"));
      log.setParams(params);
      log.setCreateBy(user.getName());
      log.setCreateDate(new Date());
      log.setRequestIp(ip);
      //保存數據庫
      systemLogService.insert(log);
      System.out.println("=====異常通知結束=====");
    } catch (Exception ex) {
      //記錄本地異常日志
      logger.error("==異常通知異常==");
      logger.error("異常信息:{}", ex.getMessage());
    }
     /*==========記錄本地異常日志==========*/
    logger.error("異常方法:{}異常代碼:{}異常信息:{}參數:{}", joinPoint.getTarget().getClass().getName() + joinPoint.getSignature().getName(), e.getClass().getName(), e.getMessage(), params);
 
  }
  
}

我這里寫的比較全,前置通知,環繞通知,后置通知,異常通知,后置飯后通知,都寫上了,在我們實際編寫中不寫全也沒事,我習慣上把記錄日志的邏輯寫在后置通知里面,我看網上也有些在前置通知里面的,但我感覺寫在后置通知里比較好。

下面開始在controller中加入自定義的注解!!

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package com.gcx.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import com.gcx.annotation.Log;
import com.gcx.service.UserService;
@Controller
@RequestMapping("userController")
public class UserController {
  @Autowired
  private UserService userService;
  
  @RequestMapping("testAOP")
  @Log(operationType="add操作:",operationName="添加用戶")
  public void testAOP(String userName,String password){   
    userService.addUser(userName, password);
  }
}

下面編寫測試類

?
1
2
3
4
5
6
7
8
@Test
  public void testAOP1(){
    //啟動Spring容器   
    ApplicationContext ctx = new ClassPathXmlApplicationContext(new String[]{"classpath:applicationContext-mvc.xml","classpath:applicationContext-dataSource.xml"});
    //獲取service或controller組件
    UserController userController = (UserController) ctx.getBean("userController");
    userController.testAOP("zhangsan", "123456");
  }

spring AOP自定義注解方式實現日志管理的實例講解

數據庫數據:

spring AOP自定義注解方式實現日志管理的實例講解

我原本想寫兩個切點,一個是service層,一個是controller層,service層是用來記錄異常信息的日志,而controller層的是用來記錄功能的日志,運行結果如下。 spring AOP自定義注解方式實現日志管理的實例講解

這樣做的話不知道在實際的項目中運行效率好不好,在這里請看到博客的大牛給點建議!!

以上這篇spring AOP自定義注解方式實現日志管理的實例講解就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支持服務器之家。

原文鏈接:http://www.cnblogs.com/jianjianyang/p/4910851.html

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 500福利第一巨人导航 | 亚洲第成色999久久网站 | 色综合伊人色综合网站中国 | 小鸟酱在线播放 | 疯狂伦交1一6小说 | h动态图男女啪啪27报 | 手机在线观看精品国产片 | 国产午夜精品久久理论片小说 | 天选之王漫画顾长歌免费阅读 | 人禽l交视频在线播放 视频 | 日本免费的一级绿象 | 国产有码在线 | 成成人看片在线 | 国产精品合集一区二区 | 扒开斗罗美女了的胸罩和内裤漫画 | 2021国产精品露脸在线 | 日韩精品一区二区三区视频 | www亚洲色图 | 欧美国产日韩综合 | 国产成人影院一区二区 | 欧美va天堂va视频va在线 | 国产成人8x视频一区二区 | 狠狠色婷婷 | 久久精品手机观看 | 国产欧美日韩精品高清二区综合区 | 国产高清国内精品福利 | 肥胖老寡妇做性 | 国产欧美曰韩一区二区三区 | 日本午夜色 | free性欧洲| 国产成人在线免费视频 | 男人综合网 | 日韩 国产 欧美 精品 在线 | 91青青视频| 草大逼 | 午夜国产精品视频 | 欧美成人momandson | 掀开奶罩边躁狠狠躁软学生 | 免费观看www视频 | 日韩精品成人 | 99精品在线 |