从动态代理到AOP

从动态代理到AOP

0x00前言

上文简单了解了下两种动态代理,JDK CGLib 咱就是说啥呢,确实CGLib比JDK
动态代理有点方便。。。
JDK动态代理的缺点就是被代理对象必须要实现一个接口,这种严苛的条件并不能满足日常开发的全部需求,并不是所有的类都必须实现接口

0x02进入正题AOP

AOP:面向切面编程(Aspect Oriented Programming)是面向对象编程的一种补充和完善
AOP提供"横向"的切面逻辑,将与多个对象有关的公共模块封装成一个可重用模块,并将其整合成Aspect(切面),减少了代码的重复降低了模块的耦合度更加有利于扩展。
功能:再不改变原有业务逻辑的前提下对业务进行增强

0x03相关概念与实现流程

  • 连接点(JoinPoint):程序执行过程中某个特定的点,由于Sping只支持方法类型的连接点,所以总是表示一个方法的执行
  • 横切关注点:下文统称切点单不是PointCut, 对原方法进行增强的方法
  • 切面:包含切点的类叫切面类
  • 切入点(PointCut):被代理类中的方法 被横切的方法
  1. 申明切入点(使用SpEL表达式匹配一个或多个)pointcut
  2. 申明切面类(在此之前将切面类交给spring管理)
  3. Aspect在切面类中进行通知(切点放在切入点前还是后)

0x04注解形式实现

<!--包扫描注解 自动装配-->
<context:component-scan base-package="com"></context:component-scan>
<!--开启aop注解-->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
<!-- 添加context aspects 依赖-->
<dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.3.18</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aspects</artifactId>
            <version>5.3.18</version>
        </dependency>

这里展示aop利用两种动态代理的实现
Apple 使用CGLib动态代理
Banana 使用JDK动态代理

//水果接口
public interface Fruit {
    void sayWhoami();
}
//Banana 使用JDK动态代理 实现水果接口 并交给Spring管理
@Component
public class Banana implements Fruit {
    @Override
    public void sayWhoami() {
        System.out.println("I am Banana!");
    }
}
@Component
public class Apple {
	//苹果使用CGLib动态代理
    public void sayWhoami() {
        System.out.println("I am Apple!");
    }
}
//切面类
@Aspect
@Component
public class FruitHandler {
	//SpEL表达是匹配切入点
    @Pointcut("execution(* com.*.sayWhoami())")
    public void eat(){}
    
    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd:hh:mm:ss");
	//前置通知
    @Before("eat()")
    public void startTime(){
        Date date = new Date();
        String format = simpleDateFormat.format(date);
        System.out.println("开启事务"+format);
    }
    //后置通知
    @After("eat()")
    public void endTime(){
        Date date = new Date();
        String endformat = simpleDateFormat.format(date);
        System.out.println("提交事务"+endformat);
    }
}
 public static void main(String[] args) {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        Apple apple = (Apple) applicationContext.getBean("apple");
        apple.sayWhoami();

        Fruit banana  = (Fruit) applicationContext.getBean("banana");
        banana.sayWhoami();
    }

在两个对象调用sayWhoami处打断点 验证目的
在这里插入图片描述

0x05xml配置类实现

注解实现改写配置类:删除注解修改FruitHandler(删除声明切入点) 与 配置文件

public class FruitHandler {
    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd:hh:mm:ss");
    public void startTime(){
        Date date = new Date();
        String format = simpleDateFormat.format(date);
        System.out.println("开启事务"+format);
    }
    public void endTime(){
        Date date = new Date();
        String endformat = simpleDateFormat.format(date);
        System.out.println("提交事务"+endformat);
    }
}
 	<bean id="apple" class="com.Apple"></bean>
    <bean id="banana" class="com.Banana"></bean>
    <bean id="eatHandler" class="com.FruitHandler"></bean>
    <aop:config>
        <!--切入点 -->
        <aop:pointcut id="eat" expression="execution(* com.*.sayWhoami())"/>

        <aop:aspect ref="eatHandler">
            <aop:before method="startTime" pointcut-ref="eat" />
            <aop:after method="endTime" pointcut-ref="eat" />
        </aop:aspect>
    </aop:config>

在这里插入图片描述
运行结果
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值