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

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

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

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 国产成人精品日本亚洲网站 | 日本大片在线 | 国产成年人网站 | 免费亚洲视频在线观看 | 性欧美xxxxx老太婆 | 精品精品国产自在久久高清 | 九九精品免视看国产成人 | 久久精品国产清白在天天线 | 好湿好紧好多水c | 欧洲美女女同 | 久久精品成人免费看 | 亚洲精品视频专区 | av毛片免费看 | h版小说| 国产综合视频在线 | 日本老妇和子乱视频 | 久久国产免费 | 日本亚洲免费 | 女人爽到喷水的视频免费 | 日韩成人在线网站 | 日本捏胸吃奶视频免费 | 四虎黄色影视库 | 日韩一级片在线播放 | 精品国产自在现线久久 | 十八女下面流水不遮免费 | 欧美区一区 | 欧美zoosex| 久久成人精品免费播放 | 国产91精品在线播放 | 荡娃艳妇系列小说 | 九九精品免费视频 | 亚洲欧美精品久久 | 精品国产福利片在线观看 | 午夜国产小视频 | 国产v日韩v欧美v精品专区 | 国产一区二区三区免费在线视频 | 婷婷综合在线 | 好大好硬好深好爽想要吃奶 | 免费观看视频高清在线 | 美女脱一光二净的视频 | h肉动漫在线视频无修无遮挡 |