aop是spring框架的兩大核心之一,即面向切面編程,它是對oo編程的補充。那麼spring aop在實際項目開發中有什麼作用呢?它最大的作用就是完成日誌記錄,一個簡單的例子,你在ATM上取款系統是會記錄下來一些信息的,比如取款時間、銀行卡號、ATM位置、等等。不管是一般還是不一般的項目,應該來說,只要是敏感的數據,只要用戶對它進行操作了,牽扯到數據庫了,系統都應該以日誌的形式記錄下來。有日誌記錄功能,當用戶對數據進行“非法”操作的時候,spring aop會很容易幫你找到當事人。
使用spring aop開發日誌管理相當常見,現在幾乎可以說每個業務系統都需要有日誌管理模塊,有的叫審計,間接地和安全掛上了鉤。
1、定義Log實體
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name = "SYS_LOG")
public class Log {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "ID", unique = true, nullable = false)
private Integer id;
/**
* 操作賬戶
* */
@Column(name = "USERUID")
private String useruid;
/**
* 操作用戶名稱
* */
@Column(name = "USERNAME")
private String username;
/**
* 操作位置
* */
@Column(name = "OPPOSIT")
private String opposit;
/**
* 操作內容
* */
@Column(name = "OPCONT")
private String opcont;
/**
* 操作時間
* */
@Column(name = "CREATETIME")
private Date createtime;
//setters and getters
}
2、自定義註解AnnotationLog
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface AnnotationLog {
/**
* 功能說明:日誌名
* @return
*/
String name() default "";
/**
* 功能說明:日誌描述
* @return
*/
String description() default "";
}
其中@Target等4個註解的作用
3、實現AOPLog
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import com.onenzg.common.hibernate.HibernateDAO;
import com.onezg.common.log.domain.Log;
import com.onezg.common.log.service.LogService;
import com.onezg.sys.usermanage.domain.UserInfo;
import com.onezg.sys.usermanage.services.UserServices;
public class AopLog extends HibernateDAO<Log> {
/**
* 引入LogService
*/
@Autowired
private LogService logservice;
@Autowired
private UserServices userServices;
/**
* 功能說明:輸出log信息
*/
public void writeLogInfo(JoinPoint point) throws Throwable {
Method method = ((MethodSignature) point.getSignature()).getMethod();
AnnotationLog ann = method.getAnnotation(AnnotationLog.class);
if (ann != null) {
UserInfo cui = userServices.getCurrentUser();
if (null != cui) {
Map<String, Object> map = new HashMap<String, Object>();
map.put("uid", cui.getuId());
map.put("givenName", cui.getuName());
logservice.insertLog(ann.name(), ann.description(), map);
}
}
}
}
4、LogDAO和LogDAOImpl
import java.util.Map;
public interface LogDao {
/**
* 功能說明:AOP保存日誌信息
* @param strLocation 參數
* @param strContent 參數
* @param userInfo 要保存的信息集合
*/
void insertLog(String strLocation, String strContent, @SuppressWarnings("rawtypes") Map userInfo);
}
import java.util.Date;
import java.util.Map;
import org.springframework.stereotype.Repository;
import com.onezg.common.exception.DatabaseException;
import com.onezg.common.hibernate.HibernateDAO;
import com.onezg.common.log.dao.LogDao;
import com.onezg.common.log.domain.Log;
@Repository(value = "logdao")
public class LogDaoImpl extends HibernateDAO<Log> implements LogDao {
@SuppressWarnings("rawtypes")
@Override
public void insertLog(String strLocation, String strContent, Map userInfo) {
//useruid
String useruid = String.valueOf(userInfo.get("uid"));
//username, 操作賬戶.
String userName = String.valueOf(userInfo.get("givenName"));
//opposit, 操作位置.
String opposit = strLocation;
//opcont, 操作內容.
String opcont = strContent;
try {
Log log = new Log(); //bean對象
//封裝bean數據處理
log.setUseruid(useruid);
log.setUsername(userName);
log.setOpposit(opposit);
log.setOpcont(opcont);
log.setCreatetime(new Date());
//保存對象
this.save(log);
} catch (Exception ex) {
throw new DatabaseException("插入登錄日誌失敗", ex.getMessage());
}
}
}
5、配置文件寫spring aop配置,本人例子是在Spring-context.xml裏寫配置
<!-- Aop配置——開始 -->
<aop:config proxy-target-class="true">
<aop:aspect id="goLogAspect" ref="AfterReturningAdvice">
<aop:pointcut id="actionPointcut" expression="within(com.onezg..*)" />
<aop:before pointcut-ref="actionPointcut" method="writeLogInfo" />
</aop:aspect>
</aop:config>
<beans:bean id="AfterReturningAdvice" class="com.onezg.common.aop.AopLog"></beans:bean>
<!-- Aop配置——結束 -->
6、使用註解
@AnnotationLog(name = "用戶管理", description = "修改用戶")
@RequestMapping(value = "/userupdate")
public void getUserUpdate(HttpSession session, HttpServletRequest request, HttpServletResponse response,
Model model, UserInfoDTO dto) {
try {
userServices.updateUser(dto);
} catch (Exception e) {
throw new ParameterException("用戶修改失敗", e.getMessage());
}
}
到這裏,使用spring aop完成日誌記錄就結束了。