代理模式的目的
- 需要隐藏委托者,使调用者只和代理打交道
- 不需要隐藏委托者,只需要在调用前后增加处理逻辑。
Java中规定,动态代理的对象必须要有实现一个接口,因为要动态创建这个接口的实现类。
在JDK1.5之后提供了"java.lang.reflect.Proxy",通过"Proxy"类的newProxyInstance静态方法创建一个接口的代理对象,这个代理对象可以调用接口的方法。
static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)
newProxyInstance方法返回一个代理对象,这个方法有3个参数:
- ClassLoader 指明接口类装载器,
- Class<?>[] 指明代理对象的接口,
- InvocationHandler 指明代理对象要做的事情。
//歌星接口
public interface StarMan {
String sing(String song);
}
//歌星A
public class StarA implements StarMan {
public void sing(String song){
System.out.println("歌星A演唱"+song);
}
}
//歌星B
public class StarB implements StarMan {
public void sing(String song){
System.out.println("歌星B演唱"+song);
}
}
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class ProxyOrg {
//联系歌星经纪人
public static StarMan getStarManProxy(String starName) {
Class<?>[] interfaces={StarMan.class};
return (StarMan) Proxy.newProxyInstance(StarMan.class.getClassLoader(), interfaces, new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object result=null;
if (method.getName().equals("sing")) {
System.out.println("我是经纪人");
StarMan starMan = null;
//经纪人在此处根据要求去联系歌星
if(starName.equals("歌星A")){
starMan = new StarA();
}else if(starName.equals("歌星B")){
starMan = new StarB();
}
if(starMan!=null){
System.out.println("我已联系到歌星,请歌星演唱");
result = method.invoke(starMan, args);
}else{
System.out.println("我联系不到歌星");
}
}
return result;
}
});
}
}
public class Main {
public static void main(String[] args) {
//请经纪人联系歌星A
StarMan p = ProxyOrg.getStarManProxy("歌星A");
p.sing("歌曲A");
//请经纪人联系歌星B
p = ProxyOrg.getStarManProxy("歌星B");
p.sing("歌曲B");
}
}
CGLIB动态代理
CGLIB(Code Generation Library)是一个基于ASM的字节码生成库,它允许我们在运行时对字节码进行 修改和动态生成。CGLIB通过继承方式实现代理,在子类中采用方法拦截的技术拦截所有父类方法的调 用并顺势织入横切逻辑。

348

被折叠的 条评论
为什么被折叠?



