动态代理
java动态代理指在程序运行时,运用反射机制动态创建而成。根据代理对象可以区分为两种代理方式,接口代理和对象代理.接口代理由java.lang.reflect.Proxy类来完成,Proxy 提供用于创建动态代理类和实例的静态方法。对象代理方式通过CGLib字节码技术完成。
实现方式一:Proxy代理方式
SayHello 接口
/**
* 接口(动态代理针对接口的代理类)
* @author daiyang
*
*/
public interface SayHello {
void doSomeThing();
void saySomeThing();
}
实现SayHello的类
public class Waitress implements SayHello{
@Override
public void doSomeThing() {
System.out.println("吃点什么?");
}
@Override
public void saySomeThing() {
System.out.println("今天天气真好");
}
}
动态代理类WaitressProxy
public class WaitressProxy implements InvocationHandler{
private Waitress waitress;
WaitressProxy(Waitress w){
this.waitress = w;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
if(method.getName().equals("doSomeThing")){
System.out.println("您好!");
}
Object invoke = method.invoke(waitress, args);
return invoke;
}
}
Demo类
public class Demo {
public static void main(String[] args) {
Waitress w = new Waitress();
WaitressProxy waitressProxy = new WaitressProxy(w);
SayHello newProxyInstance = (SayHello)Proxy.newProxyInstance(w.getClass().getClassLoader(),
w.getClass().getInterfaces() , waitressProxy);
newProxyInstance.doSomeThing();
newProxyInstance.saySomeThing();
}
}
JDK动态代理对象必须是接口的实现,这也是JDK动态代理的局限,而CGLib代理方式,不需要类是接口的实现,这种代理方式普遍地应用在Spring AOP框架中。
实现方式二:CGLib代理方式
waitress类
public class Waitress {
public void doSomeThing(){
System.out.println("吃点什么?");
}
public void saySomeThing() {
System.out.println("今天天气真好");
}
}
Demo类
public class CGLib {
public static void main(String[] args) {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(Waitress.class);
enhancer.setUseCache(false);
enhancer.setCallback(new MethodInterceptor() {
@Override
public Object intercept(Object obj, Method method, Object[] args,
MethodProxy proxy) throws Throwable {
System.out.println("你好!");
Object result = proxy.invokeSuper(obj, args);
return result;
}
});
Waitress waitress = (Waitress)enhancer.create();
waitress.doSomeThing();
waitress.saySomeThing();
}
}