激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

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

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

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 久久国产精品影视 | 午夜伦情电午夜伦情电影 | 久久综合九色综合久久久精品综合 | 成人国产精品一区二区毛片在线 | 一级毛片在线免费观看视频 | 国产色妞影院wwwxxx | 黄色免费视频网站 | 国产九九热视频 | 日本精品视频一区二区三区四区 | 午夜小电影 | 欧美精品v国产精品v日韩精品 | 久久精品久久精品国产大片 | 98国内自拍在线视频 | 免费在线观看成人av | 欧美日韩国产一区二区三区在线观看 | 一级电影免费看 | 国产亚洲精品久久久久婷婷瑜伽 | 亚洲综合色视频在线观看 | 精品亚洲一区二区三区 | av在线网站观看 | 一级成人免费 | 日日狠狠久久偷偷四色综合免费 | 国产免费一区二区三区网站免费 | 色视频91 | 久久吊| 成年人在线免费 | 国产在线精品一区二区三区不卡 | 看黄在线 | 欧美一级高潮片免费的 | 成人免费网站在线观看视频 | 9191久久久久视频 | 日韩在线视频免费播放 | 亚洲日本欧美 | 黄色羞羞 | 久久久新| 国产精品九九久久一区hh | av懂色| 国产91精品久久久 | 中国fx性欧美xxxx | 少妇一级淫片免费放4p | 日韩精品dvd |