动态代理模式(what,why,how)
什么是动态代理
动态代理是JDK1.4版本以后提供的性能,主要是利用JAVA反射技术,而动态的进行JAVA对象的加载。和动态代理有关的有两个类
1.interface InvocationHandler :
Object invoke(Object proxy, Method method, Object[] args) 只这一个方法,后面再说
2.class Proxy
真正表示动态代理的类,提供两个静态方法:
a:Class<?> getProxyClass(ClassLoader loader, Class<?>[] interface) :
用来产生代理类,参数要提供interface数组,它会生成这些interface的“虚拟实现”,
用来冒充真实的对象。
b:Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)
产生代理对象,多了InvocationHandler参数(只是InvocationHandler接口的实现类),
它与代理对象关联,当请求分发到代理对象后,会自动执行h.invoke(...)方法,
invoke方法就是我们用来做N多事情的地方 -_-。
Object invoke(Object proxy, Method method, Object[] args) 只这一个方法,后面再说
2.class Proxy
真正表示动态代理的类,提供两个静态方法:
a:Class<?> getProxyClass(ClassLoader loader, Class<?>[] interface) :
用来产生代理类,参数要提供interface数组,它会生成这些interface的“虚拟实现”,
用来冒充真实的对象。
b:Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)
产生代理对象,多了InvocationHandler参数(只是InvocationHandler接口的实现类),
它与代理对象关联,当请求分发到代理对象后,会自动执行h.invoke(...)方法,
invoke方法就是我们用来做N多事情的地方 -_-。
为什么要用动态代理
在sping中的面向切面编程中主要就是利用到了动态代理技术,有时候我们需要对类的作用进行扩充可以有的方法是继承和组合,但是这样的话类的耦合度太大,不利用程序的扩展和维护所有我们需要动态代理技术来对方法进行扩充。还有就是hibernate种有时我们并不一定要真正的创建对象可能只是需要对象的引用这样我们就需要动态代理技术的实现。
如何进行动态代理:
动态代理类:
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class DynaProxyHello implements InvocationHandler {
private Object delegate;
public Object bind (Object delegate)
{
this.delegate = delegate;
return Proxy.newProxyInstance(this.delegate.getClass().getClassLoader(), this.delegate.getClass().getInterfaces(), this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)throws Throwable {
Object result = null;
try {
Logger.logging(Level.INFO, method.getName() + " Method Start!");
result = method.invoke(this.delegate, args);
Logger.logging(Level.DEBUGE, method.getName() + " Method end !");
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
}
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class DynaProxyHello implements InvocationHandler {
private Object delegate;
public Object bind (Object delegate)
{
this.delegate = delegate;
return Proxy.newProxyInstance(this.delegate.getClass().getClassLoader(), this.delegate.getClass().getInterfaces(), this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)throws Throwable {
Object result = null;
try {
Logger.logging(Level.INFO, method.getName() + " Method Start!");
result = method.invoke(this.delegate, args);
Logger.logging(Level.DEBUGE, method.getName() + " Method end !");
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
}
需要实现的共同接口:
public interface Ihello {
void sayHello(String name);
void sayGoodBye(String name);
}
hello类:
public class Hello implements Ihello{
public void sayHello(String name) {
System.out.println("Hello " + name);}
public void sayGoodBye(String name) {
System.out.println(name+" GoodBye!");}
void sayHello(String name);
void sayGoodBye(String name);
}
hello类:
public class Hello implements Ihello{
public void sayHello(String name) {
System.out.println("Hello " + name);}
public void sayGoodBye(String name) {
System.out.println(name+" GoodBye!");}
}
增加的切面也就是前后记录时间:
import java.util.Date;
public class Logger {
public static void logging(Level level, String context) {
if (level.equals(Level.INFO)) {
System.out.println(new Date().toLocaleString() + " " + context);}
if (level.equals(Level.DEBUGE)) {System.err.println(new Date() + " " + context);
}
}
}
public class Logger {
public static void logging(Level level, String context) {
if (level.equals(Level.INFO)) {
System.out.println(new Date().toLocaleString() + " " + context);}
if (level.equals(Level.DEBUGE)) {System.err.println(new Date() + " " + context);
}
}
}
public enum Level {
INFO,DEBUGE;
}
主函数类:
public class Test {
public static void main(String[] args) {
Ihello hello = (Ihello) new DynaProxyHello().bind(new Hello());
Ihello hello_two = (Ihello) new DynaProxyHello().bind(new Hello_two());
hello.sayHello("Double J");
hello.sayGoodBye("Double J");
hello_two.sayHello("xiaotao");
hello_two.sayGoodBye("xiaotao小涛");
}
}
public class Test {
public static void main(String[] args) {
Ihello hello = (Ihello) new DynaProxyHello().bind(new Hello());
Ihello hello_two = (Ihello) new DynaProxyHello().bind(new Hello_two());
hello.sayHello("Double J");
hello.sayGoodBye("Double J");
hello_two.sayHello("xiaotao");
hello_two.sayGoodBye("xiaotao小涛");
}
}