问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

什么是java代理模式,具体相关的动态代理和静态代理分别是什么?举例更...

发布网友 发布时间:2022-04-29 00:47

我来回答

2个回答

热心网友 时间:2022-04-15 09:26

简单的例子: HelloSpeaker.java

import java.util.logging.*;

public class HelloSpeaker {
private Logger logger = Logger.getLogger(this.getClass().getName());

public void hello(String name) {

logger.log(Level.INFO, "hello method starts...."); //日志记录
System.out.println("Hello, " + name); //!!!!!!!!!!!

logger.log(Level.INFO, "hello method ends...."); //日志记录
}
}

HelloSpeaker在执行hello()方法时,我们希望能记录该方法已经执行以及结束,
最简单的作法就是如上在执行的前后加上记录动作,然而Logger介入了HelloSpeaker中,
记录这个动作并不属于HelloSpeaker,这使得HelloSpeaker的职责加重。

------------------------------------------------------------------------------------------
怎么办,用下面的方法或许好一些:

先定义一个接口:

public interface IHello {
public void hello(String name);
}
------------------------------------------------------------------------------------------
实现该接口

public class HelloSpeaker implements IHello {
public void hello(String name) {
System.out.println("Hello, " + name);
}
}

public class Greeting implements IHello{
public void hello(String name){
System.out.println("Greeting, " + name);
}
}
------------------------------------------------------------------------------------------
实现一个代理对象: HelloProxy

import java.util.logging.*;
public class HelloProxy implements IHello {
private Logger logger = Logger.getLogger(this.getClass().getName());
private IHello helloObject; //被代理对象

public HelloProxy(){}

public HelloProxy(IHello helloObject) {
this.helloObject = helloObject; //把被代理对象传入
}

public void setHelloObject(IHello helloObject){
this.helloObject = helloObject;
}

public IHello getHelloObject(){
return this.helloObject;
}

public void hello(String name) {
logger.log(Level.INFO, "hello method starts...."); //日志记录

helloObject.hello(name); //!!!!!!!!调用被代理对象的方法

logger.log(Level.INFO, "hello method ends...."); //日志记录
}
}

-----------------------------------------------------------------------------------------------------
执行:

IHello helloProxy = new HelloProxy(new HelloSpeaker()); //生成代理对象, 并给它传入一个被代理的对象
helloProxy.hello("world");

//IHello h=factory.getBean("hello"); // IoC
//h.hello("world");

IHello helloProxy = new HelloProxy(new Greeting()); //生成代理对象, 并给它传入一个被代理的对象
helloProxy.hello("world");

-----------------------------------------------------------------------------------------------------

代理对象HelloProxy将代理真正的HelloSpeaker来执行hello(),并在其前后加上记录的动作,
这使得我们的HelloSpeaker在写时不必介入记录动作,HelloSpeaker可以专心于它的职责。

  这是静态代理的基本范例,然而,代理对象的一个接口只服务于一种类的对象,而且如果要代理的方法很多,
我们势必要为每个方法进行代理,静态代理在程序规模稍大时就必定无法胜任.

Java在JDK 1.3之后加入协助开发动态代理功能的类,我们不必为特定对象与方法写特定的代理,使用动态代理,
可以使得一个handler服务于各个对象,首先,一个handler必须实现java.lang.reflect.InvocationHandler:

import java.util.logging.*;
import java.lang.reflect.*;

public class LogHandler implements InvocationHandler { //
private Logger logger = Logger.getLogger(this.getClass().getName());
private Object delegate; //被代理的对象

public Object bind(Object delegate) { //自定义的一个方法,用来绑定被代理对象的,返回值为被代理方法的返回值
this.delegate = delegate;
return Proxy.newProxyInstance(
delegate.getClass().getClassLoader(),
delegate.getClass().getInterfaces(),
this); //通过被代理的对象生成它的代理对象, 并同handler绑定在一起
}

public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object result = null;
try {
logger.log(Level.INFO, "method starts..." + method); //日志记录
result = method.invoke(delegate, args); //!!!!!!!!调用被代理对象的方法
logger.log(Level.INFO, "method ends..." + method); //日志记录
} catch (Exception e){
logger.log(Level.INFO, e.toString());
}
return result;
}
}
InvocationHandler的invoke()方法会传入被代理对象的方法名称与参数, 实际上要执行的方法交由method.invoke(),
并在其前后加上记录动作,method.invoke()返回的对象是实际方法执行过后的回传结果。

