OA專案(使用Spring AOP 給執行方法新增日誌功能)
Spring AOP 實現有兩種:
①、基於代理類 ProxyFactoryBean 的 AOP 實現
②、AOP 配置方式實現 (本教程採用第二種)
本教程的目的:
原來搭建的 SSH2 + log4j 框架中,列印輸出的日誌資訊很單一,基本上只有執行的 SQL 語句,無法滿足我們的需求
所以就想到 使用 Spring AOP 技術完成日誌功能,在使用這個技術後我們可以
①、記錄每個方法執行的時間,從而為後面優化我們的程式
②、記錄什麼時間,誰做了什麼,從而完成審計功能
③、記錄自定義的異常資訊
一、編寫 java 類
package cn.oa.aop;
import org.apache.log4j.Logger;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
public class AllLogAdvice {
private Logger logger = Logger.getLogger(AllLogAdvice.class);
//前置通知,方法執行之前執行
public void myBeforeAdvice(JoinPoint jionpoint) {
// 獲取被呼叫的類名
String targetClassName = jionpoint.getTarget().getClass().getName();
// 獲取呼叫的方法名
String targetMethodName = jionpoint.getSignature().getName();
// 日誌格式 字串
String logInfoText = "前置通知" + targetClassName + " 類的 " + targetMethodName + " 方法開始執行........";
logger.info(logInfoText);
}
//後置通知,方法執行之後執行(不管是否發生異常)
public void myAfterReturnAdvice(JoinPoint jionpoint) {
// 獲取被呼叫的類名
String targetClassName = jionpoint.getTarget().getClass().getName();
// 獲取呼叫的方法名
String targetMethodName = jionpoint.getSignature().getName();
// 日誌格式 字串
String logInfoText = "後置通知" + targetClassName + " 類的 " + targetMethodName + " 方法執行完畢........";
logger.info(logInfoText);
}
// 異常通知
public void myThrowingAdvice(JoinPoint jionpoint, Exception e) {
// 獲取被呼叫的類名
String targetClassName = jionpoint.getTarget().getClass().getName();
// 獲取呼叫的方法名
String targetMethodName = jionpoint.getSignature().getName();
// 日誌格式 字串
String logInfoText = "異常通知:執行 " + targetClassName + " 類的 " + targetMethodName + " 方法 傳送異常......." + "異常資訊:" + e.getMessage();
logger.info(logInfoText);
}
// 環形通知
public void myAroundAdvice(ProceedingJoinPoint jionpoint) throws Throwable {
long beginTime = System.currentTimeMillis();
jionpoint.proceed();
long endTime = System.currentTimeMillis();
// 獲取被呼叫的類名
String targetClassName = jionpoint.getTarget().getClass().getName();
// 獲取呼叫的方法名
String targetMethodName = jionpoint.getSignature().getName();
// 日誌格式 字串
String logInfoText = "環形通知:執行 " + targetClassName + " 類的 " + targetMethodName + " 方法 用時......." + (endTime - beginTime);
logger.info(logInfoText);
}
}
二、編輯 spring 配置檔案
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<!-- 自動掃描與裝配bean -->
<context:component-scan base-package="cn.oa"></context:component-scan>
<!-- 載入外部的properties配置檔案 -->
<context:property-placeholder location="classpath:jdbc.properties" />
<!-- 配置資料庫連線池(c3p0) -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<!-- 基本資訊 -->
<property name="jdbcUrl" value="${jdbcUrl}"></property>
<property name="driverClass" value="${driverClass}"></property>
<property name="user" value="${username}"></property>
<property name="password" value="${password}"></property>
<!-- 其他配置 -->
<!--初始化時獲取三個連線,取值應在minPoolSize與maxPoolSize之間。Default: 3 -->
<property name="initialPoolSize" value="3"></property>
<!--連線池中保留的最小連線數。Default: 3 -->
<property name="minPoolSize" value="3"></property>
<!--連線池中保留的最大連線數。Default: 15 -->
<property name="maxPoolSize" value="5"></property>
<!--當連線池中的連線耗盡的時候c3p0一次同時獲取的連線數。Default: 3 -->
<property name="acquireIncrement" value="3"></property>
<!-- 控制資料來源內載入的PreparedStatements數量。如果maxStatements與maxStatementsPerConnection均為0,則快取被關閉。Default:
0 -->
<property name="maxStatements" value="8"></property>
<!-- maxStatementsPerConnection定義了連線池內單個連線所擁有的最大快取statements數。Default:
0 -->
<property name="maxStatementsPerConnection" value="5"></property>
<!--最大空閒時間,1800秒內未使用則連線被丟棄。若為0則永不丟棄。Default: 0 -->
<property name="maxIdleTime" value="1800"></property>
</bean>
<!-- 配置SessionFactory -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property>
<property name="configLocation" value="classpath:hibernate.cfg.xml"></property>
</bean>
<!-- 配置宣告式的事務管理(採用基於註解的方式) -->
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"></property>
</bean>
<tx:annotation-driven transaction-manager="transactionManager" />
<!-- 新增日誌處理 -->
<bean id="allLogAdvice" class="cn.oa.aop.AllLogAdvice"></bean>
<aop:config>
<aop:aspect id="logaop" ref="allLogAdvice">
<aop:pointcut expression="execution(* cn.oa.action.*.* (..)) and !execution(* cn.oa.action.*.set* (..))" id="logpointcut"/>
<aop:before method="myBeforeAdvice" pointcut-ref="logpointcut" />
<aop:after-returning method="myAfterReturnAdvice" pointcut-ref="logpointcut" />
<aop:after-throwing method="myThrowingAdvice" pointcut-ref="logpointcut" throwing="e"/>
<aop:around method="myAroundAdvice" pointcut-ref="logpointcut" />
</aop:aspect>
</aop:config>
</beans>
PS: ①、新增了日誌處理的 aop
②、修改bean 的頭部名稱空間
③、切入點表示式:選擇 cn.oa.action 包中所有類的所有方法(但排除 set 方法外),做日誌記錄
三、將所有的 action 類取消 繼承 ActionSupport 類
至於為什麼選擇取消 繼承 ActionSupport 類?
我發現, 繼承 ActionSupport 類,當客戶端發出請求時,沒有繼承 ActionSupport 類的方法正常執行,而繼承 ActionSupport 類的Action 會報異常:java.lang.NoSuchMethodException: com.sun.proxy
相關文章
- 我使用Spring AOP實現了使用者操作日誌功能Spring
- Spring AOP代理執行解析Spring
- 是否可以使用資料質量工具執行MDM專案OA
- 專案裡多執行緒常用姿勢,很給力的使用方法執行緒
- 新增日誌檔案組與日誌檔案成員
- Spring Aop的執行順序Spring
- 如何執行Spring Boot專案Spring Boot
- 某知名OA命令執行方法探索(續)
- AOP行為日誌
- Spring 使用Aop 做切面日誌,和許可權。Spring
- 溫故知新——Spring AOPSpring
- Spring Boot 入門(五):整合 AOP 進行日誌管理Spring Boot
- 新增日誌組以及調整日誌的大小
- iOS 檢視及匯出專案執行日誌iOS
- springboot下新增日誌模組和設定日誌檔案輸出Spring Boot
- spring-boot-route(十七)使用aop記錄操作日誌Springboot
- Spring Boot 專案配置的使用方法Spring Boot
- 溫故知新——Spring AOP(二)Spring
- Spring系列.AOP使用Spring
- 使用Node.js執行Cesium專案Node.js
- 使用Cordova執行專案到androidAndroid
- Spring Boot實際專案用簡單的AOPSpring Boot
- Java專案計算程式執行時間方法Java
- 軟體工程實踐專案學習與執行日誌軟體工程
- Spring AOP 實現業務日誌記錄Spring
- Spring AOP快速使用教程Spring
- linux伺服器部署SpringBoot專案並檢視專案執行日誌Linux伺服器Spring Boot
- 如何制定專案執行計劃的幾種方法
- 如何執行vue專案Vue
- 新晉總監生存指南四——專案執行指南,如何挽救混亂的專案
- spring3.0.5的aop使用Spring
- Spring(4)-AOP使用細節Spring
- OA專案-虛擬機器上部署專案虛擬機
- spring boot 執行sql檔案Spring BootSQL
- OPMS專案管理+OA系統專案管理
- 新藥研發專案管理方案:PM專案提供製藥行業四大功能專案管理行業
- Spring Boot利用AOP獲取使用者操作實現日誌記錄Spring Boot
- Spring AOP實現統一日誌輸出Spring