Spring AOP基础之代理模式.静态代理和动态代理

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
简介: Spring AOP基础之代理模式.静态代理和动态代理

一、代理模式介绍

代理模式是一种设计模式,提供了对目标对象额外的访问方式,即通过代理对象访问目标对象,这样可以在不修改原目标对象的前提下,提供额外的功能操作,扩展目标对象的功能。

简言之,代理模式就是设置一个中间代理来控制访问原目标对象,以达到增强原对象的功能和简化访问方式。

一.静态代理

上图角色分析:

?抽象角色:一般会使用接口或者抽象类来解决

?真实角色:被代理的角色实现抽象方法

?代理角色:代理真实角色,代理真实角色,也实现抽象方法,一般会做一些附属操作。

代理模式的优点:

?可以使真实角色的操作更加纯粹!不用关注一些公共的业务。

?公共业务交给代理角色,实现了业务的分工

?公共业务扩展的时候,方便集中管理。

静态代理的缺点:

?一个真实角色就会产生一个代理角色,代码量翻倍,开发效率变低。

参考代码如下:

//1.抽象角色
public interface IRent {
    //租房接口的方法;
    public void rent();
}
/*2.房东:中式英语;*/
public class HouseOwner implements IRent{
    public void rent() {
        System.out.println("房东直租房屋,一室一厅一卫,一个月300$");
    }
}
/*3.传说中中介,非链家莫属了*/
public class Proxy implements IRent{
    //1.目标对象,代理房东的房子
    HouseOwner target;
    //2.构造方法
    public Proxy(HouseOwner target) {
        this.target = target;
    }
    //3.实现的代理方法
    public void rent() {
        before();
        target.rent();
        after();
    }
    //代理增强的附加功能;
    public void before(){
        System.out.println("收取看房费100元");
    }
    public void after(){
        System.out.println("合适进行收费");
    }
}
public class ClientTest {
    @Test
    public void test(){
        //3.1房东直租
        HouseOwner owner=new HouseOwner();
        //3.2 中介代理对象的创建,来了
        Proxy proxy=new Proxy(owner);
        //3.3 客户看房子;
        proxy.rent();
    }
}

效果:

作业扩充:

代理增加日志功能

1.?创建一个抽象接口,对用户业务进行抽象:实现一个日志输出功能,以记录业务代码的调用情况。

实现思路有两种,如下:

?思路1:在业务实现类每个方法中增加相应操作(该思路是传统方法,缺点很多)。

?思路2:使用代理,在不改变原有业务的情况下,实现此日志记录功能!

体现一个重要的思想:在不改变原有代码的情况下,实现对原有功能的增强。AOP的核心思想。

二.动态代理

动态代理和静态代理的角色是一样的,动态代理的代理类是动态生成的,不是像静态代理那样是直接写死的。动态代理可以分为两大类:一类是基于接口动态代理 , 一类是基于类的动态代理。

基于接口的动态代理,如JDK动态代理

基于类的动态代理,如cglib

JDK的动态代理需要了解两个类:

核心 : InvocationHandler (调用处理程序) 和 Proxy (代理)

//proxy - 调用该方法的代理实例
//method -所述方法对应于调用代理实例上的接口方法的实例。方法对象的声明类将是该方法声明的接口,它可以是代理类继承该方法的代理接口的超级接口。
//args -包含的方法调用传递代理实例的参数值的对象的阵列,或null如果接口方法没有参数。原始类型的参数包含在适当的原始包装器类的实例中,例如java.lang.Integer或java.lang.Boolean 。
Object invoke(Object proxy, 方法 method, Object[] args)
.
static Object newProxyInstance(ClassLoader loader, //指定当前目标对象使用类加载器
Class[] interfaces, //目标对象实现的接口的类型
InvocationHandler h //事件处理器
)

案例说明:

订单模块进行操作,增加日志功能。

JDK动态代理是代理工厂,不再需要实现多个接口了,注意这里面变化比较大。

