重学JAVA基础(三):动态代理
1.接口
public interface Hello {
public void sayHello();
}
2.实例类
public class Hello2 {
public void sayHello() {
System.out.println("hello world2!");
}
}
public class Hello3 extends Hello2{
}
public class HelloImpl implements Hello{
@Override
public void sayHello() {
System.out.println("hello world!");
}
}
3.JDK动态代理
ublic class JdkTest implements InvocationHandler{
private Object object;
@SuppressWarnings("unchecked")
public <T> T bind(Object obj){
this.object = obj;
return (T)Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
System.out.println("before sayHello");
method.invoke(object, null);
System.out.println("after sayHello");
return null;
}
public static void main(String[] args) {
JdkTest test = new JdkTest();
Hello hello = test.bind(new HelloImpl());
hello.sayHello();
}
}
4.cglib动态代理
public class CglibTest implements MethodInterceptor{
private Object obj;
/**
* 普通接口类代理
* @author tomsnail
* @date 2015年4月2日 上午10:36:10
*/
public <T> T instance(T obj){
this.obj = obj;
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(this.obj.getClass());
enhancer.setCallback(this);
return (T)enhancer.create();
}
@Override
public Object intercept(Object arg0, Method arg1, Object[] arg2,
MethodProxy arg3) throws Throwable {
System.out.println("before sayHello");
arg3.invoke(obj, arg2);
System.out.println("after sayHello");
return null;
}
/**
* 无接口类代理
* @author tomsnail
* @date 2015年4月2日 上午10:35:58
*/
public <T> T instanceObject(T obj){
T t = (T)Enhancer.create(obj.getClass(),new MethodInterceptor(){
@Override
public Object intercept(Object arg0, Method arg1, Object[] arg2,
MethodProxy arg3) throws Throwable {
System.out.println("hello2 proxy");
return arg3.invokeSuper(arg0, arg2);
}
});
return t;
}
/**
* 无接口类代理
* @author tomsnail
* @date 2015年4月2日 上午10:35:58
*/
public <T> T instanceSuperObject(T obj){
T t = (T)Enhancer.create(obj.getClass(),NoOp.INSTANCE);//无任何代理时,调用父类方法实现
return t;
}
public static void main(String[] args) {
CglibTest test = new CglibTest();
Hello hello = test.instance(new HelloImpl());
hello.sayHello();
Hello2 hello2 = test.instanceObject(new Hello2());//无接口类的动态代理
hello2.sayHello();
Hello2 hello3 = test.instanceSuperObject(new Hello3());//子类没有重写父类方法的动态代理
hello3.sayHello();
}
}
5.小小总结一下
JDK的动态代理只能通过接口进行处理,如果没有接口的,会很难处理。cglib没有这一限制。
还有就是性能,我看见一篇网上已经有了对比,在jdk7/8与cglib相比,反而jdk的性能很好,见http://www.cnblogs.com/haiq/p/4304615.html
重学JAVA基础(三):动态代理的更多相关文章
- 重学 Java 设计模式:实战代理模式「模拟mybatis-spring中定义DAO接口,使用代理类方式操作数据库原理实现场景」
作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 难以跨越的瓶颈期,把你拿捏滴死死的! 编程开发学习过程中遇到的瓶颈期,往往是由于看不 ...
- Java基础-JDK动态代理
JDK的动态代理依靠接口实现 代理模式 代理模式是常用的java设计模式,他的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息.过滤消息.把消息转发给委托类,以及事后处理消息等.代 ...
- Java基础-CGLIB动态代理
JDK的动态代理机制只能代理实现了接口的类,而不能实现接口的类就不能实现JDK的动态代理,cglib是针对类来实现代理的,他的原理是对指定的目标类生成一个子类,并覆盖其中方法实现增强,但因为采用的是继 ...
- Java基础加强——动态代理
代理模式: 为其他对象提供一种代理以控制对这个对象的访问. 代理模式主要分为两类: 静态代理:由程序员创建或特定工具自动生成源代码,再对其编译.在程序运行前,代理类的.class文件就已经存在了. ...
- Java基础-jdk动态代理与cglib动态代理区别
JDK动态代理 此时代理对象和目标对象实现了相同的接口,目标对象作为代理对象的一个属性,具体接口实现中,可以在调用目标对象相应方法前后加上其他业务处理逻辑. 代理模式在实际使用时需要指定具体的目标对象 ...
- 重学JAVA基础(八):锁的基本知识
1.线程状态 如上图,当我们新建一个线程,并start后,其实不一定会马上执行,因为只有操作系统调度了我们的线程,才能真正进行执行,而操作系统也随时可以运行其他线程,这时线程又回到可运行状态.这个过程 ...
- 重学JAVA基础(二):Java反射
看一下百度的解释: JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性:这种动态获取的信息 ...
- 重学JAVA基础(五):面向对象
1.封装 import java.util.Date; public class Human { protected String name; protected BirthDay birthDay; ...
- 重学JAVA基础(一):PATH和CLASSPATH
我想大多数Java初学者都会遇到的问题,那就是怎么配置环境,执行java -jar xxx.jar 都会报NoClassDefFindError,我在最开始学习的时候,也遇到了这些问题. 1.PAT ...
随机推荐
- Chrome自带恐龙小游戏的源码研究(五)
在上一篇<Chrome自带恐龙小游戏的源码研究(四)>中实现了障碍物的绘制及移动,从这一篇开始主要研究恐龙的绘制及一系列键盘动作的实现. 会眨眼睛的恐龙 在游戏开始前的待机界面,如果仔细观 ...
- 深入Asyncio(九)异步生成器
Async Generators:yield inside async def functions 如果在async def中使用yield会发生什么,答案就是生成一个异步生成器函数,如果有生成器.协 ...
- implode 函数 把数组拼接成字符串
$array( '0'=>1, '1'=>5, '2'=>5 ); $str=imploade(',',$array); echo str;//输出1,5,3
- C语言--循环结构
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvenVveW91MTMxNA==/font/5a6L5L2T/fontsize/400/fill/I0JBQk ...
- 【峰回路转】Excel技巧百例 08.计算两个日期的差值
在Excel中假设高速计算两个日期之间的差? 比如A日期为:2012/3/12 B日期为:2015/7/29 那么这两个日期之间差几年,差几个月.差多少天? 我们使用DateDif 函数来处理. ...
- UITextView的一些技巧
1.在指定位置插入字符串: NSMutableString *TextViewStr=[[NSMutableString alloc] initWithString:TextView.text ...
- Chernoff-Hoeffding inequality -- Chernoff bounds, and some applications
https://www.cs.utah.edu/~jeffp/teaching/cs5955/L3-Chern-Hoeff.pdf [大数据-通过随机过程降维 ] When dealing with ...
- 性能测试--Jmeter的Non GUI模式、集群
Jmeter的Non GUI模式.集群 一.Non GUI模式 1.一般情况下在NonGUI模式下运行jmeter,有两个好处: 节省系统资源,能够产生更大的负载 可以通过命令行参数对测试场景进行更精 ...
- 我的Java开发学习之旅------>工具类:Java使用正则表达式分离出字符串中的中文和英文
今天看到一个工具类使用正则表达式将一大段字符串中的中文和英文都分离出来了,在此记录一下,读者可以收藏! import java.util.ArrayList; import java.util.Col ...
- "静态方法里仅仅能调用静态变量和静态方法"具体解释
静态方法里能够调用静态方法和静态变量,同一时候也能调用非静态方法和非静态变量. public class Test { public Test() {}; public Test(int i) {th ...