AOP之代理模式(一)

      AOP,为Aspect OrientedProgramming的缩写,意为:面向切面,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。

     说了一堆很官方的话,大家可能不是特别明白,不过这些算是我们实践的理论寄出去,还是很有必要知道的,但是现在不必要很懂,接下来从最简单的代码开始,一步步的慢慢深入了解,到底什么是AOP,什么是代理模式。学习,就是这样一个理论与实践相结合的过程。

     先来看一下最基本的,没有任何优化的代码:

/**
 * 业务接口类
 * @author sunliduan
 *
 */
public interface Greeting {
	void sayHello(String name);
}

package com.tgb.sld;
/**
 * 业务实现类
 * @author sunliduan
 *
 */
public class GreetingImpl implements Greeting {

	@Override
	public void sayHello(String name) {
		System.out.println("Hello! " + name);
	}
}

      由于业务变动,我需要在执行sayHello之前,插入一段代码b,实现某项功能,例如日志或者工作流等。最简单的就是直接在业务实现类里直接插入这段代码,然后在sayHello方法中调用这段代码。详见以下代码:

package com.tgb.sld;
/**
 * 业务实现类
 * @author sunliduan
 *
 */
public class GreetingImpl implements Greeting {

	@Override
	public void sayHello(String name) {
		before();
		System.out.println("Hello! " + name);
		after();
	}

	private void before() {
		System.out.println("Before==我在被切类的里面");
	}

	private void after() {
		System.out.println("After==我在被切类的里面");
	}

}

      可是这样有很多缺点:首先是插入的方法before()和after()不能得到复用,某一个需要插入这两个方法的类都需要复制粘贴到本类中;而过多的复制粘贴也必然造成维护极不方便,我们需要修改每一处复制粘贴的地方,一不小心有一个地方忘记修改了,那可就麻烦啦。其次要想插入新的功能方法,我们必须停止已经运行的服务,重新编译部署,这对用户来说是很不友好的。

     为了解决以上的问题,我们可以使用代理模式,且看下面代理模式的一步步发展。

 

     第一步:静态代理,其实就是设计模式中的Proxy模式。

/**
 * 业务接口类
 * @author sunliduan
 *
 */
public interface Greeting {
	void sayHello(String name);
}

/**
 * 业务实现类
 * @author sunliduan
 *
 */
public class GreetingImpl implements Greeting {

	@Override
	public void sayHello(String name) {
		System.out.println("Hello! " + name);
	}
}

      为了实现切入方法和业务方法的解耦,我们加入了一个代理类:

/**
 * 静态代理类
 * 
 * @author sunliduan
 *
 */
public class GreetingStaticProxy implements Greeting {
	
	private Greeting greeting;

	// 用静态代理类GreetingProxy代替Greeting类
	public GreetingStaticProxy(Greeting greeting) {
		super(); 
		this.greeting = greeting;
	}

	@Override
	public void sayHello(String name) {
		before();
		greeting.sayHello(name);
		after();
	}

	private void before() {
		System.out.println("Before==通过静态代理把我加到被切方法之前");
	}

	private void after() {
		System.out.println("After==通过静态代理把我加到被切方法之后");
	}
}


      来看一看客户端如何调用:

public class Client {

	public static void main(String[] args) {
		Greeting staticProxyGreeting = new GreetingStaticProxy(new GreetingImpl());
		
		staticProxyGreeting.sayHello("sunliduan");
		
	}

}

     业务不需要专门去调用,而是走到静态代理类里的sayHello方法,顺理成章的执行了切入方法,并调用了原来的业务方法。

     可以说静态代理也就是设计模式中的代理模式,它是AOP的雏形。不过从这段代码看:1、要实现代理方式,必须要定义接口。2、每个业务类,必须有一个代理类。

     但是一个业务类需要对应一个代理类,这样的代码还是有坏味道的,还是不能实现很好的复用。接下来动态代理就来了,敬请期待下一篇博客~~

<think>好的,我现在需要帮用户查找关于AOP代理模式的示意图。首先,用户提到了AOP代理模式,特别是Spring AOP使用的JDK动态代理CGLIB代理。根据用户提供的引用内容,我需要整理这些信息,并生成相关的示意图描述。 首先,用户提供的引用[1]提到,Spring AOP默认使用JDK动态代理,当目标对象没有实现接口时则使用CGLIB。引用[4]解释了切面将公共行为封装成模块。用户需要的是示意图,所以可能需要用文字描述结构图,比如类、代理对象、方法调用流程等。 接下来,我需要确定如何将代理模式的结构可视化。通常,AOP代理会在目标对象的方法调用前后插入切面逻辑,如日志、事务等。示意图可能包括客户端调用代理对象,代理对象调用目标对象的方法,并在适当时机应用通知(Advice)。 另外,引用[2][3]提到AOP与OOP的区别以及切面类的配置,这些可能需要在示意图中体现,比如显示切面类如何横切多个业务类。不过用户主要关注代理模式,所以重点应放在代理的结构上。 可能的结构包括:客户端、代理对象、目标对象、切面(Advice)。在JDK动态代理中,代理对象实现接口,而CGLIB代理则继承目标类。需要说明两者的区别,并指出何时使用哪种。 需要注意用户无法查看图片,所以需要用文字详细描述示意图的各个部分,比如用方框表示组件,箭头表示调用关系,并标注步骤。例如,代理对象拦截方法调用,执行前置通知,调用目标方法,执行后置通知等。 最后,根据用户的要求生成相关问题,需要围绕代理模式、动态代理与CGLIB的区别、应用场景等展开。确保问题与用户查询相关,并帮助深化理解。</think>### AOP代理模式示意图解析 在AOP中,代理模式是实现切面逻辑织入的核心机制。以下是代理模式的结构描述(以Spring AOP为例): **1. 代理模式示意图核心组件** ``` [客户端] --> [代理对象] --> [目标对象] ↑ | 调用前后织入 [切面(Advice)] ``` - **客户端**:发起方法调用的业务代码,例如调用`UserService.save()`。 - **代理对象**:由AOP框架动态生成的类,拦截目标方法并在适当时机触发切面逻辑。 - **目标对象**:实际执行业务逻辑的原始对象(如`UserServiceImpl`)。 - **切面(Advice)**:包含横切关注点的代码(如日志、事务等)。 **2. 动态代理类型对比** - **JDK动态代理** ![JDK动态代理] 要求目标对象**实现接口**,代理对象通过`InvocationHandler`拦截接口方法调用,并在方法执行前后插入切面逻辑[^1]。 - **CGLIB代理** ![CGLIB代理] 通过**继承目标类**生成子类代理,覆盖父类方法实现拦截,适用于未实现接口的类。 **3. 方法调用流程示例** ``` 1. 客户端调用代理对象的方法(如`save()`) 2. 代理对象触发前置通知(@Before) 3. 代理对象调用目标对象的实际方法 4. 代理对象触发后置通知(@After) 5. 返回结果给客户端 ``` ###
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值