Spring AOP、Spring AOP 实现原理

一、为什么会出现AOP
一个场景

把大象装进冰箱分三步:
(1)、打开冰箱
(2)、把大象装进冰箱
(3)、关上冰箱
把老虎装进冰箱分三步:
(1)、打开冰箱
(2)、把老虎装进冰箱
(3)、关上冰箱
如果把1000种动物装进冰箱,还需要计时怎么办?显然不能1000个类中都加代码

交叉业务逻辑,系统级的服务 类比 打开冰箱门,关闭冰箱门
主业务逻辑 类比 把动物放进冰箱,主业务执行前后添加系统级服务,比如要加事务,打印日志

优化:
1.将xxx放到冰箱中这个过程封装成标准的过程
2.为标准过程的开始通知开始计时
3.为标准过程的结束通知结束计时
4.关闭冰箱,输出计时结果

解决的几种思路方法:
1、可以写一个工具类,把重复的过程写工具类里
2、继承一个类,执行相同的方法
3、动态代理解决
4、AOP

AOP底层就是通过动态代理实现的。(JDK动态代理,CGLIB动态代理)
即通过一定手段将不同服务的公共的纵向处理逻辑提取出来,统一实现。
二、AOP是什么
AOP是面向切面编程,它是一种思想。交叉业务逻辑,系统级的服务是切面。把切面加入到主业务逻辑的过程就是织入
连接点:可以被切面织入的方法,通常业务接口的方法都是连接点。final方法不能是连接。
切入点:具体被织入的方法就是切入点。
目标对象:别增强的对象,主业务逻辑类的对象
通知Advice通知是切面的一种实现,定义切入的时间
顾问Advisor顾问是切面的另一种实现,包装了通知,能够将通知以更为复杂的方式织入的目标对象。

可以说是OOP面向对象编程的一种完善和补充。面向对象更多的操作是纵向的(继承,接口),这就导致一些需要在横向上(即业务代码方法中的前后)嵌入的非核心代码得在每一个方法上都要去写(比如日志,权限,异常处理等)。它们散布在各方法的横切面上,造成代码重复,也不利于各个模块的重用。
AOP就是为了解决这种难题而生的。在不修改代码的前提下,引入可以在运行期为类动态地添加一些方法或字段

三、AOP能做什么
1、降低模块之间的耦合度
2、使系统容易扩展
3、避免修改业务代码,避免引入重复代码,更好的代码复用
四、AOP怎么用

/*
前置通知:某方法调用之前发出通知。
后置通知:某方法完成之后发出通知
返回后通知:方法正常返回后,调用通知。在方法调用后,正常退出发出通知
异常通知:抛出异常后通知(After throwing advice) : 在方法抛出异常退出时执行 的通知。在方法调用时,异常退出发出通知
环绕通知:通知包裹在被通知的方法的周围知。

*/
@Aspect
@Component
public class LogAspect {
    private static final Logger logger=LoggerFactory.getLogger(LogAspect.class);
    @Before("execution(* com.hbu.toutiao.controller.SettingController.*(..))")
    public void beforeMethod(JoinPoint joinPoint){
        logger.info("方法执行之前");
    }
    @AfterReturning(value="execution(* com.hbu.toutiao.controller.SettingController.*(..))",returning = "result")
    public Object afterReturn(Object result){
        logger.info("执行返回后通知");
      return result+"返回后通知";
    }
    @After("execution(* com.hbu.toutiao.controller.SettingController.*(..))")
    public void afterMethod(){
        logger.info("执行后置通知方法执行之后");
    }

    @Around("poincut()")
    public  Object Around(ProceedingJoinPoint pjp) throws Throwable {
        logger.info("环绕执行之前");
        Object o=pjp.proceed();
        logger.info("环绕执行之后"+o);
        o="环绕通知:"+o;
        return  o;
    }
    @AfterThrowing(value = "execution(* com.hbu.toutiao.controller.SettingController.*(..))",throwing = "ex")
    public void exceptinMethod(Exception ex){
        logger.info("发生了异常"+ex.getMessage());
    }

    //定义一个切入点
    @Pointcut(value="execution(* com.hbu.toutiao.controller.SettingController.around(..))")
    public void poincut(){

    }
}

参考链接:
https://blog.csdn.net/zhaoenweiex/article/details/78177481

你可能感兴趣的:(spring框架总结,spring,aop,java,web)