天天看点

黑马程序员—代理

------- android培训、java培训、期待与您交流! ----------

1,JVM可以在运行期动态生成出类的字节码,这种动态生成的类往往被用作代理类,即动态代理类。

2,JVM生成的动态类必须实现一个或多个接口,所以,JVM生成的动态类只能用作具有相同接口的目标类的代理。

3,CGLIB库可以动态生成一个类的子类,一个类的子类也可以用作该类的代理,所以,如果要为一个没有实现接口的类生成动态代理类,那么可以使用CGLIB库。

4,代理类的各个方法中通常除了要调用目标的相应方法和对外返回目标返回的结果外,还可以在代理方法中的如下四个位置加上系统功能代码:

(1)在调用目标方法之前

(2)在调用目标方法之后

(3)在调用目标方法之后 

(4)在处理目标方法 异常的catch块中

这是我对以上4个小点的总结:其实这4个小点并不用记,在编程的时候根据自己的思想,觉得目标方法需要放在哪里你就可以把它放在哪里。

5,这个图我觉得画得很好,就把它截了下来,看了一目了然

黑马程序员—代理

6,下面这个问题是黑马论坛里面一个同学贴出来的,据他所说这是他在网上看到一个面试题,我看了后就觉得这个就是在考代理的编程思想

题目:实例一个巨大但有限容量的map,当元素数量达到上限后,新加入的对象映射关系将替换最近不常用的对象映射关系。

import java.util.HashMap;

import java.util.Map;

import java.util.Set;

public class MainClass {

public static void main(String[] args) {

MyMap myMap = new MyMap(3);// 定义上限为3,当然这个可以把上限定义得很大,我这里是为了方便测试

for (int i = 10, j = 100; i < 20; i++, j++) {

myMap.put(i, j);// 放入键值对

myMap.get(10);// 使用键为10的键值对

myMap.get(11);// 使用键为11的键值对

myMap.get(15);// 使用键为15的键值对

}

}

}

class MyMap {

private Map map = null;

private int toplimit;// 上限

public MyMap(int toplimit) {

this.toplimit = toplimit;

map = new HashMap();// map指向一个HashMap对象

}

public void put(Object key, Object value) {

Set<key> set = map.keySet();// map中的所有键放入一个set中

System.out.println("放入");

if (map.size() == toplimit) {// 达到上限

System.out.println("Map对象的容量已达到上限");

if (!set.contains(key)) {// 如果这个键是新放入的则执行下面的代码

int minAccessTimes = ((Key) set.toArray()[0]).accessTimes;

for (Object k : set) {

if (minAccessTimes > ((Key) k).accessTimes) {

minAccessTimes = ((Key) k).accessTimes;// 取出访问量最少的次数

}

}

for (Key k : set) {

if (minAccessTimes == k.accessTimes) {// 前面找出的最少 的次数来找到对应的键

map.remove(k);// 移出这个键值对

break;

}

}

}

}

map.put(new Key(key), value);// 放入新的键值对

for (Key k : set) {

System.out.println(k.key + "," + map.get(k).toString() + ","

+ k.accessTimes);

}

}

public Object get(Object key) {

System.out.println("使用");

Set<key> set = map.keySet();

Object value = null;

for (Key k : set) {

if (k.key.equals(key)) {

++k.accessTimes;// 每使用一次访问量加1

value = map.get(key);

}

}

for (Key k : set) {

System.out.println(k.key + "," + map.get(k).toString() + ","

+ k.accessTimes);

}

return value;

}

class Key {

private int accessTimes = 0;// 存放这个键值对的访问量

private Object key = null;// 存放原始的键

public Key(Object key) {

this.key = key;

}

}

}

</key></key>

7,个人对代理的看法:

看了张老师所讲的动态代理后,我就觉得这个动态代理不能滥用,当你要对一个对象中的多个方法提供相同的额外操作时,就可以使用动态代理,如果你只对部分方法提供额外的操作,并且这些操作又各不相同,那这个时候再用动态代理的话就降低了程序的性能,并且在代码的编写量上程序员也没捡到便宜,因些我认为当只对部分方法提供额外的操作,并且这些操作又各不相同时,还不如自己写一个代理类,就比如说上面那道题,我就是自己写的一个代理类,个人觉得对于这个问题用动态代理并不合适

------- android培训、java培训、期待与您交流! ----------