Java 动态代理机制分析及扩展,第 2 部分

点击查看原文
相信通过阅读“Java 动态代理机制分析和扩展,第 1 部分”,读者已经对 Java 动态代理机制有了一定的了解。本文将在上一篇的基础上,针对 Java 动态代理仅支持接口代理这一局限进行扩展,实现对类的代理。

本文希望将 Java 动态代理机制从接口扩展到类,使得类能够享有与接口类似的动态代理支持。

设计及特点

新扩展的类名为 ProxyEx,将直接继承于 java.lang.reflect.Proxy,也声明了与原 Proxy 类中同名的 public 静态方法,目的是保持与原代理机制在使用方法上的完全一致。
图 1. ProxyEx 类继承图

阅读全文 »

Java 动态代理机制分析及扩展,第 1 部分

点击查看原文
本文通过分析 Java 动态代理的机制和特点,解读动态代理类的源代码,并且模拟推演了动态代理类的可能实现,向读者阐述了一个完整的 Java 动态代理运作过程,希望能帮助读者加深对 Java 动态代理的理解和应用。

引言

Java 动态代理机制的出现,使得 Java 开发人员不用手工编写代理类,只要简单地指定一组接口及委托类对象,便能动态地获得代理类。代理类会负责将所有的方法调用分派到委托对象上反射执行,在分派执行的过程中,开发人员还可以按需调整委托类对象及其功能,这是一套非常灵活有弹性的代理框架。通过阅读本文,读者将会对 Java 动态代理机制有更加深入的理解。本文首先从 Java 动态代理的运行机制和特点出发,对其代码进行了分析,推演了动态生成类的内部实现。

代理:设计模式

代理是一种常用的设计模式,其目的就是为其他对象提供一个代理以控制对某个对象的访问。代理类负责为委托类预处理消息,过滤消息并转发消息,以及进行消息被委托类执行后的后续处理。
图 1. 代理模式

阅读全文 »

如何在墙内反代 Gravatar 显示博客头像

生命不息,折腾不止

Gravatar 即全球通用头像 (Globally Recognized Avatar) 服务,用户只要在上面上传了自己的头像,那么在所有支持的网站上发帖时,只要提供与这个头像关联的 Email,就可以显示出自己的 Gravatar 头像。可以说是「一次上传,全网通用」~~

可惜国内的网络环境实在一言难尽,Gravatar 常年都处于无法访问的状态,所以本站一直都是用 v2ex 提供的 CDN 镜像,然而,就在前两周,v2ex 也被墙了,emm… 因为不想再白嫖其他的国内镜像,因此开始考虑自己动手搭建。这个事情其实挺简单的,网上随便搜索一下就有答案,只要有一台墙外的 VPS,用 nginx 给 Gravatar 做个反向代理就好。

但是,如果你的主机在墙内呢,怎么办?

阅读全文 »

「译」LINQ: Building an IQueryable Provider - Part IX: Removing redundant subqueries

英文原文是Matt Warren发表在MSDN Blogs的系列文章之一,英文渣渣,翻译不供参考,请直接看原文

现在写一篇新的文章的时间变得越来越长,似乎已经成了一个趋势了。要怪就怪电视编剧罢工吧,嗯。

Cleaning up the Mess

我之前说过要把我们的查询翻译器不断累积下来的不必要的嵌套select表达式给清理掉。对于人类的大脑来说,简化一条SQL是一件很简单的事情。但是,对于计算机程序而言,保留这些无用的嵌套查询却更加容易,毕竟它们的语义是一样的。再者,我们希望少写一点代码的心情也无可厚非。

我们很容易就能从一条带有where子句的简单的查询中看出问题所在。

1
2
3
from c in db.Customers
where c.Country == "UK"
select c;
阅读全文 »

「译」LINQ: Building an IQueryable Provider - Part VIII: OrderBy

英文原文是Matt Warren发表在MSDN Blogs的系列文章之一,英文渣渣,翻译不供参考,请直接看原文

距离上篇文章,又已经过了几个星期。我感觉大家可能已经迫不及待想要看到下篇文章了。你们的提供程序本来应该已经完成,可以拿到外面去惊艳众人,但是现在却放在角落里吃灰。

Implementing OrderBy

今天的话题是翻译order-by子句。幸运的是,进行排序操作的方式只有一种,那就是LINQ的排序操作符。但坏消息是,有四种不同的操作符。

使用查询的语法来写一条排序的查询是很简单的,只需一个子句就好。

1
2
3
var query = from c in db.Customers
orderby c.Country, c.City
select c;

但是,将上面的查询转换为方法调用的形式的话,所涉及到的就不止是一个LINQ操作符了。

阅读全文 »

「译」LINQ: Building an IQueryable Provider - Part VII: Join and SelectMany

