如果你的程序需要频繁、反复地创建代理对象,则 JDK 动态代理在性能上更占优。
目标对象一定要实现接口,否则不能用动态代理
package com.carl.proxy;
public interface IFly {
boolean isCanFly();
String flying();
}
package com.carl.proxy;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class Bird implements IFly {
private static final Logger LOGGER = LoggerFactory.getLogger(Main.class);
@Override
public boolean isCanFly() {
LOGGER.info("isCanFly");
return true;
}
@Override
public String flying() {
LOGGER.info("flying");
return "flying";
}
}
package com.carl.proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class ProxyFactory {
private static final Logger LOGGER = LoggerFactory.getLogger(ProxyFactory.class);
private Object target;
public ProxyFactory(Object target) {
this.target = target;
}
public void test() {
LOGGER.info("testing");
}
public Object getProxyInstance() {
return Proxy.newProxyInstance(
target.getClass().getClassLoader(),
target.getClass().getInterfaces(),
new InvocationHandler(){
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
LOGGER.info("invoke start");
test();
Object obj = method.invoke(target, args);
LOGGER.info("invoke end");
return obj;
}
});
}
}
package com.carl.proxy;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class Main {
// private static final Logger LOGGER = LoggerFactory.getLogger(Main.class);
public static void main(String[] args) {
IFly f = new Bird();
IFly proxy = (IFly) new ProxyFactory(f).getProxyInstance();
proxy.isCanFly();
}
}
22:22:10.984 [main] INFO com.carl.proxy.ProxyFactory - invoke start
22:22:10.988 [main] INFO com.carl.proxy.ProxyFactory - testing
22:22:10.989 [main] INFO com.carl.proxy.Main - isCanFly
22:22:10.989 [main] INFO com.carl.proxy.ProxyFactory - invoke end
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
HPROSE 是 High Performance Remote Object Service Engine 的缩写,翻译成中文就是 “高性能远程对象服务引擎”。
在运行期扩展 Java 类与实现 Java 接口,通俗说 cglib 可以在运行时动态生成字节码
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>3.2.5</version>
</dependency>
package com.carl.cglib;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class Bird {
private static final Logger LOGGER = LoggerFactory.getLogger(Bird.class);
public boolean isCanFly() {
LOGGER.info("isCanFly");
return true;
}
public String flying() {
LOGGER.info("flying");
return "flying";
}
}
package com.carl.cglib;
import java.lang.reflect.Method;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
public class DynamicProxy implements MethodInterceptor {
private static final Logger LOGGER = LoggerFactory.getLogger(DynamicProxy.class);
Object target;
public Object getProxyObject(Object target) {
this.target = target;
Enhancer enhancer = new Enhancer();
enhancer.setCallback(this);
enhancer.setSuperclass(target.getClass());
return enhancer.create();
}
@Override
public Object intercept(Object object, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
LOGGER.info("invoke start");
LOGGER.info(methodProxy.getSuperName());
Object result = methodProxy.invoke(target, args);
LOGGER.info("invoke end");
return result;
}
}
package com.carl.cglib;
public class Main {
public static void main(String[] args) {
Bird bird = (Bird) new DynamicProxy().getProxyObject(new Bird());
bird.flying();
bird.isCanFly();
}
}
21:35:39.214 [main] INFO com.carl.cglib.DynamicProxy - invoke start
21:35:39.217 [main] INFO com.carl.cglib.DynamicProxy - CGLIB$flying$0
21:35:39.229 [main] INFO com.carl.cglib.Bird - flying
21:35:39.229 [main] INFO com.carl.cglib.DynamicProxy - invoke end
21:35:39.229 [main] INFO com.carl.cglib.DynamicProxy - invoke start
21:35:39.229 [main] INFO com.carl.cglib.DynamicProxy - CGLIB$isCanFly$1
21:35:39.229 [main] INFO com.carl.cglib.Bird - isCanFly
21:35:39.229 [main] INFO com.carl.cglib.DynamicProxy - invoke end
cglib 在执行时动态的生成了一个新的 Bird 类并重写了被代理的方法
如果使用 intellij 可能是可以看到源码的,eclipse 不行呢