导航:首页 > 编程语言 > 静态代理java

静态代理java

发布时间:2022-05-04 06:47:59

1. java静态代理与动态代理的区别

JAVA的静态代理与动态代理比较
1.静态代理类:
程序员创建或由特定工具自动生成源代码,再对其编译。在程序运行前,代理类的.class文件就已经存在了。动态代理类:在程序运行时,运用反射机制动态创建而成。
由此可见,代理类可以为委托类预处理消息、把消息转发给委托类和事后处理消息等。
例程1 HelloService.java
package proxy;
import java.util.Date;
public interface HelloService{
public String echo(String msg);
public Date getTime();
}
2.动态代理类
与静态代理类对照的是动态代理类,动态代理类的字节码在程序运行时由Java反射机制动态生成,无需程序员手工编写它的源代码。动态代理类不仅简化了编程工作,而且提高了软件系统的可扩展性,因为Java 反射机制可以生成任意类型的动态代理类。java.lang.reflect 包中的Proxy类和InvocationHandler 接口提供了生成动态代理类的能力。

Proxy类提供了创建动态代理类及其实例的静态方法。
(1)getProxyClass()静态方法负责创建动态代理类,它的完整定义如下:
public static Class<?> getProxyClass(ClassLoader loader, Class<?>[] interfaces) throws IllegalArgumentException
参数loader 指定动态代理类的类加载器,参数interfaces 指定动态代理类需要实现的所有接口。
(2)newProxyInstance()静态方法负责创建动态代理类的实例,它的完整定义如下:
public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler handler) throws
IllegalArgumentException
参数loader 指定动态代理类的类加载器,参数interfaces 指定动态代理类需要实现的所有接口,参数handler 指定与动态代理类关联的 InvocationHandler 对象。
以下两种方式都创建了实现Foo接口的动态代理类的实例:
/**** 方式一 ****/
//创建InvocationHandler对象
InvocationHandler handler = new MyInvocationHandler(...);
//创建动态代理类
Class proxyClass = Proxy.getProxyClass(Foo.class.getClassLoader(), new Class[] { Foo.class });
//创建动态代理类的实例
Foo foo = (Foo) proxyClass.getConstructor(new Class[] { InvocationHandler.class }).
newInstance(new Object[] { handler });
/**** 方式二 ****/
//创建InvocationHandler对象
InvocationHandler handler = new MyInvocationHandler(...);
//直接创建动态代理类的实例
Foo foo = (Foo) Proxy.newProxyInstance(Foo.class.getClassLoader(),new Class[] { Foo.class }, handler);
由Proxy类的静态方法创建的动态代理类具有以下特点:
动态代理类是public、final和非抽象类型的;
动态代理类继承了java.lang.reflect.Proxy类;
动态代理类的名字以“$Proxy”开头;
动态代理类实现getProxyClass()和newProxyInstance()方法中参数interfaces指定的所有接口;

2. 静态代理,JDK动态代理和CGLib动态代理之前的区别

区别:
java动态代理是利用反射机制生成一个实现代理接口的匿名类,在调用具体方法前调用InvokeHandler来处理。而cglib动态代理是利用asm开源包,对代理对象类的class文件加载进来,通过修改其字节码生成子类来处理。
1、如果目标对象实现了接口,默认情况下会采用JDK的动态代理实现AOP
2、如果目标对象实现了接口,可以强制使用CGLIB实现AOP
3、如果目标对象没有实现了接口,必须采用CGLIB库,spring会自动在JDK动态代理和CGLIB之间转换

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

简单的例子: 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");

4. Java动态代理和静态代理的区别

缺Java中的动态代理相对于静态代理优点:
1、静态代理类和委托类实现了相同的接口,代理类通过委托类实现了相同的方法。这样就出现了大量的代码重复。如果接口增加一个方法,除了所有实现类需要实现这个方法外,所有代理类也需要实现此方法。增加了代码维护的复杂度。
2、静态代理对象只服务于一种类型的对象,如果要服务多类型的对象。势必要为每一种对象都进行代理,静态代理在程序规模稍大时就无法胜任了。如上的代码是只为UserManager类的访问提供了代理,但是如果还要为其他类如Department类提供代理的话,就需要我们再次添加代理Department的代理类。

5. java静态代理和装饰模式的区别

  1. 装饰模式:以对客户端透明的方式扩展对象的功能,是继承关系的一个替代方案;

  2. 代理模式:给一个对象提供一个代理对象,并有代理对象来控制对原有对象的引用;

  3. 装饰模式应该为所装饰的对象增强功能;代理模式对代理的对象施加控制,并不提供对象本身的增强功能

  4. 二者的实现机制确实是一样的,可以看到他们的实例代码重复是很多的。但就语义上说,这两者的功能是相反的,模式的一个重要作用是简化其他程序员对你程序的理解,你在一个地方写装饰,大家就知道这是在增加功能,你写代理,大家就知道是在限制。

6. java有几个学习方向

java作为计算机编程使用最多的语言之一,就业面是比较广的,是一个不错的选择。

作为世界上最通用的编程语言之一,Java现在几乎在平台、技术和经济领域都得到了广泛的应用。这就是为什么对Java开发人员的需求不断增加的原因。基本上每一家专业的IT培训学校,都会开设有Java方向的课程。这里简单列举下学习Java要学习的内容。

Java的学习内容:

①Java编程基础

②web前端开发技术(MySQL数据库、HTML5、CSS3、JS、linux系统)

③后台开发主流的技术框架(SSM框架、SSH框架)

④前后端分离的开发模式(GitHub、Maven)

