JAva反射レビュー
10212 ワード
jdkダイナミックエージェント
cglibダイナミックエージェント
JDK動的エージェントメカニズムの欠陥:JDKの動的エージェントメカニズムはエージェントがインタフェースのクラスを実現しただけで、インタフェースを実現できないクラスはJDKの動的エージェントを実現できない
cglibはクラスに対してエージェントを実装し、指定したターゲットクラスに対してサブクラスを生成し、メソッド実装の強化を上書きすることを原理としています.
cglib欠陥cglibは動的エージェントを実現するが,継承を採用しているためfinal修飾クラスをエージェントすることはできない.
RPC動的エージェントによるリモート関数の呼び出し
クライアントがリモートのサービスオブジェクトを呼び出す必要がある場合、動的エージェントによってクライアントに必要なオブジェクトを作成します.
//
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 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();
}
}
});
}