Spring AOP 之静态代理和动态代理
大家都知道Spring AOP的实现,底层是动态代理,那我们先了解下静态代理和动态代理是怎么工作的吧
静态代理
静态代理就是说我们常说的代理模式,其用途有:
1. 远程代理(Remote Proxy ):为一个对象在不同的地址空间提供局部代理。
2. 虚代理(Virtual Proxy ):根据需要创建开销很大的对象。
3. 保护代理(Protection Proxy ):控制对原始对象的访问。保护代理用于对象应该有不同的访问权限的时候。
4. 智能指引(Smart Reference ):取代了简单的指针,它在访问对象时执行一些附加操作。
类图
代码:
//抽象主题增加了可以返回自身代理对象的方法getProxy()
abstract class Subject02 {
public abstract void request();
public abstract Subject02 getProxy();
}
//被代理者
class RealSubject02 extends Subject02 {
private Subject02 proxy = null;
//被代理者明白自己需要被代理,于是将自己this作为参数找到自己的代理
public RealSubject02() {
this.proxy = new Proxy03(this);
}
public void request() {
System.out.println("被代理者的 request() ...");
}
public Subject02 getProxy() {
return this.proxy;
}
}
//代理者,它是由具体的被代理者指定的
class Proxy03 extends Subject02 {
private Subject02 realSubject = null;
public Proxy03(Subject02 realSubject) {
this.realSubject = realSubject;
}
public void request() {
System.out.println("代理者的 request() ...");
this.realSubject.request();
System.out.println("被代理者操作完成 ...");
}
//代理者本身只是返回自己,当然也可以一直扩展下去
public Subject02 getProxy() {
return this;
}
}
public class Client {
public static void main(String[] args) {
System.out.println("\n第三种代理:强制代理");
Subject02 realSubject = new RealSubject02();
//获得具体被代理者的代理
Subject02 proxy03 = realSubject.getProxy();
proxy03.request();
}
}
测试结果:
第三种代理:强制代理
代理者的 request() ...
被代理者的 request() ...
被代理者操作完成 ...
静态代理的另一种写法:
//抽象主题,定义一系列业务需求处理
abstract class Subject{
public abstract void request();
}
//真实主题,即被代理者
class RealSubject01 extends Subject{
public void request() {
System.out.println("被代理者的 request() ...");
}
}
//代理者
class Proxy01 extends Subject{
private Subject subject = null;
//传进被代理者的方式使得代理者了解自己代理了谁
public Proxy01(Subject realSubject) {
this.subject = realSubject;
}
public void request() {
System.out.println("代理者的 request() ...");
this.subject.request();
System.out.println("被代理者操作完成 ...");
}
}
class Proxy02 extends Subject{
private Subject subject = null;
//直接new 一个被代理者,代理者事先不必知道自己代理了谁,只管负责做好本职工作
public Proxy02() {
this.subject = new RealSubject01();
}
public void request() {
System.out.println("代理者的 request() ...");
this.subject.request();
System.out.println("被代理者操作完成 ...");
}
}
public class Client {
public static void main(String[] args) {
System.out.println("第一种代理:代理者认识被代理者");
Subject proxy01 = new Proxy01(new RealSubject01());
proxy01.request();
System.out.println("\n第二种代理:代理者不认识被代理者");
Subject proxy02 = new Proxy02();
proxy02.request();
}
}
动态代理
动态代理具有更好的灵活性,因为它不用在我们设计实现的时候就指定某一个代理类来代理哪一个被代理对象,我们可以把这种指定延迟到程序运行时由JVM来实现。
更重要的是,动态代理模式可以使得我们在不改变原来已有的代码结构的情况下,对原来的“真实方法”进行扩展、增强其功能,并且可以达到控制被代理对象的行为的目的。
类图:
代码:
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
//抽象主题类,这里不能用abstract抽象类,一定要是interface
interface AbstractSubject {
public abstract void request();
}
// 真实主题类,即被代理类
class RealSubject implements AbstractSubject {
public void request() {
System.out.println("RealSubject's request() ...");
}
}
// 动态代理类,实现InvocationHandler接口
class DynamicProxy implements InvocationHandler {
// 被代理类的实例
Object obj = null;
// 将被代理者的实例传进动态代理类的构造函数中
public DynamicProxy(Object obj) {
this.obj = obj;
}
/**
* 覆盖InvocationHandler接口中的invoke()方法
*
* 更重要的是,动态代理模式可以使得我们在不改变原来已有的代码结构
* 的情况下,对原来的“真实方法”进行扩展、增强其功能,并且可以达到
* 控制被代理对象的行为,下面的before、after就是我们可以进行特殊
* 代码切入的扩展点了。
*/
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
/*
* before :doSomething();
*/
Object result = method.invoke(this.obj, args);
/*
* after : doSomething();
*/
return result;
}
}
// 测试类
public class Client {
public static void main(String[] args) {
// 被代理类的实例
AbstractSubject realSubject = new RealSubject();
// 获得被代理类的类加载器,使得JVM能够加载并找到被代理类的内部结构,以及已实现的interface
ClassLoader loader = realSubject.getClass().getClassLoader();
// 获得被代理类已实现的所有接口interface,使得动态代理类的实例
Class<?>[] interfaces = realSubject.getClass().getInterfaces();
// 用被代理类的实例创建动态代理类的实例,用于真正调用处理程序
InvocationHandler handler = new DynamicProxy(realSubject);
/*
* loader : 被代理类的类加载器
* interfaces :被代理类已实现的所有接口,而这些是动态代理类要实现的接口列表
* handler : 用被代理类的实例创建动态代理类的实例,用于真正调用处理程序
*
* return :返回实现了被代理类所实现的所有接口的Object对象,即动态代理,需要强制转型
*/
//获得代理的实例
AbstractSubject proxy = (AbstractSubject) Proxy.newProxyInstance(
loader, interfaces, handler);
proxy.request();
//打印出该代理实例的名称
System.out.println(proxy.getClass().getName());
}
}
测试结果:
RealSubject's request() ...
DesignPattern.proxy.dynamicProxy.$Proxy0
相关推荐
【Spring AOP的静态代理和动态代理】 在软件开发中,代理模式是一种常见的设计模式,它允许我们在不修改原有对象的基础上,对对象的行为进行增强。代理模式的核心思想是通过代理对象来控制对原始对象(也称为委托...
主要对Spring AOP的相关概念和简单的静态代理、动态代理以及常见的几种AOP配置方式做总结学习。主要包括:1. AOP的常见概念 2. 静态代理 3. jdk动态代理 4. Aspectj and Aspectjweaver 5. **aop-config** 6. CGLIB ...
本资源主要涵盖了静态代理和动态代理两种常见类型的代理模式,以及Spring AOP中动态代理的三种配置方式。以下是详细的知识点解析: ### 静态代理 静态代理是程序员手动创建代理类并实现相同接口的方式。代理类和...
通过阅读和分析这些代码,开发者可以直观地了解Spring AOP静态代理的工作原理,并将其应用到自己的项目中。 总结起来,这个案例旨在通过Spring AOP的静态代理模式,帮助开发者掌握如何在不改变原有业务逻辑的情况下...
1. **静态代理**:Spring AOP 提供了两种代理方式,一种是静态代理,另一种是动态代理。静态代理是在编译时就确定了代理类,这种代理方式通常通过实现相同接口的方式创建。然而,Spring AOP默认并不使用静态代理,...
总结来说,Spring的静态代理和动态代理都用于实现AOP,静态代理适用于简单场景,但需要手动编写代理类,而动态代理则更加灵活,可以在运行时动态创建代理对象,适用于接口众多的情况。了解和掌握这两种代理模式对于...
Spring AOP里的静态代理和动态代理用法详解 Spring AOP里的静态代理和动态代理用法详解是关于 Spring AOP里的静态代理和动态代理的详细介绍。代理是一种设计模式,通过创建一个代理对象来控制对委托类对象的直接...
现在让我们深入探讨JDK动态代理和Spring AOP的原理。 首先,JDK动态代理基于Java的反射机制,通过`java.lang.reflect.Proxy`类和`java.lang.reflect.InvocationHandler`接口来实现。Proxy类用于创建一个代理对象,...
Spring AOP的实现方式主要有两种:静态代理和动态代理。静态代理是开发者手动创建代理类,而动态代理则是在运行时生成代理对象,这正是反射发挥作用的地方。在Java中,可以使用`java.lang.reflect.Proxy`类和`java....
Spring框架AOP静态代理 AOP(Aspect-Oriented Programming,面向切面编程)是一种编程范式,旨在通过将横切关注点(如日志记录、事务管理等)从主业务逻辑中分离出来,提高代码的模块化和可维护性。 静态代理是在...
代理模式主要有两种形式:静态代理和动态代理。 1. **静态代理** 静态代理在程序运行前就已经存在,代理类和被代理类的关系是明确的。实现过程包括: - 定义一个公共接口,被代理类和代理类都实现该接口。 - 被...
AOP实现的关键在于AOP框架自动创建的AOP代理,AOP代理主要分为静态代理和动态代理,静态代理的代表为AspectJ;而动态代理则以Spring AOP为代表。 何为切面? 一个和业务没有任何耦合相关的代码段,诸如:调用日志,...
动态代理在运行时创建,而静态代理则需要额外的编译步骤。 4. **切面(Aspect)**:切面是通知和切入点的组合。它是模块化的,可以封装一组相关的行为和关注点。在Spring中,切面可以通过使用`@Aspect`注解的Java类...
- **代理(Proxy)**:Spring AOP 通过代理来实现对目标对象的增强,有 JDK 动态代理和 CGLIB 代理两种方式。 2. **AspectJ 1.6.12 Jar 包** `AspectJ` 是一个独立的 AOP 框架,提供了更强大的 AOP 支持,包括...
在Java开发领域,Spring框架是应用最广泛的轻量级框架之一,它提供了众多功能,包括依赖注入、面向切面编程(AOP)等。本文将详细介绍在使用Spring AOP时所需的两个关键jar包:aopalliance-1.0.jar和aspectjweaver-...
- 优点:避免了静态代理中代理类过多的问题,提高了代码的灵活性和扩展性。 #### 三、Spring AOP 的关键概念 **1. Aspect (切面)** - 定义:用来描述横切关注点的模块化,比如日志记录、事务管理等。 **2. ...
Spring AOP,即面向切面编程,是Spring框架的核心组件之一,它允许程序员在不修改原有业务代码的情况下,对程序进行功能增强。本篇文章将详细阐述Spring AOP的基本概念、种类、代理原理、通知类型以及切入点,帮助你...
在Spring中,AOP通过代理机制实现了切面编程,允许我们在不修改原有业务代码的情况下,插入额外的功能。 一、理解AOP概念 1. 切面(Aspect):AOP的核心概念,代表一个关注点的模块化,这个关注点可能会横切多个...
在IT行业中,Spring框架是Java企业级应用开发的首选,其强大的功能之一就是AOP(面向切面编程)。本文将详细解析Spring AOP的三种实现方式,帮助你深入理解这一重要概念。 首先,理解AOP的基本概念至关重要。AOP是...
AOP分为静态织入和动态织入两种。静态织入通常在编译阶段完成,会改变目标代码的字节码。而动态织入则在运行时通过代理机制实现,Spring采用这种方式,并且依赖AspectJ库来实现。 **核心概念解析:** 1. **横切...