3.10——统一记录日志

AOP的概念

Aspect Oriented Programing即面向切面编程,AOP是一种编程思想,是对OOP的补充,可以进一步提高编程的效率。

AOP的术语:
JoinPoint:Target上切入的点
Aspect:Pointcut和Advice

Weaving:
在编译时织入,需要使用特殊的编译器。
装载时编入,需要特殊的类加载器。
运行时编入,需要为目标生成代理对象。

AOP的实现

AspectJ是语言级的实现,它扩展了Java语言,定义了AOP语法,AspectJ在编译期织入代码,它有一个专门的编译器,用来生成遵守Java字节码的规范的class文件。

SpringAOP使用纯Java实现,它不需要专门的编译过程,也不需要特数的类装载器。SpringAOP在运行期间通过代理的方式织入代码,只支持方法的连接点。Spring支持对AspectJ的集成。

Spring AOP

JDK动态管理:
Java提供的动态代理技术,可以在运行时创建接口的实现代理示例,SpringAOP默认采用这种方式,在接口的代理实现中织入代码。
CGLib动态代理:
采用底层的字节码技术,在运行时创建子类代理实例。当目标对象不存在接口的时,Spring AOP会采用这种方式,在子类实例中织入代码。

在Aspect包下的ServiceLogAspect上

@Component
@Aspect
public class ServiceLogAspect {

    private static final Logger logger = LoggerFactory.getLogger(ServiceLogAspect.class);

    @Pointcut("execution(* com.nowcoder.community.service.*.*(..))")
    public void pointcut() {

    }

    @Before("pointcut()")
    public void before(JoinPoint joinPoint) {
        // 用户[1.2.3.4],在[xxx],访问了[com.nowcoder.community.service.xxx()].
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        String ip = request.getRemoteHost();
        String now = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
        String target = joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName();
        logger.info(String.format("用户[%s],在[%s],访问了[%s].", ip, now, target));
    }

}

你可能感兴趣的:(3.10——统一记录日志)