package com.yh.jdk;
//1.抽象接口
public interface OrderService {
    void addOrder();
    void updateOrder();
    void selectOders();
}
package com.yh.jdk;
/*2.目标对象*/
public class OrderDaoImpl implements OrderService{
    public void addOrder() {
        System.out.println("增加订单业务");
    }
    public void updateOrder() {
        System.out.println("更新订单业务");
    }
    public void selectOders() {
        System.out.println("查询日志信息");
    }
}
package com.yh.jdk;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/*3.定义一个动态代理的,工厂,又来了。呵呵,好处大大滴
* static Object newProxyInstance(ClassLoader loader, 类<?>[] interfaces, InvocationHandler h)
返回指定接口的代理类的实例,该接口将方法调用分派给指定的调用处理程序。
*           loader - 类加载器来定义代理类
            interfaces - 代理类实现的接口列表
            InvocationHandler h - 调度方法调用的调用处理函数
* */
public class JDKProxyFactory {
    //3.1要代理的目标对象;
    Object target;
    //3.2构造方法;
    public JDKProxyFactory(Object target) {
        this.target = target;
    }
    //3.3 注意这里是重要的,合并实现的方法.
    public Object getInstance(){
        return Proxy.newProxyInstance(
                target.getClass().getClassLoader(),//获取目标对象的类加载器;
                target.getClass().getInterfaces(),//获取目标对象的接口
                new InvocationHandler() {   //事件处理器,拦截方法,处理.
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        //注意看这里有个参数是method,还有印象吗?
                        System.out.println("******开始记录日志 **********");
                        Object invoke = method.invoke(target, args);
                        if(method.getName().equals("selectOders"))
                            System.out.println("******结束记录日志 **********");
                        return invoke;
                    }
                }
        );
    }
}
```package com.yh.jdk;
import org.junit.Test;
public class TestJdkClient {
    @Test
    public void test03(){
        OrderService target=new OrderDaoImpl();
        System.out.println(target.getClass());
        //注意动态代理的灵活性;获取实例方法.
        OrderService jdkProxyFactory = (OrderService) new JDKProxyFactory(target).getInstance();
        //代理类执行;
        jdkProxyFactory.addOrder();
    }
}


相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
目录
相关文章
|
1月前
|
监控 安全 Java
Spring AOP实现原理
本内容主要介绍了Spring AOP的核心概念、实现机制及代理生成流程。涵盖切面(Aspect)、连接点(Join Point)、通知(Advice)、切点(Pointcut)等关键概念,解析了JDK动态代理与CGLIB代理的原理及对比,并深入探讨了通知执行链路和责任链模式的应用。同时,详细分析了AspectJ注解驱动的AOP解析过程,包括切面识别、切点表达式匹配及通知适配为Advice的机制,帮助理解Spring AOP的工作原理与实现细节。
|
5月前
|
XML Java 开发者
Spring Boot中的AOP实现
Spring AOP(面向切面编程)允许开发者在不修改原有业务逻辑的情况下增强功能,基于代理模式拦截和增强方法调用。Spring Boot通过集成Spring AOP和AspectJ简化了AOP的使用,只需添加依赖并定义切面类。关键概念包括切面、通知和切点。切面类使用`@Aspect`和`@Component`注解标注,通知定义切面行为,切点定义应用位置。Spring Boot自动检测并创建代理对象,支持JDK动态代理和CGLIB代理。通过源码分析可深入了解其实现细节,优化应用功能。
247 6
|
4月前
|
XML Java 测试技术
Spring AOP—通知类型 和 切入点表达式 万字详解(通俗易懂)
Spring 第五节 AOP——切入点表达式 万字详解!
232 25
|
4月前
|
XML 安全 Java
Spring AOP—深入动态代理 万字详解(通俗易懂)
Spring 第四节 AOP——动态代理 万字详解!
138 24
|
3月前
|
Java API 微服务
微服务——SpringBoot使用归纳——Spring Boot中的切面AOP处理——Spring Boot 中的 AOP 处理
本文详细讲解了Spring Boot中的AOP(面向切面编程)处理方法。首先介绍如何引入AOP依赖,通过添加`spring-boot-starter-aop`实现。接着阐述了如何定义和实现AOP切面,包括常用注解如`@Aspect`、`@Pointcut`、`@Before`、`@After`、`@AfterReturning`和`@AfterThrowing`的使用场景与示例代码。通过这些注解,可以分别在方法执行前、后、返回时或抛出异常时插入自定义逻辑,从而实现功能增强或日志记录等操作。最后总结了AOP在实际项目中的重要作用,并提供了课程源码下载链接供进一步学习。
138 0
|
3月前
|
Java 开发者 微服务
微服务——SpringBoot使用归纳——Spring Boot中的切面AOP处理——什么是AOP
本文介绍了Spring Boot中的切面AOP处理。AOP(Aspect Oriented Programming)即面向切面编程,其核心思想是分离关注点。通过AOP,程序可以将与业务逻辑无关的代码(如日志记录、事务管理等)从主要逻辑中抽离,交由专门的“仆人”处理,从而让开发者专注于核心任务。这种机制实现了模块间的灵活组合,使程序结构更加可配置、可扩展。文中以生活化比喻生动阐释了AOP的工作原理及其优势。
87 0
|
安全 Java Spring
Spring之Aop的底层原理
Spring之Aop的底层原理
|
设计模式 Java uml
Spring AOP 原理
Spring AOP 原理
63 0
|
10月前
|
Java
Spring5入门到实战------9、AOP基本概念、底层原理、JDK动态代理实现
这篇文章是Spring5框架的实战教程,深入讲解了AOP的基本概念、如何利用动态代理实现AOP,特别是通过JDK动态代理机制在不修改源代码的情况下为业务逻辑添加新功能,降低代码耦合度,并通过具体代码示例演示了JDK动态代理的实现过程。
Spring5入门到实战------9、AOP基本概念、底层原理、JDK动态代理实现
|
7月前
|
Java 开发者 Spring
Spring AOP 底层原理技术分享
Spring AOP(面向切面编程)是Spring框架中一个强大的功能,它允许开发者在不修改业务逻辑代码的情况下,增加额外的功能,如日志记录、事务管理等。本文将深入探讨Spring AOP的底层原理,包括其核心概念、实现方式以及如何与Spring框架协同工作。