1.简介
Proxy 提供用于创建动态代理类和实例的静态方法
(1)动态代理类的属性
- 代理类是公共的、最终的,而不是抽象的
- 未指定代理类的非限定名称。但是,以字符串
"$Proxy"
开头的类名空间应该为代理类保留 - 代理类扩展
java.lang.reflect.Proxy
代理类会按同一顺序准确地实现其创建时指定的接口
如果代理类实现了非公共接口,那么它将在与该接口相同的包中定义。否则,代理类的包也是未指定的。注意,包密封将不阻止代理类在运行时在特定包中的成功定义,也不会阻止相同类加载器和带有特定签名的包所定义的类
由于代理类将实现所有在其创建时指定的接口,所以对其
Class
对象调用getInterfaces
将返回一个包含相同接口列表的数组(按其创建时指定的顺序),对其Class
对象调用getMethods
将返回一个包括这些接口中所有方法的Method
对象的数组,并且调用getMethod
将会在代理接口中找到期望的一些方法如果
Proxy.isProxyClass
方法传递代理类(由Proxy.getProxyClass
返回的类,或由Proxy.newProxyInstance
返回的对象的类),则该方法返回 true,否则返回 false代理类的
java.security.ProtectionDomain
与由引导类加载器(如java.lang.Object
)加载的系统类相同,原因是代理类的代码由受信任的系统代码生成。此保护域通常被授予java.security.AllPermission
每个代理类都有一个可以带一个参数(接口
InvocationHandler
的实现)的公共构造方法,用于设置代理实例的调用处理程序。并非必须使用反射 API 才能访问公共构造方法,通过调用Proxy.newInstance
方法(将调用Proxy.getProxyClass
的操作和调用带有调用处理程序的构造方法结合在一起)也可以创建代理实例
(2)冲突处理
- 不同的接口有相同的方法声明:第一个实现接口的Method对象将被传递
- 接口中有方法声明与java.lang.Object 的
hashCode
、equals
或toString
方法相同:java.lang.Object 的Method对象将被传递,换句话说,java.lang.Object
公共的非最终方法理论上在所有代理接口之前
3.实例
(1)TargetInterface
package com.siyuan.designmodel.aop;
public interface TargetInterface {
void doSomething();
String toString();
}
(2)TargetInterface1
package com.siyuan.designmodel.aop;
public interface TargetInterface1 {
void doSomething();
}
(3)Target
package com.siyuan.designmodel.aop;
public class Target implements TargetInterface, TargetInterface1 {
public void doSomething() {
System.out.println("do something...");
}
public String toString() {
return "Target.toString()";
}
}
(4)MyHandler
package com.siyuan.designmodel.aop;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class MyHandler implements InvocationHandler {
private Interceptor interceptor = new Interceptor();
private Object target;
public void setObj(Object target) {
this.target = target;
}
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
Object result = null;
interceptor.beforeDoSomething();
System.out.println(method);
method.invoke(target, args);
interceptor.afterDoSomething();
return result;
}
}
(5)Interceptor
package com.siyuan.designmodel.aop;
public class Interceptor {
public void beforeDoSomething(){
System.out.println("beforeDoSomething...");
}
public void afterDoSomething(){
System.out.println("afterDoSomething...");
}
}
(6)MyProxy
package com.siyuan.designmodel.aop;
import java.lang.reflect.Proxy;
public class MyProxy {
private MyHandler myHandler;
public void setMyHandler(MyHandler myHandler) {
this.myHandler = myHandler;
}
public Object getProxy(Object target){
myHandler.setObj(target);
return Proxy.newProxyInstance(MyProxy.class.getClassLoader(),
target.getClass().getInterfaces(),
myHandler);
}
}
(7)AOPTeset
package com.siyuan.designmodel.aop;
public class AOPTeset {
/**
* AOP模式优势:把一些可重用的代码通过切面实现,例如:Spring的事务管理
*/
public static void main(String[] args) {
Target target = new Target();
MyHandler myHandler = new MyHandler();
MyProxy myProxy = new MyProxy();
myProxy.setMyHandler(myHandler);
// TargetInterface proxy = (TargetInterface) myProxy.getProxy(target);
TargetInterface1 proxy = (TargetInterface1) myProxy.getProxy(target);
proxy.doSomething();
System.out.println(proxy.toString());
}
}
4.运行结果
beforeDoSomething...
public abstract void com.siyuan.designmodel.aop.TargetInterface.doSomething()
do something...
afterDoSomething...
beforeDoSomething...
public java.lang.String java.lang.Object.toString()
afterDoSomething...
null