Spring从入门到放弃-AOP基础

开局一张图:切面实现横切关注点的模块化

AOP 的理解?

AOP(Aspect-Oriented Programming:面向切面编程)能够将那些与业务无关,却为业务模块所共同调用的逻辑或责任(例如事务处理、日志管理、权限控制等)封装起来,便于减少系统的重复代码,降低模块间的耦合度,并有利于未来的可拓展性和可维护性;

Spring AOP是基于动态代理的,如果要代理的对象实现了某个接口,那么Spring AOP会使用JDK Proxy去创建代理对象,而对于没有实现接口的对象,就无法使用 JDK Proxy 去进行代理了,这时候Spring AOP会使用Cglib ,Cglib 生成一个被代理对象的子类来作为代理;

AOP的相关概念:

  • Advice通知):通知定义了切面什么时候引用;
  • Join point(连接点):连接点是在程序执行过程中能够插入的一个点,切面代码可以利用这些点插入到程序的正常流程中;
  • Poincut(切点):切点有助于缩小切面所通知的连接点的范围;
  • Aspect(切面):切面时通知和切点的结合;
  • Introduction(引入):允许我们向现有的类引入新的方法或属性;
  • Weaving(织入):把切面应用到目标对象并创建新的代理对象的过程;

Spring切面的5种通知方式:

  • Before(前置通知):在目标方法被调用之前调用通知功能;
  • After(后置通知):在目标方法完成之后通知,此时不关心方法返回的是什么;
  • After-returning(返回通知):在目标方法成功执行之后调用通知;
  • After-throwing(异常通知):在目标方法抛出异常之后掉用;
  • Around(环绕通知):通知包裹了被通知的方法,在被通知方法的调用前和调用后执行自定义的行为;

上代码:

package com.cn.concert;

/**
 * @ClassName Audience
 * @Author 小林林同学
 * @Date 2021/6/19 17:10
 **/
@Aspect
@Component
public class Audience {
    @Pointcut("execution(* com.cn.concert..*(..))")
    public void performance(){}
    
    //前置通知
    @Before("performance()")
    public void silenceCellPhone(){
        System.out.println("表演之前,手机静音!");
    }
    //前置通知
    @Before("performance()")
    public void takeSeats(){
        System.out.println("表演之前,禁止说话!");
    }
    //后置返回通知
    @AfterReturning("performance()")
    public void applause(){
        System.out.println("表演之后!");
    }
    //异常通知
    @AfterThrowing("performance()")
    public void demandRefund(){
        System.out.println("表演失败之后!");
    }
    //环绕通知
    @Around("performance()")
    public void watchPerformance(ProceedingJoinPoint joinPoint){
        try{
            System.out.println("表演之前,手机静音!");
            System.out.println("表演之前,禁止说话!");
            Object[] args = joinPoint.getArgs();
            Object proceed = joinPoint.proceed();
            System.out.println(args.length);
            for(Object o:args){
                System.out.println(o);
            }
            System.out.println(proceed);
            System.out.println("表演之后!");
        }catch (Throwable e){
            System.out.println("表演失败之后!");
        }
    }
}
package com.cn.concert;

public interface Performance {
    public Integer perform(int i);
}
package com.cn.concert;

/**
 * @ClassName testPerformance
 * @Author 小林林同学
 * @Date 2021/6/19 17:33
 **/
@Component
public class TestPerformance implements Performance {
    public Integer perform(int i) {
        System.out.println("跳舞!!");
        return i;
    }
}
package com.cn.config;

/**
 * @ClassName ConcerConfig
 * @Author 小林林同学
 * @Date 2021/6/19 17:18
 **/
@Configuration
@EnableAspectJAutoProxy
@ComponentScan(basePackages = {"com"})
public class ConcerConfig {
    @Bean
    public Audience audience(){
        return new Audience();
    }
}

 

知识点: 

使用execution()指示器选择来选择切点
  • 使用注解@Aspect表示该类不仅是一个POJO,还是一个切面。                                         
  • 使用注解@Pointcut来定义命名切点,之后就可以在任意的通知注解表达式中使用它;       
  • 在环绕通知中,当要将控制权交给被通知的方法需要调用proceed()方法,未调用会阻塞对被通知方法的调用,在环绕通知中回去被通知方法的参数可调用getArgs()方法,获取返回值则在调用proceed()后获取; 
  • 记得在配置类中使用注解@EnableAspectAutoProxy来启用Aspect自动代理;                                                 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值