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完成日志记录就结束了。