jdk动态代理
//动物接口
public interface Animal {
void shout(String sound);
}
//动物接口实现类
public class Cat implements Animal {
@Override
public void shout(String sound) {
for (int i = 0; i < 3; i++) {
System.out.print("cat->"+sound + "! ");
}
System.out.println();
}
}
//动物接口实现类
public class Dog implements Animal {
@Override
public void shout(String sound) {
for (int i = 0; i < 3; i++) {
System.out.print("dog->"+sound + "! ");
}
System.out.println();
}
}
class AnimalProxy implements InvocationHandler {
private Object target;
public Object getInstance(Object target) {
this.target = target;
return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object result = null;
System.out.println("方法调用前...");
result = method.invoke(target, args);
System.out.println("方法调用后...");
return result;
}
}
public class ProxyTest {
public static void main(String[] args) {
AnimalProxy proxy=new AnimalProxy();
Animal dogProxy= (Animal) proxy.getInstance(new Dog());
dogProxy.shout("wang");
}
}
cglib动态代理
JDK动态代理机制缺陷:JDK的动态代理机制只能代理实现了接口的类,而不能实现接口的类就不能实现JDK的动态代理
cglib是针对类来实现代理的,他的原理是对指定的目标类生成一个子类,并覆盖其中方法实现增强,
cglib缺陷 cglib实现动态代理但因为采用的是继承,所以不能对final修饰的类进行代理。
class Snake {
public void makeSound(String name) {
System.out.println("Hi," + name + "");
}
}
class AnimalProxyCglib implements MethodInterceptor {
private Object target;
public Object getInstance(Object target) {
this.target = target;
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(this.target.getClass());
enhancer.setCallback(this);
return enhancer.create();
}
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
Object result = null;
System.out.println("方法调用前操作...");
result = methodProxy.invokeSuper(o, objects);
System.out.println("方法调用后操作...");
return result;
}
}
public class DynamicProxyCglibDemo {
public static void main(String[] args) {
AnimalProxyCglib proxy = new AnimalProxyCglib();
Snake dogProxy=(Snake)proxy.getInstance(new Snake());
dogProxy.makeSound("tom");
}
}
RPC利用动态代理调用远程函数
HelloService helloService=rpcProxy.create(HelloService.class);
客户端需要调用远程一个服务对象的时候,通过动态代理的方式创建客户端所需的对象
public <T> T create(final Class<?> interfaceClass, final String serviceVersion) {
return (T) Proxy.newProxyInstance(interfaceClass.getClassLoader(), new Class<?>[]{interfaceClass}, new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//创建RPC请求对象,并设置请求属性
RpcRequest request = new RpcRequest();
request.setRequestId(UUID.randomUUID().toString());
request.setInterfaceName(method.getDeclaringClass().getName());
request.setMethodName(method.getName());
request.setParameterTypes(method.getParameterTypes());
request.setServiceVersion(serviceVersion);
request.setParameter(args);
//获取Rpc服务地址
if (serviceDiscovery != null) {
String serviceName = interfaceClass.getName();
if (StringUtil.isNotEmpty(serviceVersion)) {
serviceName += "-"+serviceVersion;
}
serviceAddress = serviceDiscovery.discover(serviceName);
LOGGER.debug("discover service:{}=>", serviceName, serviceVersion);
}
if (StringUtil.isEmpty(serviceAddress)) {
throw new RuntimeException("service address is empty ");
}
//从rpc服务地址中解析主机名与对应的端口号
String[] array = StringUtil.split(serviceAddress, ":");
String host = array[0];
int port = Integer.parseInt(array[1]);
//创建rpc客户端对象并且发送rpc请求
RpcClient client = new RpcClient(host, port);
long beginTime = System.currentTimeMillis();
RpcResponse response = client.send(request);
LOGGER.debug("time:{}ms", System.currentTimeMillis() - beginTime);
if (response == null) {
throw new RuntimeException("response is null ");
}
if (response.hasException()) {
throw response.getException();
} else {
return response.getResult();
}
}
});
}