什么是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();
}
这个构造参数传进一个参数 根据这个参数来产生不同的对象(这里一般要用到工厂模式)
根据产生对象的不同调研的方法肯定也就不一样了