Spring的核心AOP及代理模式(“最易懂得Spring学习”)(三)

简介: 2. 动态代理2.1初次理解2.2 再深理解

2. 动态代理



  • 动态代理和静态代理角色一样


  • 动态代理的代理类是动态生成的,不是我们写好的


  • 动态代理分为两大类:基于接口的动态代理;基于类的动态代理


  • 基于接口–jdk动态代理
  • 基于类—cglib
  • java字节码实现:javassist


  • 动态代理代理的是接口


需要了解两个类:Proxy:代理;InvocationHandler:调用处理程序


InvocationHandler:反射包(java.lang.reflect)下的。它是由代理实例的,调用处理程序实现的接口。每个代理实例都有一个关联的调用处理程序,当在代理实例上调用方法时,方法调用将编码并分派到其调用处理程序的invoke方法


动态代理的好处:


  • 可以使真实角色的操作更加纯粹,不用取关注一些公共的业务
  • 公共业务交给代理角色,实现业务的分工
  • 公共业务发生扩展的时候,方便集中管理
  • 一个动态代理类代理的是一个接口,一般就是对应的一类业务
  • 一个动态代理类可以代理多个类,只要是实现了同一个接口即可


2.1初次理解


不去写代理角色,让他自己生成。

package com.hxl.demo03;
public class Host implements Rent{
    public void rent() {
        System.out.println("房东要租房");
    }
}
package com.hxl.demo03;
//租房
public interface Rent {
    public void rent();
}



package com.hxl.demo03;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
//等会会用这个类自动生成代理类
public class ProxyInvocationHandler implements InvocationHandler {
    //被代理的接口
    private Rent rent;
    public void setRent(Rent rent) {
        this.rent = rent;
    }
    //生成得到代理类
    public Object getProxy(){
        Object o = Proxy.newProxyInstance(this.getClass().getClassLoader(), rent.getClass().getInterfaces(), this);
        return o;
    }
    //处理代理实例,并返回结果
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        seeHouse();
        //动态代理的本质,就是使用反射机制实现
        Object result = method.invoke(rent, args);
        fare();
        return result;
    }
    public void seeHouse(){
        System.out.println("中介带着看房子");
    }
    public void fare(){
        System.out.println("租赁合同");
    }
}



package com.hxl.demo03;
public class Client {
    public static void main(String[] args) {
        //真实角色
        Host host = new Host();
        //代理角色:现在没有
        ProxyInvocationHandler pih = new ProxyInvocationHandler();
        //通过调用程序处理角色来处理我们要调用的接口对象
        pih.setRent(host);
        //获得代理类
        Rent proxy = (Rent) pih.getProxy();//这里的proxy就是动态生成的,我们并没有写
        proxy.rent();
    }
}


2.2 再深理解


我们把它弄成一个公式类似于。弄得活起来,智能化


代理:


package com.hxl.demo04;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
//等会会用这个类自动生成代理类
public class ProxyInvocationHandler implements InvocationHandler {
    //被代理的接口.
    //这里把它变活
    private Object target;
    public void setTarget(Object target) {
        this.target = target;
    }
    //生成得到代理类
    public Object getProxy(){
        Object o = Proxy.newProxyInstance(this.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
        return o;
    }
    //处理代理实例,并返回结果
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        //可以写死,比如搞成log.add();但是不智能,所以要弄活
        log(method.getName());
        //动态代理的本质,就是使用反射机制实现
        Object result = method.invoke(target, args);
        return result;
    }
    public void log(String msg){
        System.out.println("执行了" + msg + "方法");
    }
}

测试:

package com.hxl.demo04;
import com.hxl.demo02.UserService;
import com.hxl.demo02.UserServiceImpl;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class Client {
    public static void main(String[] args) {
        //真实角色
        UserServiceImpl userService = new UserServiceImpl();
        //代理角色。不存在
        ProxyInvocationHandler pih = new ProxyInvocationHandler();
        //设置要代理的对象
        pih.setTarget(userService);
        //动态生成代理类
        UserService proxy = (UserService) pih.getProxy();
        proxy.add();
    }
}


相关文章
|
20天前
|
存储 缓存 Java
Spring高手之路23——AOP触发机制与代理逻辑的执行
本篇文章深入解析了Spring AOP代理的触发机制和执行流程,从源码角度详细讲解了Bean如何被AOP代理,包括代理对象的创建、配置与执行逻辑,帮助读者全面掌握Spring AOP的核心技术。
28 3
Spring高手之路23——AOP触发机制与代理逻辑的执行
|
5天前
|
Java Spring
[Spring]aop的配置与使用
本文介绍了AOP(面向切面编程)的基本概念和核心思想。AOP是Spring框架的核心功能之一,通过动态代理在不修改原代码的情况下注入新功能。文章详细解释了连接点、切入点、通知、切面等关键概念,并列举了前置通知、后置通知、最终通知、异常通知和环绕通知五种通知类型。
14 1
|
20天前
|
前端开发 Java 数据库
SpringBoot学习
【10月更文挑战第7天】Spring学习
33 9
|
21天前
|
XML Java 数据格式
Spring学习
【10月更文挑战第6天】Spring学习
19 1
|
25天前
|
Java 测试技术 开发者
springboot学习四:Spring Boot profile多环境配置、devtools热部署
这篇文章主要介绍了如何在Spring Boot中进行多环境配置以及如何整合DevTools实现热部署,以提高开发效率。
51 2
|
25天前
|
前端开发 Java 程序员
springboot 学习十五:Spring Boot 优雅的集成Swagger2、Knife4j
这篇文章是关于如何在Spring Boot项目中集成Swagger2和Knife4j来生成和美化API接口文档的详细教程。
47 1
|
25天前
|
Java API Spring
springboot学习七:Spring Boot2.x 拦截器基础入门&实战项目场景实现
这篇文章是关于Spring Boot 2.x中拦截器的入门教程和实战项目场景实现的详细指南。
17 0
springboot学习七:Spring Boot2.x 拦截器基础入门&实战项目场景实现
|
25天前
|
Java API Spring
springboot学习六:Spring Boot2.x 过滤器基础入门&实战项目场景实现
这篇文章是关于Spring Boot 2.x中过滤器的基础知识和实战项目应用的教程。
21 0
springboot学习六:Spring Boot2.x 过滤器基础入门&实战项目场景实现
|
25天前
|
Java Spring
springboot 学习十一:Spring Boot 优雅的集成 Lombok
这篇文章是关于如何在Spring Boot项目中集成Lombok,以简化JavaBean的编写,避免冗余代码,并提供了相关的配置步骤和常用注解的介绍。
75 0
|
2月前
|
SQL 监控 druid
springboot-druid数据源的配置方式及配置后台监控-自定义和导入stater(推荐-简单方便使用)两种方式配置druid数据源
这篇文章介绍了如何在Spring Boot项目中配置和监控Druid数据源,包括自定义配置和使用Spring Boot Starter两种方法。