一)JDK动态代理机制实现
使用步骤:
1)自定义一个接口
public interface HelloInterface {
void sayHello(String message);
}
2)实现接口
public class HelloInterfaceImpl implements HelloInterface{
@Override
public void sayHello(String message) {
System.out.println("message:"+message);
}
}
3)实现 InvocationHandler 接口并重写invoke方法,并在invoke方法中调用原生方法
public 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.out.println("say hello before");
method.invoke(target,args);
System.out.println("say hello after");
return null;
}
}
4)通过 Proxy.newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h) 方法创建代理对象;
public class TestProxy {
public static void main (String args[]){
HelloInterface helloInterface=new HelloInterfaceImpl();
MyInvocationHandler myInvocationHandler=new MyInvocationHandler(helloInterface);
HelloInterface helloInterfaceProxy=(HelloInterface) Proxy.newProxyInstance(helloInterface.getClass().getClassLoader(),helloInterface.getClass().getInterfaces(),myInvocationHandler);
helloInterfaceProxy.sayHello("Hello world!");
}
}
运行效果如下:
2)CGLIB动态代理机制
使用步骤:
1)自定义一个类;
public class HelloService {
public String send(String message) {
System.out.println("message:" + message);
return message;
}
}
2)实现MethodInterceptor接口并重写 intercept 方法,intercept 用于拦截增强被代理类的方法,和 JDK 动态代理中的 invoke 方法类似
public class MyMethodInterceptor implements MethodInterceptor {
@Override
public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
System.out.println("say hello before");
Object object = methodProxy.invokeSuper(o, args);
System.out.println("say hello after");
return object;
}
}
3)通过 Enhancer 类的 create()创建代理类
public class TestCgLib {
public static void main(String args[]){
// 创建动态代理增强类
Enhancer enhancer = new Enhancer();
// 设置类加载器
enhancer.setClassLoader(HelloService.class.getClassLoader());
// 设置被代理类
enhancer.setSuperclass(HelloService.class);
// 设置方法拦截器
enhancer.setCallback(new MyMethodInterceptor());
// 创建代理类
HelloService aliSmsService = (HelloService) enhancer.create();
aliSmsService.send("Hello world!");
}
}
因为CGLIB是一个开源项目,需要引入相关的jar包来使用
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>3.3.0</version>
</dependency>
运行效果:
简单说明:
1)因为JDK 动态代理只能代理实现了接口的类,所以为了解决这个问题,我们可以用 CGLIB 动态代理机制来避免,CGLIB 可以代理未实现任何接口的类;
2)就二者效率来看JDK动态代理更优秀一些