@Aspect注解将表示它是一个切面
@Component表示它是一个Spring的组件
切片Aspect,既然Spring那么支持AOP,就肯定都能拿。有人会问如何拿原始的HTTP请求和响应的信息,通过以下代码应该拿得到啊哈哈哈哈
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();
<aop:config>
<!-- order:指定切面bean的优先级,值越小,优先级越高 -->
<aop:aspect id="fourAdviceAspect" ref="fourAdviceBean" order="2">
<aop:around method="processTask" pointcut="execution(* com.wangjun.aop.xml.*.*(..))"/>
<aop:before method="authority" pointcut="execution(* com.wangjun.aop.xml.*.*(..))"/>
<aop:after-returning method="log" returning="rvt" pointcut="execution(* com.wangjun.aop.xml.*.*(..))"/>
</aop:aspect>
</aop:config>
其中aop:aspect/标签就是切面,此标签下面的aop:around/、aop:before/这些就是增强处理,那么在哪里进行增强处理呢?pointcut属性就定义了切入点,也就是在哪里进行增强处理。这里的表达式比如execution(* com.wangjun.aop.xml..(..))含义如下:
指定在com.wangjun.aop.xml包中任意类方法;
第一个表示返回值不限,第二个表示类名不限;
第三个*表示方法名不限,圆括号中的(..)表示任意个数、类型不限的形参。
使用场景
日志记录、审计、声明式事务、安全性和缓存等。
AspectJ和Spring AOP的区别
正好代表了实现AOP的两种方式:
AspectJ是静态实现AOP的,即在编译阶段对程序进行修改,需要特殊的编译器,具有较好的性能;
Spring AOP是动态实现AOP的,即在运行阶段动态生成AOP代理,纯java实现,因此无需特殊的编译器,但是通常性能较差。
案例:记录日志
业务日志表
package chin.common;
/**
* 操作类型枚举
*/
public enum OpearteType {
QUERY("检索","QUERY"),
CREATE("录入","CREATE"),
UPDATE("维护","UPDATE"),
DELETE("删除","DELETE"),
REVIEW("审核","REVIEW"),;
private String name;
private String code;
private OpearteType(String name, String code) {
this.name = name;
this.code = code;
}
public static String getName(String code) {
for (OpearteType c : OpearteType.values()) {
if (c.getCode().equals(code)) {
return c.name;
}
}
return null;
}
public static String getCode(String name) {
for (OpearteType c : OpearteType.values()) {
if (c.getName().equals(name)) {
return c.code;
}
}
return null;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
}
package chin.annotation;
import chin.common.BusinessModule;
import java.lang.annotation.*;
/**
* 业务模块注解
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(value = ElementType.TYPE)
public @interface BusinessModuleAttributes {
BusinessModule businessModule();
}
package chin.annotation;
import chin.common.OpearteType;
import java.lang.annotation.*;
/**
* 业务日志注解
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(value = ElementType.METHOD)
public @interface BusinessLogAttributes {
OpearteType opearteType();
String opearteDescription();
}
package chin.aspect;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.beyondbit.ias.core.base.BaseController;
import com.beyondbit.ias.core.util.IPUtil;
import chin.annotation.BusinessLogAttributes;
import chin.annotation.BusinessModuleAttributes;
import chin.entity.BusinessLog;
import chin.service.BusinessLogService;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.ui.Model;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;
import java.util.Date;
/**
* 业务日志切面
*/
@Aspect
@Component
public class BusinessLogAspect extends BaseController {
@Autowired
private BusinessLogService businessLogService;
@Pointcut("@annotation(chin.annotation.BusinessLogAttributes)")
public void logPointCut() {
}
@Around("logPointCut()")
public Object around(ProceedingJoinPoint point) throws Throwable {
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
BusinessModuleAttributes moduleAttributes = point.getTarget().getClass().getAnnotation(BusinessModuleAttributes.class);
MethodSignature signature = (MethodSignature) point.getSignature();
Method method = signature.getMethod();
BusinessLogAttributes logAttributes = method.getAnnotation(BusinessLogAttributes.class);
//获取请求参数:
MethodSignature ms = (MethodSignature) point.getSignature();
//获取请求参数类型
String[] parameterNames = ms.getParameterNames();
//获取请求参数值
Object[] parameterValues = point.getArgs();
StringBuilder strParams = new StringBuilder();
//组合请求参数,进行日志打印
if (parameterNames != null && parameterNames.length > 0) {
for (int i = 0; i < parameterNames.length; i++) {
if (parameterNames[i].equals("bindingResult")) {
break;
}
if ((parameterValues[i] instanceof HttpServletRequest) || (parameterValues[i] instanceof HttpServletResponse)||(parameterValues[i] instanceof Model)||(parameterValues[i] instanceof MultipartFile)) {
strParams.
append("[").
append(parameterNames[i]).append("=").append(parameterValues[i])
.append("]");
} else {
try
{
strParams.
append("[").
append(parameterNames[i]).append("=")
.append(JSON.toJSONString(parameterValues[i], SerializerFeature.WriteDateUseDateFormat))
.append("]");
}
catch(Throwable throwable){
strParams.
append("[").
append(parameterNames[i]).append("=").append(parameterValues[i])
.append("]");
}
}
}
}
Object result = null;
BusinessLog log = new BusinessLog();
log.setUuid(java.util.UUID.randomUUID().toString());
log.setClientIP(IPUtil.getClientIp(request));
log.setBusinessModule(moduleAttributes.businessModule().getCode());
log.setOpearteType(logAttributes.opearteType().getCode());
log.setOpearteDescription(logAttributes.opearteDescription());
log.setOpeartor(super.getCurrentUser().getUserUid());
log.setOpeartorName(super.getCurrentUser().getName());
log.setOpearteDateTime(new Date());
log.setReqUrl(request.getRequestURL().toString());
log.setClazz(point.getTarget().getClass().getName());
log.setMethod(method.getName());
log.setParams(strParams.toString());
try {
// 执行方法
result = point.proceed();
log.setStatus("1");
} catch (Exception e) {
log.setStatus("0");
log.setException(e.getStackTrace().toString());
throw e;
} finally {
businessLogService.insertBusinessLog(log);
}
return result;
}
}