java中的代理分为哪两种,java中什么是代理
如何解决写爬虫IP受阻的问题?立即使用。
我们先简单解释一下什么是代理模式。
代理是一种设计模式,它提供了另一种访问目标对象的方式。也就是说,目标对象是通过代理对象访问的。这样做的优点是,在实现目标对象的基础上,可以增强附加的功能操作,也就是说,可以扩展目标对象的功能。
这里有一个用在编程上的思路:不要随意修改别人已经写好的代码或者方法。如果需要修改,可以通过代理来扩展方法。
我们举个例子来说明代理的作用:假设我们要请一个明星,那么我们不直接联系明星,而是联系明星的经纪人来达到同样的目的。一个明星就是一个目标对象,他只需要负责活动中的节目,其他琐事就交给他的经纪人(代理人)去解决。这是现实中代理思想的一个例子。
如下所示:
代理模式的关键点是代理对象和目标对象。代理对象是目标对象的扩展,将调用目标对象。
1.1.静态代理
使用静态代理时,需要定义接口或父类,代理对象和代理对象实现同一个接口或继承同一个父类。
这里有一个例子来解释:
模拟动作,定义一个保存动作的接口:IUserDao.java,然后目标对象实现这个接口的方法UserDao.java。此时,如果使用静态代理模式,则需要在代理对象(UserDaoProxy.java)中实现IUserDao接口。调用时,通过调用代理对象的方法来调用目标对象。
注意,代理对象和目标对象应该实现相同的接口,然后通过调用相同的方法来调用目标对象的方法。
代码示例:
接口:IUserDao.java
/**
*接口
*/公共接口IUserDao { void save();
}目标对象:UserDao.java
/**
*接口实现
*目标对象
*/public类UserDao实现IUserDao { public void save() {
System.out.println( -数据已保存!- );
}
}经纪人:UserDaoProxy.java
/**
*代理对象,静态代理
*/公共类userdao代理实现I userdao {//接收并保存目标对象
私有IUserDao目标;public UserDaoProxy(IUserDao target){ this . target=target;
} public void save() {
System.out.println(开始事务.);
target . save();//执行目标对象的方法
System.out.println(提交事务.);
}
}(学习视频分享:java视频教程)
班级:App.java
/**
*测试类别
*/public class app { public static void main(string[]args){//目标对象
UserDao target=new UserDao();//代理对象,将目标对象传递给代理对象,建立代理关系。
UserDaoProxy proxy=new UserDaoProxy(target);
proxy . save();//执行代理的方法。
}
}静态代理摘要:
1.您可以扩展目标功能,而无需修改目标对象的功能。
2.缺点:
因为代理对象需要实现和目标对象相同的接口,所以会有很多代理类,类太多了。同时,一旦方法被添加到接口中,目标对象和代理对象都应该被维护。
静态代理的缺点怎么解决?答案是可以使用动态代理。
1.2.动态代理
动态代理具有以下特征:
1.代理对象,不需要实现接口。
2.代理对象的生成是利用JDK的API在内存中动态构建代理对象(我们需要指定创建代理对象/目标对象的接口类型)。
3.动态代理也称为JDK代理和接口代理。
用于在JDK生成代理对象的API
代理包:java.lang.reflect.Proxy
JDK只需要使用newProxyInstance方法来实现代理,但是这个方法需要接收三个参数。完整的写法是:
静态对象new proxy instance(Class loader loader,Class?[]接口,调用处理程序h)注意这个方法在代理类中是静态的,收到的三个参数是:
Classloader,指定当前目标对象使用类加载器,获取加载器的方法是固定的。
班级?[] interfaces:目标对象实现的接口的类型,该类型以通用的方式确认。
InvocationHandler h:事件处理,当执行目标对象的方法时,会触发事件处理程序的方法,将当前执行的目标对象的方法作为参数传入。
代码示例:
接口IUserDao.java和接口实现类(目标对象UserDao)是相同的,没有修改。在此基础上,添加一个代理工厂类(ProxyFactory.java),在这个地方编写代理类,然后在测试类(需要使用代理的代码)中建立目标对象和代理对象的连接,然后在代理对象中替换同名的方法。
代理类别:ProxyFactory.java
/**
*创建一个动态代理对象
*动态代理不需要实现接口,但是需要指定接口类型。
*/public class ProxyFactory{ //维护目标对象
私有对象目标;public ProxyFactory(对象目标){ this.target=target
}//为目标对象生成代理对象
公共对象getProxyInstance(){ return proxy . newproxyinstance(
target.getClass()。getClassLoader(),
target.getClass()。getInterfaces(),new invocation handler(){ @ Override
公共对象调用(对象代理、方法方法、对象[]参数)抛出Throwable {
System.out.println(启动事务2 );//执行目标对象方法
object return value=method . invoke(target,args);
System.out.println(提交事务2 );返回returnValue
}
}
);
}
}测试类:App.java
/**
*测试类别
*/public class app { public static void main(string[]args){//目标对象
IUserDao target=new UserDao();//[原始类型class cn . it cast . b _ dynamic . userdao]
system . out . println(target . getclass());//给定目标对象,创建代理对象。
IUserDao proxy=(IUserDao)new proxy factory(target)。getProxyInstance();//classproxy 0在内存中动态生成代理对象
system . out . println(proxy . getclass());//执行方法[代理对象]
proxy . save();
}
}摘要:
代理不需要实现接口,但是目标对象必须实现接口,否则不能使用动态代理。
1.3.Cglib代理
上述静态代理和动态代理模式要求目标对象是实现接口的目标对象,但有时目标对象只是不实现任何接口的单个对象。这时,你可以使用子类化目标对象的方法来实现代理。这种方法称为Cglib代理。
Cglib代理,也叫子类代理,在内存中构建一个子类对象,扩展目标对象的功能。
JDK的动态代理有一个限制,即使用动态代理的对象必须实现一个或多个接口。如果想代理不实现接口的类,可以用Cglib实现。Cglib是一个强大的高性能代码生成包,可以在运行时扩展java类和实现java接口。它被很多AOP框架广泛使用,比如Spring AOP和synaop。拦截Cglib包的底层,为它们提供了方法,就是通过使用一个小而块的字节码处理框架ASM来转换字节码,生成新的类。不鼓励直接使用ASM,因为这需要你熟悉JVM的内部结构,包括类文件的格式和指令集。
Cglib子类代理的实现方法:
1.需要导入cglib的jar文件,但是Spring的核心包已经包含Cglib函数,直接导入Spring-core-3 . 2 . 5 . jar就可以了。
2.引入函数包后,可以在内存中动态构建子类。
3.代理的类别不能是最终的,否则将会报告错误。
4.如果目标对象的方法是final/static,则不会被拦截,即不会执行目标对象的附加业务方法。
代码示例:
对象类别:UserDao.java
/**
*目标对象,它不实现任何接口。
*/public class UserDao { public void save(){
System.out.println( -数据已保存!- );
}
}Cglib代理工厂:ProxyFactory.java
/**
* Cglib子类代理工厂
* 对数据层在内存中动态构建一个子类对象
*/公共类代理工厂实现MethodInterceptor{ //维护目标对象
私有对象目标;公共代理工厂(对象目标){ this.target=target
} //给目标对象创建一个代理对象
公共对象getProxyInstance(){ //1 .工具类
增强剂en=新增强子();//2.设置父类
恩。设置超类(目标。getclass());//3.设置回调函数
恩。设置回调(this);//4.创建子类(代理对象)
返回恩。create();
} @覆盖
公共对象拦截(对象对象,方法方法,对象[]参数,方法代理代理)抛出可投掷的
System.out.println(开始事务.);//执行目标对象的方法
对象返回值=方法。invoke(target,args);
System.out.println(提交事务.);返回返回值
}
}测试类:
/**
* 测试类
*/公共类应用{ @测试
公共空的测试(){ //目标对象
UserDao target=new UserDao();//代理对象
UserDao proxy=(UserDao)新代理工厂(目标).getProxyInstance();//执行代理对象的方法
代理。save();
}
}在春天的面向切面编程编程中:
如果加入容器的目标对象有实现接口,用爪哇岛开发工具包代理
如果目标对象没有实现接口,用字节码生成代理
相关推荐:java入门教程以上就是爪哇岛的三种代理模式分别是什么的详细内容,更多请关注我们其它相关文章!
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。