什么是静态代理,静态代理有什么缺点?
动态代理中JDK动态代理
&CGLib动态代理
的区别和实现过程
为什么要有代理模式
代理模式是一种结构型设计模式, 让你能够提供对象的替代品或其占位符。 代理控制着对于原对象的访问, 并允许在将请求提交给对象前后进行一些处理。
比如:加日志、字符统一编码处理、给某个功能添加事务等
画图:
静态代理
JDK动态代理
/**
* 使用JDK的方式生成代理对象
*
* @author Administrator
*/
public class MyProxyUtils {
public static UserDao getProxy(final UserDao dao) {
// 使用Proxy类生成代理对象
UserDao proxy = (UserDao) Proxy.newProxyInstance(dao.getClass().getClassLoader(),
dao.getClass().getInterfaces(), new InvocationHandler() {
// 代理对象方法一执行,invoke方法就会执行一次
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if("save".equals(method.getName())){
System.out.println("记录日志...");
// 开启事务
}
// 提交事务
// 让dao类的save或者update方法正常的执行下去
return method.invoke(dao, args);
}
});
// 返回代理对象
return proxy;
}
}
CGLib动态代理
public class MyCglibUtils {
/**
* 使用CGLIB方式生成代理的对象
*
* @return
*/
public static BookDaoImpl getProxy() {
Enhancer enhancer = new Enhancer();
// 设置父类
enhancer.setSuperclass(BookDaoImpl.class);
// 设置回调函数
enhancer.setCallback(new MethodInterceptor() {
// 代理对象的方法执行,回调函数就会执行
public Object intercept(Object obj, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
if(method.getName().equals("save")){
System.out.println("记录日志...");
}
// 正常执行
return methodProxy.invokeSuper(obj, args);
}
});
// 生成代理对象
BookDaoImpl proxy = (BookDaoImpl) enhancer.create();
return proxy;
}
}
总结
静态代理,修改接口,就要修改一堆实现类,难以维护;
jdk动态代理,有个前提需要是接口的实现类;
CGLible动态代理,普通Java类也可实现代理,由spring提供