动态代理必须有接口:
public interface IHello {
public void hello(String name);
}

实现该接口:
public class HelloSpeaker implements IHello {
public void hello(String name) {
System.out.println("Hello, " + name);
}
}

执行:
LogHandler logHandler = new LogHandler();
IHello helloProxy = (IHello) logHandler.bind(new HelloSpeaker()); //传入被代理对象, 传回代理对象
helloProxy.hello("Justin");

热心网友 时间:2022-04-15 10:44

class a
{
void a1(){System.out.print("a");}
}

class b
{
b()
{
a aa =new a();
}
void b1()
{
aa.a1();
}
}
上边里例子就是一个简单的代理模式 在b中建立一个a的对象 然后b的b1方法里调研a的a1方法
你只要实例化话一个b的对象的话 调用这个对象的b1方法就和调研a对象的a1方法的效果是完全一样的
动态代理的话就是在
b()
{
a aa =new a();
}
这个构造参数传进一个参数 根据这个参数来产生不同的对象(这里一般要用到工厂模式)
根据产生对象的不同调研的方法肯定也就不一样了
声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
说课包括哪些方面 说课内容包括()。 如何在手机百度上删除对话记录? 结核病是什么样的疾病? 曹丕17岁得了肺痨,明知自己命不长久,还要强争王位,是不是很自私呢?_百... 古代小说常出现的病名 急求一篇"生活小窍门"(500字)的作文 至今最有什么小妙招 健康的戒烟方法 笔记本电池锁死是什么原因引起的? 如何使用地暖最省钱? 一个程序问题,广大大牛们可不可以用动态代理模式实现(调用method方法后... 怎么让地暖更省钱? 淘宝真实买家评价也是没有问题为什么会提示异常评价疑似无意义?_百度... 怎样使用地暖节能又省钱? 华秦申购什么时候上市 java动态代理是什么 电脑新设置了个账户,而且是管理员的身份,怎么删除我创的那个帐户 地暖如何设置最省钱 今天某宝突然收到说异常评价是怎么回事?我很少给差评,基本都是默认好评 如何使用地暖省气? 电地暖与水地暖在安装上想要节省些钱,应该怎么做呢? 地暖只能控制水流量的大小怎么用省钱 地暖怎么用,才能又省钱又舒服? 在电脑中设置的账户怎么删除啊 关于地暖如何节能省钱的攻略(一) 地暖怎么开省钱 nvidia geforce experience 可以截屏嘛 在哪 我只找到了录像功能 英伟达n卡怎么吧视频保存d盘 《巫师3:狂猎》如何在游戏中截图 秋冬取暖费用高,地暖怎么使用更节能?哪位能说说看? 如何使用Proxy模式及Java内建的动态代理机制 怎样用暖气省钱? 淘宝评价提示系统异常是咋回事? 谁能说说java框架spring的ioc和代理模式有什么关系?spring都哪里用了代理模式 淘宝评论怎么显示待评价状态不正确什么意思? 易方达丰和债券002969可以赎回吗 地暖是24小时开着省钱,还是分时段开更省钱? Spring框架的动态代理是干什么用的 系统无法识别显示器? 淘宝自检评价!怎么处理啊! 如何改变电脑识别到的显示器型号? 001496基金今天净值 收到淘宝邮件说我违反信用评价管理,删除评价,怎么没删啊 刚买的组装电脑显示器显示不出来型号,还有分辨率问题 Spring的Aop是采用的什么设计模式? Java的动态代理模式,在高并发的应用中能使用吗? Spring是什么平生 为什么说壬寅日柱女人好命 基金明天估值是低,今天净值高。如果我要低点买入是明天三点前买吗?