代理模式
-
动态代理:基于反射机制。
-
什么是动态代理?
-
动态代理能做什么?
-
代理模式:客户端,间接地通过代理对象,但最终目标还是被代理对象(控制对目标对象的访问,型成物理隔离)。
-
代理模式的作用
- 功能增强:在原有的功能上,增加额外能力。
- 控制访问:目标对象不允许直接访问。
-
实现方式:
- 静态代理:代理类是手动实现的,自己创建一个类,标识代理类。
- 优点:实现简单,易于理解。
- 缺点:目标对象增加,代理对象会成倍增加;接口新增或修改方法,所有实现类都要变更。
-
动态代理:在程序执行时(通常是启动阶段),利用反射机制,创建代理对象,并动态地制定目标对象。其实动态代理提供了一种不用手动创建类,就能产生代理对象的能力。
-
静态代理Demo:
package comg.yang.httpstest;
/**
* @description:
* @author: Yang JianXiong
* @since: 2016/8/25
*/
public class StaticProxyDemo {
public static void main(String[] args) {
SellAble proxySeller = new ProxySeller(new TargetSeller());
proxySeller.sell(100F);
}
}
/**
* 售卖能力接口
*/
interface SellAble {
void sell(float price);
}
class ProxySeller implements SellAble {
private final SellAble targetSeller;
@Override
public void sell(float price) {
this.targetSeller.sell(this.cut(price));
}
/**
* 中介盘剥
*
* @param price
* @return
*/
private float cut(float price) {
float result = price * 0.8F;
System.out.printf("中介盘剥:%f元\n", price - result);
return result;
}
public ProxySeller(SellAble targetSeller) {
this.targetSeller = targetSeller;
}
}
class TargetSeller implements SellAble {
@Override
public void sell(float price) {
System.out.printf("最终收入:%f元", price);
}
}
- 通过JDK反射机制执行方法:
package comg.yang.httpstest;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/**
* @description:
* @author: Yang JianXiong
* @since: 2016/8/25
*/
public class MethodReflectDemo {
public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
// 1.通过方法签名(方法名 + 参数列表),通过反射获取在接口中声明的方法对象
Method sayHello = HelloService.class.getMethod("sayHello", String.class);
// 2.通过给方法对象传递不同的目标对象和参数,执行不同的实现。
sayHello.invoke(new HelloServiceImpl(), "张三");
sayHello.invoke(new HelloServiceImpl_0(), "张三");
}
}
interface HelloService {
void sayHello(String name);
}
class HelloServiceImpl implements HelloService {
@Override
public void sayHello(String name) {
System.err.printf("hello:%s \n", name);
}
}
class HelloServiceImpl_0 implements HelloService {
@Override
public void sayHello(String name) {
System.err.printf("hello_0:%s \n", name);
}
}
- JDK动态代理Demo
package comg.yang.httpstest;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* @description:
* @author: Yang JianXiong
* @since: 2016/8/25
*/
public class DynamicProxyDemo {
public static void main(String[] args) {
SingAble jay = new Jay();
MyInvocationHandler myInvocationHandler = new MyInvocationHandler(jay);
SingAble proxyInstance = (SingAble) Proxy.newProxyInstance(jay.getClass().getClassLoader(), jay.getClass().getInterfaces(), myInvocationHandler);
// 唱歌
proxyInstance.sing("500 miles");
// 跑步
proxyInstance.go("5000 miles");
}
}
interface SingAble {
void sing(String songName);
void go(String songName);
}
class Jay implements SingAble {
@Override
public void sing(String songName) {
System.out.printf("周杰伦在唱歌:%s\n", songName);
}
@Override
public void go(String songName) {
System.out.printf("周杰伦在走路:%s\n", songName);
}
}
class MyInvocationHandler implements InvocationHandler {
private final Object target;
public MyInvocationHandler(Object target) {
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.err.println("额外功能");
return method.invoke(this.target, args);
}
}
学习使我充实,分享给我快乐!