Java中的动态代理和AOP

本文介绍了Java中的动态代理,包括JDK和CGLIB两种实现方式,以及其优势。接着深入探讨了Spring中的AOP,阐述了AOP的核心概念——切面、通知、切点和连接器,列举了AOP的应用场景,并简要说明了AOP的实现方式。最后,讨论了AOP带来的优点和潜在的缺点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、动态代理

        动态代理指的是:在程序的执行过程中,使用jdk的反射机制,创建代理对象,并动态的指定代理的目标类,(就相当于明星的经纪人一样,或者是被告找律师)。

  • 动态代理的实现方式常用有两种:
  • 使用JDK代理
  • 通过CDLIB代理

优点

  1. java动态代理的优势是实现无侵入式的代码扩展也就是方法的增强;
  2. 让你可以在不用修改源码的情况下,增强一些方法;

二、AOP

        AOP,即面向切面编程,是一种编程范式,它通过将横切关注点(如日志、事务、安全等)与业务逻辑分离,从而实现代码的模块化和可维护性。在Java中,AOP由Spring框架提供支持,下面我们来详细了解一下。

        Spring中的AOP是基于动态代理实现的,即 JDK动态代理和Cglib动态代理。

eb28c7627e5f24bd59e4a0719ab3972d.png 

         将代码切割开来,插入方法,所以说的是面向切面编程


1. AOP的核心概念

  • 切面(Aspect):封装横切关注点的模块。在AOP中,一个切面通常包含了多个通知(Advice)以及相关的切点(Pointcut),用于描述在何处应该应用这些通知。
  • 通知(Advice):切面中的一个方法,它定义了在什么时候、在哪里以及如何修改目标对象的行为,包括前置通知(Before)、后置通知(AfterReturning)、异常通知(AfterThrowing)、最终通知(After)和环绕通知(Around)等几种类型。
  • 切点(Pointcut):指定在哪些Join Point上应用通知。Join Point是程序执行过程中可以插入切面的点,例如方法调用、属性访问、异常处理等。
  •  连接器(Weaving):将切面与目标对象合并的过程。连接器可以在编译期、类加载期或运行期进行,并可以使用不同的方式实现,如编译时增强、类加载时增强、动态代理等。

 2. AOP的应用场景

  • 日志记录:记录程序中各个方法的执行时间、参数、返回值等信息。
  • 安全检查:在调用某些敏感方法前,先进行用户身份验证或权限校验。
  • 性能监控:统计程序中各个方法的运行时间、调用次数等信息,用于优化性能。
  •  事务管理:实现一些跨越多个方法的事务操作。

3. AOP的实现方式

  • 基于代理的AOP:使用JDK动态代理或CGLIB生成代理对象,在代理对象中添加通知逻辑。
  • 基于AspectJ的AOP:利用AspectJ提供的注解、表达式和语法,直接在代码中定义切面。

代码示例:

        下代码之前先导入相应的jar包

f7e3cb15136ea8f9f49609a932a82fb8.png

书写接口和实体类:

public interface Person {
    void eat();

}

 实体类:

public class Zhangyu implements Person {
    @Override
    public void eat() {
        System.out.println("eat...");
    }
}

增强类:

public class JJR {
    public void before(){
        System.out.println("***");
    }
    public void be2(){
        System.out.println("*****");
    }
    public void be3(){
        System.out.println("*******");
    }
    public void be4(){
        System.out.println("*********");
    }
}

在src下书写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:context="http://www.springframework.org/schema/context"
       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/context
	http://www.springframework.org/schema/context/spring-context.xsd
	http://www.springframework.org/schema/aop
	http://www.springframework.org/schema/aop/spring-aop.xsd">

    <!--1.把所有类的对象交给IOC容器进行管理-->
<bean id="Zhangyu" class="com.dhh.service.impl.Zhangyu"></bean>
    <bean id="jjr" class="com.dhh.servlet.JJR"></bean>
    <!--2.AOP的配置:让增强类 的 哪个方法  动态进行何种增强   核心类 的 哪个方法-->
    <aop:config>
        <!--指定增强类并且起个名字-->
        <aop:aspect id="qwe" ref="jjr">
            <!--前置通知/增强:在核心类方法执行之前 进行  增强-->
            <aop:before method="before" pointcut="execution(* *..Zhangyu.*(..))"/>
            <aop:after-returning method="be2" pointcut="execution(* *..Zhangyu.*(..))"/>
            <aop:after-throwing method="be3" pointcut="execution(* *..Zhangyu.*(..))"/>
            <aop:after method="be4" pointcut="execution(* *..Zhangyu.*(..))"/>
        </aop:aspect>
    </aop:config>

</beans>

在Test类中进行测试:

package com.dhh.Test;

import com.dhh.service.Person;
import com.dhh.service.impl.Zhangyu;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Test01 {

        public static void main(String[] args) {
//        加载配置
            ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("Spring.xml");
//        获取代理对象
            Person p = context.getBean(Person.class);
            p.eat();


        }
    }

 优点:提高代码的可维护性和扩展性,将横切关注点与业务逻辑分离,避免代码重复和紧耦合。
  缺点:增加代码的复杂度,可能影响程序的执行效率。

运行结果:

d3c9d1d7c1c1011e4c7d92a8a7f43ddc.png

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

晗晗想吃烤鱼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值