AOP(小卡拉米!!!)温故!

前面我们说了AOP底层是使用代理模式进行实现,spring写的接口是通过代理反射,实现方法,然后定义切入点:

springAOP接口定义的方法有:被加强的方法前执行,被加强的方法后执行,出错了执行,在执行时执行等。。。

 

实现spring的指定接口,spring底层用这个结构反射代理,进行加强。

另外一种使用自定义切面

自定义方法(在被加强方法的什么时间段):

ublic class SqlCheckTime {
    public void front() {
        System.out.println(LocalDateTime.now());
    }

    public void behind() {
        System.out.println(LocalDateTime.now());
    }
}

xml装配:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="
       http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/aop
       http://www.springframework.org/schema/aop/spring-aop.xsd
">

    <bean id="UserDaoImpl" class="com.quxiao.dao.impl.UserDaoImpl"></bean>
    <!--    <bean id="addAppcontion" class="com.quxiao.aop.addAppcontion"></bean>-->
    <!--    <aop:config>-->
    <!--        <aop:pointcut id="pointcut" expression="execution(* com.quxiao.dao.impl.UserDaoImpl.*(..))"/>-->
    <!--        <aop:advisor advice-ref="addAppcontion" pointcut-ref="pointcut"></aop:advisor>-->
    <!--    </aop:config>-->

    <bean id="SqlCheckTime" class="com.quxiao.aop.SqlCheckTime"></bean>
    <aop:config>
        <!--                切面-->
        <aop:aspect ref="SqlCheckTime">
            <!--            切入点-->
            <aop:pointcut id="point" expression="execution(* com.quxiao.dao.impl.UserDaoImpl.*(..))"/>
            <!--            执行方法-->
            <aop:after method="front" pointcut-ref="point"></aop:after>
            <aop:before method="behind" pointcut-ref="point"></aop:before>
        </aop:aspect>
    </aop:config>
</beans>

这个方法就简便多了,不过第一种它的能力更强,只要实力足够,自己可以完全自定义实现如何AOP,本人菜苔一根,一个类都没看懂。。。。

另外有一种是用的注解完成:

还是那句话,懒人推进科技的进步,上面的都繁琐,为了简便,注解又产生了:

package com.quxiao.aop;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

/**
 * @program: fxspring
 * @author: quxiao
 * @create: 2023-05-12 10:44
 **/
@Component
//标记该类可以使用aop
@Aspect
public class checkAge {
    @Before("execution(* com.quxiao.dao.impl.UserDaoImpl.*(..))")
    public void check1() {
        System.out.println("检查一下年龄");
    }

    @Around("execution(* com.quxiao.dao.impl.UserDaoImpl.add(..))")
    public String check2(ProceedingJoinPoint point) {
        String proceed = "";
        try {
            System.out.println("环绕前");
            proceed = (String) point.proceed();
            System.out.println("环绕后");
        } catch (Throwable e) {
            throw new RuntimeException(e);
        }
        return "失败!";
    }
}

方法上有好几个注解:执行前,执行后,环绕。

当让,还是要在xml中注册,当然也是可以注解用springconfig配配置,

环绕方法:

package com.example.springboot17.aop;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
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.springframework.stereotype.Component;

/**
 * @program: springBoot17
 * @author: quxiao
 * @create: 2024-01-07 11:19
 **/
@Component
@Aspect
@RequiredArgsConstructor
@Slf4j
public class logAop {
    //    @Pointcut("@annotation(com.example.springboot17.util.IsCheckName)")
    //指定拥有某个注解的方法或者类
    @Pointcut("@within(org.springframework.web.bind.annotation.RequestMapping)")
    public void pointCut() {
    }

    @Around("pointCut()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {

        long l = 0;
        long r = 0;
        boolean f = true;
        Object proceed = null;
        try {
//        方法前
            l = System.currentTimeMillis();
            proceed = joinPoint.proceed();
//        方法后
            r = System.currentTimeMillis();
        } catch (Throwable e) {
            r = System.currentTimeMillis();
            f = false;
            throw new RuntimeException(e);
        } finally {
            System.out.println("调用情况:" + f);
            System.out.println("耗时:" + (r - l));
        }

        return proceed;
    }
}

这个方法是将被加强的方法完全取出来,等待调用proceed才执行,可以拿出方法返回值,如果不放回,那么这个方法就没有返回值了。给一个默认值,引用类型就是null,基本数据类型就是它们自己的默认值。(8条消息) Java中8种基本数据类型及其默认值_byte的默认值_爱写代码的小菜鸡的博客-CSDN博客

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值