Java 动态代理作用是什么?
来源:网络整理 网络用户发布,如有版权联系网管删除 2018-07-23
① 首先你要明白静态代理的作用
我们有一个字体提供类,有多种实现(从磁盘,从网络,从系统)
public interface FontProvider {
Font getFont(String name);
}
public abstract class ProviderFactory {
public static FontProvider getFontProvider() {
return new FontProviderFromDisk();
}
}
public class Main() {
public static void main(String[] args) {
FontProvider fontProvider = ProviderFactory.getFontProvider();
Font font = fontProvider.getFont("微软雅黑");
......
}
}
public class CachedFontProvider implements FontProvider {
private FontProvider fontProvider;
private Map<String, Font> cached;
public CachedFontProvider(FontProvider fontProvider) {
this.fontProvider = fontProvider;
}
public Font getFont(String name) {
Font font = cached.get(name);
if (font == null) {
font = fontProvider.getFont(name);
cached.put(name, font);
}
return font;
}
}
/* 对工厂类进行相应修改,代码使用处不必进行任何修改。
这也是面向接口编程以及工厂模式的一个好处 */
public abstract class ProviderFactory {
public static FontProvider getFontProvider() {
return new CachedFontProvider(new FontProviderFromDisk());
}
}
况且将来还可能添加日志,权限检查,异常处理等功能显然用代理类更好一点。
② 然而为什么要用动态代理?
考虑以下各种情况,有多个提供类,每个类都有getXxx(String name)方法,每个类都要加入缓存功能,使用静态代理虽然也能实现,但是也是略显繁琐,需要手动一一创建代理类。
public abstract class ProviderFactory {
public static FontProvider getFontProvider() {...}
public static ImageProvider getImageProvider() {...}
public static MusicProvider getMusicProvider() {...}
......
}
public class CachedProviderHandler implements InvocationHandler {
private Map<String, Object> cached = new HashMap<>();
private Object target;
public CachedProviderHandler(Object target) {
this.target = target;
}
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
Type[] types = method.getParameterTypes();
if (method.getName().matches("get.+") && (types.length == 1) &&
(types[0] == String.class)) {
String key = (String) args[0];
Object value = cached.get(key);
if (value == null) {
value = method.invoke(target, args);
cached.put(key, value);
}
return value;
}
return method.invoke(target, args);
}
}
public abstract class ProviderFactory {
public static FontProvider getFontProvider() {
Class<FontProvider> targetClass = FontProvider.class;
return (FontProvider) Proxy.newProxyInstance(targetClass.getClassLoader(),
new Class[] { targetClass },
new CachedProviderHandler(new FontProviderFromDisk()));
}
}
Spring容器代替工厂,Spring AOP代替JDK动态代理,让面向切面编程更容易实现。
在Spring的帮助下轻松添加,移除动态代理,且对源代码无任何影响。
查看评论 回复
"Java 动态代理作用是什么?"的相关文章
- 上一篇:【慕课网课程推荐】系列:Java入门第二季
- 下一篇:Mac如何安装java?