java常用代理模式实现:jdk动态代理,cglib
动态代理:用一个代理对象来控制真实对象(客户--客服--工程师)。
作用:在真实对象访问之前或者之后加入对应的逻辑,或者根据其他规则来控制是否使用真实对象
步骤:1.代理对象和真实对象建立代理关系
2.实现代理对象的代理逻辑方法
一、JDK动态代理
UML图
编写接口
public interface Helloword {
public void sayHello();
}
实现类
public class HelloWordImpl implements Helloword {
@Override
public void sayHello() {
System.out.println("你好!世界!");
}
}
代理类
package jdk;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class JdkProxyExample implements InvocationHandler{
// 真实对象
private Object realObj;
/**
* 1.建立代理对象和真实对象的关系
* @param target 真实对象
* @return 代理对象
*/
public Object bind(Object target) {
this.realObj = target;
return Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces() , this);
}
/**
* 2.编写代理方法逻辑
* @param proxy 代理对象
* @param method 当前调度方法
* @param args 当前方法参数
* @return 代理结果返回
* @throws 异常
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("准备进入代理逻辑方法");
System.out.println("调用真实对象之前的服务");
//相当于调用sayHelloWorld
Object object = method.invoke(realObj, args);
System.out.println("调用真实对象之后的服务");
return object;
}
}
测试类
public class Test {
public static void main(String[] args) {
JdkProxyExample jdk = new JdkProxyExample();
Helloword hellowordProxy = (Helloword) jdk.bind(new HelloWordImpl());
hellowordProxy.sayHello();
}
}
测试结果
二、CGLIB动态代理
由于jdk动态代理只有提供接口才可以使用,在一些不能提供接口的地方,只能使用第三方技术,例如cglib
优势:不需要接口,只需一个非抽象类就能实现动态代理
首先创建实现类
public class HelloServiceImpl {
public void sayHello(String name) {
System.out.println("你好 "+name);
}
}
创建代理逻辑类
由代理类生成的代理对象,调用真实方法,就会先调用代理方法
package cglib;
import java.lang.reflect.Method;
import org.junit.Test;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
public class CglibProxyExample implements MethodInterceptor{
/**
* 生成cglib代理对象
* @param class 类
* @return Class 类的代理对象
*/
public Object getProxy(Class cl) {
//创建增强类的对象
Enhancer enhancer = new Enhancer();
//设置增强类型
enhancer.setSuperclass(cl);
//设置代理逻辑对象为当前对象
//意味着用当前对象实现MethodInterceptor的intercept
enhancer.setCallback(this);
return enhancer.create();
}
/**
* 代理逻辑方法
* @param proxy 代理对象
* @param method 方法
* @param args 方法参数
* @param methodProxy 方法代理
* @return 代理逻辑
* @throws 异常
*/
@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;
}
public static void main(String[] args) {
CglibProxyExample cExample = new CglibProxyExample();
HelloServiceImpl helloServiceImpl = (HelloServiceImpl) cExample.getProxy(HelloServiceImpl.class);
helloServiceImpl.sayHello("王天");
}
}