9、统一记录日志(AOP)

1、AOP

AOP,即面向切面编程,切面是一个一个组件。业务Bean是一个一个target。我们要先声明切点的位置,再通知要做什么事。只需要对切面组件编程即可,不需要再进到业务Bean中取改,提高了编程效率。
9、统一记录日志(AOP)_第1张图片
框架为切面提供了织入的功能,有编译时(运行快),类装载,运行时织入(慢些)。
Aspect切面:

  • 注解@Component @Aspect
  • 声明切点的位置@Pointcut(切点的位置:返回值 包.类.方法.参数) pointcut()
  • 通知具体逻辑,5个注解@Before @After AfterReturning @AfterThrowing @Around
    Target: 是业务Bean
    9、统一记录日志(AOP)_第2张图片
    AOP实现的两种方式:
    AspectJ和Spring AOP。一般用后者,它是运行时织入,通过代理的方式,只在方法处有连接点。

Spring AOP有两种动态代理方式:
**为什么要代理:**在织入切面代码时,不在原来的实例中织入,而是在代理对象中织入。调用时也是掉哟个代理对象,而不是调用原始对象。容器调用对象,如果有AOP作用,就调用代理对象。

JDK动态代理(自带的)和CGLib动态代理(第三方)。前者生成接口的实现类,在代理实例中织入,要求必须有业务接口;后者在业务不存在接口时,创建子类实例以实现代理。

2、使用演示

AlphaAspect

//@Component
//@Aspect
public class AlphaAspect {

    // 切点:返回值 包 类 方法 参数
    @Pointcut("execution(* com.nowcoder.community.service.*.*(..))")
    public void pointcut() {

    }

    // 通知:连接点前、后、返回值、抛异常、连接点前后。
    @Before("pointcut()")// 针对该切点pointcut()
    public void before() {
        System.out.println("before");
    }

    @After("pointcut()")
    public void after() {
        System.out.println("after");
    }

    @AfterReturning("pointcut()")
    public void afterRetuning() {
        System.out.println("afterRetuning");
    }

    @AfterThrowing("pointcut()")
    public void afterThrowing() {
        System.out.println("afterThrowing");
    }

    @Around("pointcut()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {// 参数:连接点
        System.out.println("around before");
        Object obj = joinPoint.proceed();// 连接点调用目标组件的方法,返回目标组件的返回值
        System.out.println("around after");
        return obj;
    }

}

3、统一记录日志

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));

    }
}

9、统一记录日志(AOP)_第3张图片

你可能感兴趣的:(仿牛客网,java,spring,开发语言)