⑤分布式微服架构技术以及SpringCloud等技术(Dubbox的微服实战、Spring Cloud的微服实战、Nosql数据库、Vue.js实战等)

互联网行业目前还是最热门的行业之一,学习IT技能之后足够优秀是有机会进入腾讯、阿里、网易等互联网大厂高薪就业的,发展前景非常好,普通人也可以学习。

想要系统学习,你可以考察对比一下开设有相关专业的热门学校,好的学校拥有根据当下企业需求自主研发课程的能力,能够在校期间取得大专或本科学历,中博软件学院、南京课工场、南京北大青鸟等开设相关专业的学校都是不错的,建议实地考察对比一下。

祝你学有所成,望采纳。

7. Java静态代理和iOS代理模式这两个概念的理解上的疑惑

java静态代理模式,举例给你,看下如何理解:
public class Ts {
public static void main(String[] args) throws Exception {
// 通过中介公司生产一批衣服
ClothingProct cp = new ProxCompany( new LiNingCompany());
cp.proctClothing();
}

}

/**
* 定义生产一批衣服功能的接口
*
*/
interface ClothingProct {

void proctClothing(); // 有生产一批衣服的功能

}

/**
*
* 代理类:中介公司
*
*/
class ProxCompany implements ClothingProct {

private ClothingProct cp ; // 中介公司不会生产衣服,需要找一家真正能生产衣服的公司

ProxCompany(ClothingProct cp) {
super ();
this . cp = cp;
}

@Override
public void proctClothing() {

System. out .println( "收取1块钱的中介费" );
cp .proctClothing();

}

}

/**
*
* 李宁公司是生产服装的目标类
*
*/
class LiNingCompany implements ClothingProct {

@Override
public void proctClothing() {

System. out .println( "生产一批衣服。。。。" );
}

}

上面程序的做法,使用的模式是静态代理模式

静态代理模式在现实编程中的弊端:
它的特征是代理类和目标对象的类都是在编译期间确定下来的,不利于程序上的扩展,上面示例中,如果客户还想找一个“生产一批鞋子”的工厂,那么还需要新增加一个代理类和一个目标类。如果客户还需要很多其他的服务,就必须一一的添加代理类和目标类。那就需要写很多的代理类和目标类

代理模式到底做了什么?
我眼中的代理模式只有两个关注点:协议和代理者
协议定义了一组方法,由某一个类负责实现。
代理者作为某个类的一个属性,通常是另一个类的实例对象,可以负责完成原来这个类不方便或者无法完成的任务。
首先谈一谈代理者,在脑中重新回想一下代理模式的实现过程。在页面B中定义一个代理对象的时候,好像和定义一个普通的property非常类似(除了 weak和id《delegate》>)。这也正是我对代理的概括:代理本来就是一个属性而已,并没有非常神秘。
当然,代理者并不只是一个类普通的属性,否则我只需要重写一下B的初始化方法即可达到同样的效果:
self.BVC = [[BViewController alloc]initWithDelegate:self];

然后在BViewController.m中定义一个AViewController *AVC并在初始化方法中赋值即可。
注意到代理者在定义的时候,格式往往是这样的:
id <SomeDelegate> delegate;

所以我对代理的优势的理解是:
代理的核心优势在于解耦
与直接声明一个属于某个固定的类的代理者相比,声明为id的代理者具备两个明星的优势。
允许多个不同的类成为本类的代理。试想一下在本文例子中,如果页面B可以跳转回N个页面,如果还是通过声明一个普通对象的方式,那怎么办?
允许代理者的类还不固定。试想一下,UITableView也有delegate,它根本不知道那个类会成为它的代理者。
再看一看协议。协议更加简单了。协议只是定义了一组方法。在代理模式中,完全可以不用在页面B中定义一个协议,然后A再去遵循这个协议。直接调用A的方法即可。
个人认为协议的优点在于以下几点:
可以利用Xcode的检查机制。对于定义为@required的方法,如果实现了协议而没有实现这个方法,编译器将会有警告。这样可以防止因为疏忽,忘记实现某个代码的情况,而由于OC的运行时特性,这样的错误往往在运行阶段才会导致程序崩溃。
有利于代码的封装。如果一个类,实现了某个协议,那么这个协议中的方法不必在.h中被声明,就可以被定义协议的类调用。这样可以减少一个类暴露给外部的方法。
有利于程序的结构化与层次化。一个协议往往是解决问题的某个方法,对于一个其他的不过却类似的问题,我们只用再次实现协议即可,避免了自己再次构思一组方法。协议的继承机制使得这一有点更加强大。
说了怎么多,总结起来只有一句:代理模式并不神秘,只是一个经过了优化的小技巧(让某个类持有另一个类的指针)。代理和协议也只是让程序耦合度更低,结构感更强而已。

阅读全文

与静态代理java相关的资料

热点内容
fibonacci数列算法 浏览:775
产品经理要和程序员吵架吗 浏览:252
grub2命令行 浏览:618
无法获取加密卡信息 浏览:774
云服务器网卡充值 浏览:509
编程就是软件 浏览:49
服务器如何添加权限 浏览:437
引用指针编程 浏览:851
手机加密日记本苹果版下载 浏览:63
命令行括号 浏览:176
java程序升级 浏览:490
排序算法之插入类 浏览:227
gcccreate命令 浏览:73
海尔监控用什么app 浏览:64
系统盘被压缩开不了机 浏览:984
linuxredis30 浏览:541
狸窝pdf转换器 浏览:696
ajax调用java后台 浏览:905
活塞式压缩机常见故障 浏览:614
break算法 浏览:731