什么是java代理模式,具体相关的动态代理和静态代理分别是什么?举例更好啦~
发布网友
发布时间:2022-03-24 06:11
我来回答
共3个回答
懂视网
时间:2022-03-24 10:32
动态代理和静态代理的区别如下:
1、静态代理业务类只需要关注业务逻辑本身,保证了业务类的重用性。代理对象的一个接口只服务于一种类型的对象,如果要代理的方法很多,需要为每一种方法都进行代理,静态代理在程序规模稍大时就无法胜任。如果接口增加一个方法,除了所有实现类需要实现这个方法外,所有代理类也需要实现此方法,增加了代码维护的复杂度。
2、动态代理与静态代理相比较,最大的好处是接口中声明的所有方法都被转移到调用处理器一个集中的方法中处理(InvocationHandler invoke)。这样,在接口方法数量比较多的时候,可以进行灵活处理,而不需要像静态代理那样每一个方法进行中转。而且动态代理的应用使类职责更加单一,复用性更强。
热心网友
时间:2022-03-24 07:40
简单的例子: 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-03-24 08:58
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();
}
这个构造参数传进一个参数 根据这个参数来产生不同的对象(这里一般要用到工厂模式)
根据产生对象的不同调研的方法肯定也就不一样了