Java中的代理技术有JDK,CGLIB,Javassist,ASM,其中JDK,CGLIB较为常用.
1 JDK动态代理
1)Jdk代理是java.lang.reflect.*提供的方式,它必须借助一个接口才能产生代理对象,所以先定义接口,如下:
public interface HelloWorld {
public void syaHelloWorld();
}
2)提供一个实现类
public class HelloWorldImpl implements HelloWorld {
@Override
public void syaHelloWorld() {
System.out.println("Hello World.......");
}
}
3)动态代理类
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* @Author:musi
* @Date:2019/9/13
* @Description:
*/
public class JdkProxyExample implements InvocationHandler {
//真实对象
private Object target = null;
/**
* 建立代理对象和真实对象的关系,并返回代理对象.
* @param target
* @return
*/
public Object bind(Object target){
this.target = target;
return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
}
/**
* 代理方法逻辑
* @param proxy 代理对象
* @param method 当前调度方法
* @param args 当前方法参数
* @return 代理结果返回
* @throws Throwable 异常
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("进入代理逻辑方法");
System.out.println("在调度真实对象之前的服务");
Object obj = method.invoke(target, args);//相当于调用sayHelloWorld方法
System.out.println("在调度真实对象之后的服务");
return obj;
}
}
代理分两个步骤;
第一步,建立对象和真实对象的关系,这里使用了bind方法,其中newProxyInstance方法包含了三个参数
->第一个是类加载器,我们采用了target本身的类加载器
->第二个是把生成的动态代理对象挂在哪些接口下,这个写法就是放在target实现的接口下.
->第三个是定义实现方法逻辑的代理类.this表示当前对象,它必须实现InvocationHandler接口的invoke方法,它就是代理逻辑的现实方法
第二步,实现代理逻辑方法,其中invoke方法的三个参数含义为:
proxy:代理对象,就是bind方法生成的对象.
method:当前调度的方法
args:调度方法的参数
4)测试类
public class TestJdkProxy {
@Test
public void testJdkProxy(){
JdkProxyExample jdkProxyExample = new JdkProxyExample();
HelloWorld proxy = (HelloWorld) jdkProxyExample.bind(new HelloWorldImpl());
proxy.syaHelloWorld();
}
}
2 CGLIB动态代理
1)maven依赖
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib-nodep</artifactId>
<version>3.1</version>
</dependency>
2)代理类
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
/**
* @Author:musi
* @Date:2019/9/13
* @Description:
*/
public class CglibProxyExample implements MethodInterceptor {
/**
* 生成CGLIB代理对象
* @param cls --Class类
* @return Class类的CGLIB代理对象
*/
public Object getProxy(Class cls){
//CGLIB enhancer增强类对象
Enhancer enhancer = new Enhancer();
//设置增强类型
enhancer.setSuperclass(cls);
//定义代理逻辑对象为当前对象,要求当前对象实现MethodInterceptor方法
enhancer.setCallback(this);
//生成并返回代理对象
return enhancer.create();
}
/**
* 代理逻辑方法
* @param proxy 代理对象
* @param method 方法
* @param args 参数
* @param methodProxy 方法代理
* @return 代理逻辑返回
* @throws Throwable 异常
*/
@Override
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
System.out.println("调用真实对象前");
//CGLIB反射调用真实对象方法
Object result = methodProxy.invokeSuper(proxy, args);
System.out.println("调用真实对象后");
return result;
}
}
3)测试类
public class TestCglibProxy {
@Test
public void testCglibProxy(){
CglibProxyExample cglibProxyExample = new CglibProxyExample();
HelloWorldImpl helloWorld = (HelloWorldImpl) cglibProxyExample.getProxy(HelloWorldImpl.class);
helloWorld.syaHelloWorld();
}
}