spring入门(13)---JDK动态代理

本文深入探讨了Java中的代理模式及其实现方式——JDK动态代理。通过具体案例,详细介绍了如何创建接口、接口实现类以及如何利用代理类实现目标方法的前后处理,最终演示了如何使用代理对象替代真实主题对象进行操作。

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

JDK动态代理

首先我们来了解一下java中的代理模式,代理模式的英文叫做Proxy或Surrogate,中文都可译为”代理“,所谓代理,就是一个人或者一个机构代表另一个人或者另一个机构采取行动。在一些情况下,一个客户不想或者不能够直接引用一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。

1抽象主题角色

声明了真实主题和代理主题的共同接口,这样一来在任何可以使用真实主题的地方都可以是使用代理主题

2代理主题(Proxy)角色:

代理主题角色内部含有对真实主题的引用,从而可以在任何时候操作真实主题对象;代理主题角色提供一个与真实主题角色相同的接口,以便可以在任何时候都可以替代真实主题控制对真实主题的引用,负责在需要的时候创建真实主题对象(和删除真实主题对象);代理角色通常在将客户端调用传递给真实的主题之前或之后,都要执行某个操作,而不是单纯地将调用传递给真实主题对象。

3真实主题角色

定义了代理角色所代表地真实对象

JDK动态代理是基于接口的,必须实现了某一个或多个任意接口才可以被代理,并且只有这些接口中的方法会被代理.下面通过一个(男朋友要和女朋友分手)案例讲解JDK动态代理的实现.

1、创建一个接口

  1. package www.csdn.spring.jdk.proxy;
  2. //抽象主题 角色
  3. public interface SayGoodBye {
  4. /**
  5. * 说的内容
  6. * @param content
  7. */
  8. public void say(String content);
  9. }
package www.csdn.spring.jdk.proxy;

//抽象主题 角色

public interface SayGoodBye {

/**

 * 说的内容

 * @param content

 */

public void say(String content);

}

2 、创建接口的实现类。
  1. package www.csdn.spring.jdk.proxy;
  2. //这是主题角色
  3. public class SayGoodByeImpl implements SayGoodBye {
  4. @Override
  5. public void say(String content) {
  6. System.out.println("say:" + content);
  7. }
  8. }
package www.csdn.spring.jdk.proxy;

//这是主题角色

public class SayGoodByeImpl implements SayGoodBye {

@Override
public void say(String content) {
System.out.println("say:" + content);
}

}


3、测试说明

  1. package www.csdn.spring.jdk.proxy;
  2. import org.junit.Test;
  3. public class TestSay {
  4. @Test
  5. public void say(){
  6. //创建对象
  7. SayGoodByeImpl sayGoodByeImpl = new SayGoodByeImpl();
  8. //调用say方法
  9. sayGoodByeImpl.say("咱们分手吧!");
  10. }
  11. }
package www.csdn.spring.jdk.proxy;

import org.junit.Test;

public class TestSay {

@Test

public void say(){

//创建对象
SayGoodByeImpl sayGoodByeImpl = new SayGoodByeImpl();

//调用say方法
sayGoodByeImpl.say("咱们分手吧!");

}
}

分析说明:上面创建SayGoodByeImpl的实例,调用了 say 方法,相当于男朋友自己给女朋友说咱们分手吧 . 但是男朋友不想和自己的女朋友直接说,想找一个中间人来说。那么就要使用到了代理。下面创建这样的代理类 :

4、代理类

  1. package www.csdn.spring.jdk.proxy;
  2. import java.lang.reflect.InvocationHandler;
  3. import java.lang.reflect.Method;
  4. import java.lang.reflect.Proxy;
  5. /**
  6. * JDK动态代理
  7. * @author redarmy
  8. */
  9. public class JDKProxy implements InvocationHandler {
  10. // 代理目标对象
  11. private Object target;
  12. // 创建目标对象的的代理对象
  13. public Object createProxyInstance(Object target) {
  14. this.target = target;// 代理的目标对象
  15. // 创建代理对象
  16. // 1、定义代理类的类加载器
  17. // 2、代理类要实现的接口列表
  18. // 3、 指派方法调用的调用处理程序
  19. return Proxy.newProxyInstance(target.getClass().getClassLoader(),
  20. target.getClass().getInterfaces(), this);
  21. }
  22. /**
  23. * proxy:目标对象的代理实例method:对于代理实例调用接口方法的Method实例args:方法参数
  24. */
  25. @Override
  26. public Object invoke(Object proxy, Method method, Object[] args)
  27. throws Throwable {
  28. // 声明返回值
  29. Object returnValue = null;
  30. beforeMethod();
  31. // 执行目标方法
  32. returnValue = method.invoke(target, args);
  33. afterMethod();
  34. // 修改返回值
  35. return returnValue;
  36. }
  37. public void beforeMethod(){
  38. System.out.println("---------------------目标方法之前执行");
  39. }
  40. public void afterMethod(){
  41. System.out.println("---------------------目标方法之后执行");
  42. }
  43. }
package www.csdn.spring.jdk.proxy;

import java.lang.reflect.InvocationHandler;

import java.lang.reflect.Method;

import java.lang.reflect.Proxy;

/**

 * JDK动态代理

 * @author redarmy


 */

public class JDKProxy implements InvocationHandler {

// 代理目标对象
private Object target;

// 创建目标对象的的代理对象
public  Object createProxyInstance(Object target) {
this.target = target;// 代理的目标对象
// 创建代理对象
// 1、定义代理类的类加载器
// 2、代理类要实现的接口列表
// 3、 指派方法调用的调用处理程序
return Proxy.newProxyInstance(target.getClass().getClassLoader(),
target.getClass().getInterfaces(), this);

}
/**
* proxy:目标对象的代理实例method:对于代理实例调用接口方法的Method实例args:方法参数
*/

@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {

// 声明返回值
Object returnValue = null;
beforeMethod();
// 执行目标方法
returnValue = method.invoke(target, args);
afterMethod();
// 修改返回值
return returnValue;

}

public void beforeMethod(){

System.out.println("---------------------目标方法之前执行");

}

public void afterMethod(){

System.out.println("---------------------目标方法之后执行");

}

}
5、测试说明

  1. <PRE class=java name="code">package www.csdn.spring.jdk.proxy;
  2. import org.junit.Test;
  3. public class TestSay {
  4. @Test
  5. public void say(){
  6. //真实主题角色
  7. SayGoodByeImpl sayGoodByeImpl = new SayGoodByeImpl();
  8. //代理角色
  9. JDKProxy jdkProxy = new JDKProxy();
  10. SayGoodBye sayProxy = (SayGoodBye) jdkProxy.createProxyInstance(sayGoodByeImpl);
  11. //代理说:
  12. sayProxy.say("你和他分手吧!!!");
  13. }
  14. }</PRE>
  15. <PRE></PRE>
  16. <P></P>
  17. <PRE></PRE>
  18. <P></P>  

  
  1. package www.csdn.spring.jdk.proxy;
  2. import org.junit.Test;
  3. public class TestSay {
  4. @Test
  5. public void say(){
  6. //真实主题角色
  7. SayGoodByeImpl sayGoodByeImpl = new SayGoodByeImpl();
  8. //代理角色
  9. JDKProxy jdkProxy = new JDKProxy();
  10. SayGoodBye sayProxy = (SayGoodBye) jdkProxy.createProxyInstance(sayGoodByeImpl);
  11. //代理说:
  12. sayProxy.say("你和他分手吧!!!");
  13. }
  14. }




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值