英文原文是Matt Warren发表在MSDN Blogs的系列文章之一,英文渣渣,翻译不供参考,请直接看原文

从上篇文章到现在,已经有好几个星期没有更新了。希望在这段时间里面你们也有用自己的时间来探索如何构建自己的提供程序。我也一直在关注别人的各种各样的“LINQ to XXX”的项目,感觉都很不错。今天我将向你们介绍如何在我的提供程序中添加连接查询的功能,比起只支持select和where来,支持join将能提供更多有趣的用法。

Implementing Join

在LINQ中有许多种不同的连接查询的写法。在C♯或者VB中,如果写了多个from子句,将会产生笛卡尔积的结果,但如果把一个子句的键和另一个子句的键匹配起来,所得到的就是一个连接查询。

1
2
3
4
var query = from c in db.Customers
from o in db.Orders
where c.CustomerID == o.CustomerID
select new { c.ContactName, o.OrderDate };
阅读全文 »

「译」LINQ: Building an IQueryable Provider - Part VI: Nested queries

英文原文是Matt Warren发表在MSDN Blogs的系列文章之一,英文渣渣,翻译不供参考,请直接看原文

你又以为这个系列已经完成,所以我已经转移到其他阵地上去了吗?因为Select操作工作得非常好,所以你以为前面所讲的就是你构建自己的IQueryable提供程序所需要了解的所有内容了吗?哈!还有很多需要学习的呢,而且,Select操作还是有些漏洞。

Finishing Select

有漏洞?怎么可能?我把你当成从来不会出错的微软大神,但是你却说你给我的是劣质的代码?我把已经把代码复制粘贴到产品里,老板已经说了下周一就启动!你怎么能这么做?(喘气)

放心啦,不是什么严重的漏洞,只是一点小小的缺陷而已。

回想一下,在上篇文章中,我建了四种表达式节点,Table,Column,Select和Projection,它们工作十分良好,不是吗?有漏洞的地方是我没有考虑到所有可以写查询表达式的地方。我考虑到的只是最明显的Projection节点出现在查询表达式树顶的情况。毕竟,因为我只支持SelectWhere,所以最后一个操作必定是这两者之一。我的代码就是这样假设的。

这不是问题所在。

问题是Projection节点也有可能出现在选择器表达式里面,例如,看下面的查询。

1
2
3
4
5
6
7
var query = from c in db.Customers
select new {
Name = c.ContactName,
Orders = from o in db.Orders
where o.CustomerID == c.CustomerID
select o
};
阅读全文 »

「译」LINQ: Building an IQueryable Provider - Part V: Improved Column binding

英文原文是Matt Warren发表在MSDN Blogs的系列文章之一,英文渣渣,翻译不供参考,请直接看原文

在前面四篇文章里面,我构建了一个LINQ IQueryable提供程序,它可将Queryable.WhereQueryable.Select两个标准查询操作符翻译成SQL,并通过ADO送到数据库中去执行。虽然已经做得很不错,但是这个提供程序还是有一些漏洞,而且我还没有提到其他的查询操作,比如OrderBy和Join等等。如果认为用户写出的查询都像我的demo一样这么理想化的话,你可能就会掉进大坑里去。

阅读全文 »

「译」LINQ: Building an IQueryable Provider - Part IV: Select

英文原文是Matt Warren发表在MSDN Blogs的系列文章之一,英文渣渣,翻译不供参考,请直接看原文

我是个完美主义者,我做了一个仅仅可以将Where方法翻译为SQL的LINQ提供程序,它可以执行查询并且将结果转换为对象,但我觉得还不够完美,相信你们也这么认为。你们也许想知道从一个简单的示例程序演变成一个成熟的ORM系统的所有细节。但是我并不会做到这个程度,即便如此,我还是觉得,我可以通过介绍如何实现Select操作来覆盖到一些通用的知识点,以方便你编写自己的提供程序。

阅读全文 »

「译」LINQ: Building an IQueryable Provider - Part III: Local variable references

英文原文是Matt Warren发表在MSDN Blogs的系列文章之一,英文渣渣,翻译不供参考,请直接看原文

第三部分?难道上篇文章还没有讲完吗?我不是做了一个可以翻译和执行SQL命令并且返回一个对象序列的提供程序了吗?

确实如此,但是也仅仅如此而已。我写的那个提供程序的功能实在太弱,它只支持一种查询操作符与少量比较运算符。然而,真正的查询提供程序必须要提供更多的查询操作与更复杂的交互方式。我的查询提供程序甚至还不支持将数据投影为其他形式。

Translating Local Variable References

你知道当查询里面引用了局部变量的时候会发生什么吗?不知道?

1
2
string city = "London";
var query = db.Customers.Where(c => c.City == city);

去试试翻译上面这句查询的时候会出现什么情况吧,我等着你的结果。

阅读全文 »