1)对次要业务进行具体实现
2)通知JVM,当前被拦截的主要业务方法与次要业务方法应该如何绑定
1)被监控实例对象
2)需要被监控的行为
3)具体通知类实例对象
1.定义一个要监控的行为—>接口
public interface Eat {
/**
* 某种生物吃东西
* @param something
*/
void eat(String something);
}
2.定义实现接口的实例
public class Person implements Eat {
@Override
public void eat(String something) {
System.out.println("我吃" + something);
}
}
3.通知jvm需要拦截的方法—>实现InvocationHandler
public class Invocation implements InvocationHandler {
public Invocation(Object object) {
this.object = object;
}
private Object object;
/***
* 这个方法就是要告诉代理对象要处理的方法
*
* @param proxy 代理对象
* @param method 实例对象要调用的方法
* @param args 实例对象要调用的方法的参数
* @return Object
* @throws Throwable
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if (object instanceof Person){
wash();
}else if(object instanceof Dog){
sound();
}
return method.invoke(object, args);
}
private void wash(){
System.out.println("我是人,我要洗手");
}
private void sound(){
System.out.println("我是狗,汪汪汪");
}
}
4.创建代理对象
public static Object getInstance(Class clz) throws IllegalAccessException, InstantiationException {
/**
*
* ClassLoader loader, 被代理类的加载器
* Class>[] interfaces, 被代理类的所有接口
* InvocationHandler h 调用的处理器
*
* return 代理对象
*/
Object object = Proxy.newProxyInstance(clz.getClassLoader(), clz.getInterfaces(), new Invocation(clz.newInstance()));
return object;
}
public static Object newProxyInstance(ClassLoader loader, Class>[] interfaces,InvocationHandler h) throws IllegalArgumentException{
//判断InvocationHandler对象是否为空
Objects.requireNonNull(h);
//获取接口的克隆对象
final Class>[] intfs = interfaces.clone();
//获取安全管理对象,一般为空
final SecurityManager sm = System.getSecurityManager();
if (sm != null) {
checkProxyAccess(Reflection.getCallerClass(), loader, intfs);
}
//通过类加载器和接口去找或者生成接口对应的代理类
Class> cl = getProxyClass0(loader, intfs);
try {
if (sm != null) {
checkNewProxyPermission(Reflection.getCallerClass(), cl);
}
final Constructor> cons = cl.getConstructor(constructorParams);
final InvocationHandler ih = h;
if (!Modifier.isPublic(cl.getModifiers())) {
AccessController.doPrivileged(new PrivilegedAction() {
public Void run() {
cons.setAccessible(true);
return null;
}
});
}
return cons.newInstance(new Object[]{h});
} catch (IllegalAccessException|InstantiationException e) {
throw new InternalError(e.toString(), e);
} catch (InvocationTargetException e) {
Throwable t = e.getCause();
if (t instanceof RuntimeException) {
throw (RuntimeException) t;
} else {
throw new InternalError(t.toString(), t);
}
} catch (NoSuchMethodException e) {
throw new InternalError(e.toString(), e);
}
}
//解析真正获取代理对象的方法
private static Class> getProxyClass0(ClassLoader loader,Class>... interfaces) {
if (interfaces.length > 65535) {
throw new IllegalArgumentException("interface limit exceeded");
}
//这里似乎是从缓存中拿到了数据,继续往下看
return proxyClassCache.get(loader, interfaces);
}
// proxyClassCache.get(loader, interfaces)
public V get(K key, P parameter) {
//判断接口是否为空
Objects.requireNonNull(parameter);
expungeStaleEntries();
Object cacheKey = CacheKey.valueOf(key, refQueue);
// lazily install the 2nd level valuesMap for the particular cacheKey
ConcurrentMap
1.实现InvocationHandlder接口
2.通过Proxy.newProxyInstance方法创建代理对象
3.被代理的对象必须实现接口