概述
黑马程序员:Java基础总结
静态代理模式&动态代理
ASP.Net+Android+IO开发
、
.Net培训
、期待与您交流!
静态代理模式
public
class
Ts {
public
static
void
main(String[] args)
throws
Exception {
// 通过中介公司生产一批衣服
ClothingProduct cp =
new
ProxCompany(
new
LiNingCompany());
cp.productClothing();
}
}
/**
* 定义生产一批衣服功能的接口
*
*/
interface
ClothingProduct {
void
productClothing();
// 有生产一批衣服的功能
}
/**
*
* 代理类:中介公司
*
*/
class
ProxCompany
implements
ClothingProduct {
private
ClothingProduct
cp
;
// 中介公司不会生产衣服,需要找一家真正能生产衣服的公司
ProxCompany(ClothingProduct cp) {
super
();
this
.
cp
= cp;
}
@Override
public
void
productClothing() {
System.
out
.println(
"收取1000块钱的中介费"
);
cp
.productClothing();
}
}
/**
*
* 李宁公司是生产服装的目标类
*
*/
class
LiNingCompany
implements
ClothingProduct {
@Override
public
void
productClothing() {
System.
out
.println(
"生产一批衣服。。。。"
);
}
}
上面程序的做法,使用的模式是静态代理模式
静态代理模式在现实编程中的弊端:
它的特征是代理类和目标对象的类都是在编译期间确定下来的,不利于程序上的扩展,上面示例中,如果客户还想找一个“生产一批鞋子”的工厂,那么还需要新增加一个代理类和一个目标类。如果客户还需要很多其他的服务,就必须一一的添加代理类和目标类。那就需要写很多的代理类和目标类
java.lang.reflect
类 Proxy
类 Proxy
Proxy
提供用于创建动态代理类和实例的静态方法,它还是由这些方法创建的所有动态代理类的超类。
构造方法摘要 | |
---|---|
protected | Proxy(InvocationHandler h) 使用其调用处理程序的指定值从子类(通常为动态代理类)构建新的 Proxy 实例。 |
字段摘要 | |
---|---|
protected InvocationHandler | h 此代理实例的调用处理程序。 |
方法摘要 | |
---|---|
static InvocationHandler | getInvocationHandler(Object proxy) 返回指定代理实例的调用处理程序。 |
static Class<?> | getProxyClass(ClassLoader loader, Class<?>... interfaces) 返回代理类的 java.lang.Class 对象,并向其提供类加载器和接口数组。 |
static boolean | isProxyClass(Class<?> cl) 当且仅当指定的类通过 getProxyClass 方法或 newProxyInstance 方法动态生成为代理类时,返回 true。 |
static Object | newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) 返回一个指定接口的代理类实例,该接口可以将方法调用指派到指定的调用处理程序。 |
每个代理实例都具有一个关联的调用处理程序。对代理实例调用方法时,将对方法调用进行编码并将其指派到它的调用处理程序的 invoke
方法。
| |
---|---|
Object | invoke(Object proxy, Method method, Object[] args) 在代理实例上处理方法调用并返回结果。
|
import
java.lang.reflect.InvocationHandler;
import
java.lang.reflect.Method;
import
java.lang.reflect.Proxy;
import
java.util.ArrayList;
import
java.util.Collection;
public
class
Ts {
public
static
void
main(String[] args)
throws
Exception {
ArrayList test =
new
ArrayList();
// 代理只可以强转换成接口
Collection list = (Collection ) getProxy(test,
new
MyAdvice());
list.add(123);
list.add(123);
System.
out
.println(list);
}
public
static
Object getProxy(
final
Object target,
final
Advice adv)
/* 终态是因为内部类调用 */
{
// 返回一个指定接口的代理类实例 obj
Object obj = Proxy. newProxyInstance(
// 定义代理类的类加载器
target.getClass().getClassLoader(),
// 代理类要实现的接口列表
target.getClass().getInterfaces(),
// 指派方法调用的调用处理程序 InvocationHandler
new
InvocationHandler() {
@Override
public
Object invoke(Object proxy, Method method,
Object[] args)
throws
Throwable {
adv.begintime(method);
//target目标 ,args方法参数,调用原来的方法
Object retVal = method.invoke(target, args);
adv.endtime(method);
return
retVal;
}
});
return
obj;
}
}
//插入的建议接口
interface
Advice {
void
begintime(Method method);
void
endtime(Method method);
}
//我的建议
class
MyAdvice
implements
Advice {
@Override
public
void
begintime(Method method) {
Long time = System. currentTimeMillis();
System.
out
.println(method.getName() + time);
}
@Override
public
void
endtime(Method method) {
Long time = System. currentTimeMillis();
System.
out
.println(method.getName() + time);
}
}
一个更巧妙的方法:自定义一个处理程序
public
class
Ts {
public
static
void
main(String[] args)
throws
Exception {
ProxyHandler handler=
new
ProxyHandler();
ClothingProduct cp2=(ClothingProduct)handler.newProxyInstance(
new
LiNingCompany());
cp2.productClothing();
}
}
class
ProxyHandler
implements
InvocationHandler {
/* 目标对象 */
private
Object
target
;
/* 创建目标对象的代理对象 */
public
Object newProxyInstance(Object target) {
this
.
target
= target;
/*
* 第一个参数:定义代理类的类加载器
* 第二个参数:代理类要实现的接口 列表
* 第三个参数:指派方法调用的调用处理程序
*/
return
Proxy.newProxyInstance(
this
.
target
.getClass().getClassLoader(),
this
.
target
.getClass().getClasses(),
this
);
}
@Override
public
Object invoke(Object proxy, Method method, Object[] args)
throws
Throwable {
Object result =
null
;
System.
out
.println(
"目标对象上的方法调用之前可以添加其他代码。。。"
);
result = method.invoke(
this
.
target
, args);
// 通过反射调用目标对象上的方法
System.
out
.println(
"目标对象上的方法调用之后可以添加其他代码。。。"
);
return
result;
}
}
ASP.Net+Android+IO开发
、
.Net培训
、期待与您交流!
最后
以上就是体贴人生为你收集整理的黑马程序员:Java基础总结----静态代理模式&动态代理的全部内容,希望文章能够帮你解决黑马程序员:Java基础总结----静态代理模式&动态代理所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复