環境:dubbo 下的ssm框架
1.AOP切面代碼(web層)

@Aspect @Component public class LogAopController { @Autowired private HttpServletRequest request; //需要在web.xml配置
@Reference //注意不同的項目下不能使用@Autowired 要是用@Reference
private ISysLogService service; private Date visitTime;//5開始時間
private Class clazz;//6訪問的類
private Method method;//7訪問的方法 /* 1如何獲取操作者? * 2如何獲取訪問的ip * 3如何獲取訪問的url * 4如何獲取執行的時長 */
//前置通知,主要獲取開始時間,執行的類是哪一個,執行了哪個方法
@Before("execution(* com.qingcheng.controller.goods.SpuController.*(..))")//.*是包下的所有類 .*是類下的所有方法
public void doBefore(JoinPoint jp) throws NoSuchMethodException { visitTime=new Date();//當前時間就是開始的時間
clazz=jp.getTarget().getClass();//獲取類
String methodName=jp.getSignature().getName();//只能獲取方法的名字
Object[] args = jp.getArgs();//獲取訪問的方法參數 //獲取具體的方法對象
if (args == null||args.length == 0){ //無參數
method=clazz.getMethod(methodName); //根據方法的名字,只能獲取無參數的方法
}else { //有參數
Class[] classArgs=new Class[args.length]; for (int i=0;i<args.length;i++){ classArgs[i]=args[i].getClass();//把方法的每個參數都存入到數組中
} method=clazz.getMethod(methodName,classArgs); } } //后置通知
@After("execution(* com.qingcheng.controller.goods.SpuController.*(..))") public void doAfter(JoinPoint jp){ //4如何獲取執行的時長?
String time= String.valueOf(new Date().getTime()-visitTime.getTime()); //3如何獲取訪問的url
String url=""; if(clazz!=null&&method!=null&&clazz!= LogAopController.class){ //獲取url @RequestMapping("/findAll.do") //子類 對象名= (子類) 父類; 強制轉換 將父類對象賦予子類對象需要強制轉換為子類對象(小知識點!!!!)
RequestMapping classAnnotation = (RequestMapping) clazz.getAnnotation(RequestMapping.class); if(classAnnotation!=null){ //1.獲取類上的路徑
String[] classValue=classAnnotation.value(); //2.獲取方法上的路徑
RequestMapping methodAnnotation = method.getAnnotation(RequestMapping.class); if (methodAnnotation!=null){ String[] methodValue = methodAnnotation.value();//獲取了方法上的路徑 //類路徑+方法路徑
url=classValue[0]+methodValue[0]; } } } //如何獲取2如何獲取訪問的ip //1.配置web.xml 獲取HttpServletRequest 2.注入依賴獲取request對象
String ip = request.getRemoteAddr(); ///獲取ip //封裝信息
Syslog syslog=new Syslog(); UUID uuid = UUID.randomUUID(); syslog.setId(uuid.toString());//1
syslog.setExecutionTime(time);//2
syslog.setIp(ip);//3
syslog.setMethod("[類]"+clazz.getName()+"[方法]"+method.getName());//4
syslog.setUrl(url);//5
syslog.setUsername("TEST");//6
syslog.setVisitTime(visitTime);//7
System.out.println(syslog); service.saveLog(syslog); } }
2.配置mvc的xml文件
<context:component-scan base-package="掃描包路徑"/>
<aop:aspectj-autoproxy proxy-target-class="true"/> <!-- 支持AOP的注解支持,AOP底層使用代理技術-->
3.web層的查詢日志代碼

@RestController @RequestMapping("/spuLog") public class LogSpuController { @Reference private ISysLogService spuService; @GetMapping("findAll") public List<Syslog> findAll(){ return spuService.findAll(); } }
4.pojo

@Table(name = "tb_syslog") public class Syslog implements Serializable { @Id private String id; private Date visitTime; private String visitTimestr; //注意 visitTimestr 設計數據庫字段為visit_timestr Mapper才會識別
private String username; private String ip; private String url; private String executionTime; private String method; }
5.service接口
public interface ISysLogService { public void saveLog(Syslog syslog); //保存日志 List<Syslog> findAll();//查詢所有日志
}
6.service層下的dao (使用的通用mapper)
public interface ISysLogMapper extends Mapper<Syslog> { }
7.service層下的接口實現
@Service public class ISysLogServiceImpl implements ISysLogService { @Autowired private ISysLogMapper iSysLogMapper; public void saveLog(Syslog syslog) {//保存日志
iSysLogMapper.insert(syslog);//當mysql數據庫設置默認值時,如果使用insert插入會把字段為空的值也插入到數據庫,所以數據庫設置的默認值也沒用
} public List<Syslog> findAll() { return iSysLogMapper.selectAll(); } }
切面配置好后會顯示m->
8.測試