Spring-----AOP面向切面

AOP(Aspect Oriented Programming ) 面向切面 编程 种编程范式,指导开发者如何组织程序 结构
-- OOP(Object Oriented Programming) 面向对象编程
作用:在不惊动原始设计的基础上为其进行功能增强
Spring 理念:无入侵式 / 无侵入式

本讲解基于全注解开发 

AOP也是一种思想,做的是解耦操作,把一系列的重复操作提取出来,更方便更改。尤其是做外卖的日志操作。

 入门案例一:在接口执行前输出当前系统时间:对update进行增强

 

 注意我专门写了一个SpringConfig类进行全注解开发,这是一个配置类

 第三个注解@EnableAspectJAutoProxy  是告诉Spring识别切面类

 切面类:

@Component
@Aspect
public class MyAdvice {
    //随便定义一个无参无方法体的方法
    //设置切入点
    @Pointcut("execution(void com.gsdx.dao.BookDao.update())")
    private void pt(){}

    //设置在切入点前执行
    @Before("pt()")
    public void method(){
        System.out.println(System.currentTimeMillis());
    }
}

测试类

public class App 
{
    public static void main( String[] args )
    {
        ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);
        BookDao bookDao = ctx.getBean(BookDao.class);
        bookDao.update();
    }
}

测试结果

 update执行前,当前时间已经输出了


AOP工作流程

 代理对象简单理解的话就是继承了BookDaoImpl,然后在方法执行前执行abefore方法,这是片面的理解


通知类型

前置 通知 @Before
后置 通知 @After
环绕 通知(重点 @Around
返回后 通知(了解 @AfterReturning
抛出异常后 通知 (了解 @AfterThrowing

我们就来讲一下环绕通知

@Around("pt()")
public Object around(ProceedingJoinPoint pjp) throws Throwable {
   
System.out.println("around before advice ...");
   
Object ret = pjp.proceed();
   
System.out.println("around after advice ...");
   
return ret;
}

这是BookDao中有返回参数的写法,返回Object,里面要用到ProceedingJoinPoint类

 


案例2测量业务层接口万次执行效率

简单的说就是测量业务层某接口执行前后的时间,我们肯定要用到around环绕通知

@Around("ProjectAdvice.servicePt()")
public void runSpeed(ProceedingJoinPoint pjp) throws Throwable {
   
//获取执行签名信息
   
Signature signature = pjp.getSignature();
   
//通过签名获取执行类型(接口名)
   
String className = signature.getDeclaringTypeName();
   
//通过签名获取执行操作名称(方法名)
   
String methodName = signature.getName();
    long start = System.currentTimeMillis();
   
for (int i = 0; i < 10000; i++) {
        pjp.proceed();
    }

    long end = System.currentTimeMillis();
   
System.out.println("万次执行:"+className+"."+methodName+"--->"+(end-start)+"ms");
}

pjp.proceed表示的是去执行接口中的方法


 案例3:百度网盘密码数据兼容处理

案例先知:AOP通知获取数据

这里获取的是接口中方法的形参的值 

@Around("pt()")
public Object around(ProceedingJoinPoint pjp) throws Throwable {
   
Object[] args = pjp.getArgs();
   
System.out.println(Arrays.toString(args));
   
Object ret = pjp.proceed();
   
return ret;
}

 思路是通过环绕通知,先对url,password进行处理,再执行pjp.proceed();

@Repository
public class ResourcesDaoImpl implements ResourcesDao {
    public boolean readResources(String url, String password) {
        System.out.println(password.length());
        //模拟校验
        return password.equals("root");
    }
}

 

@Component
@Aspect
public class DataAdvice {
    @Pointcut("execution(boolean com.itheima.service.*Service.*(*,*))")
    private void servicePt(){}

    @Around("DataAdvice.servicePt()")
    public Object trimStr(ProceedingJoinPoint pjp) throws Throwable {
        Object[] args = pjp.getArgs();
        for (int i = 0; i < args.length; i++) {
            //判断参数是不是字符串
            if(args[i].getClass().equals(String.class)){
                args[i] = args[i].toString().trim();
            }
        }
        Object ret = pjp.proceed(args);
        return ret;
    }


}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值