一 基于接口的动态代理(JDK默认使用方式)
1. 定义一个接口
public interface People { public void eat(); }
2.定义一个接口实现类
public class BlackMan implements People { @Override public void eat() { System.out.print("I am BlackMan"); } }
3. 使用
public class MyClass { BlackMan man = new BlackMan(); InvocationHandler handler = new InvocationHandler() { @Override public Object invoke(Object o, Method method, Object[] objects) throws Throwable { System.out.println("invoke"); method.invoke(man, null); return o; } }; private void proxy() { People ProxyPeople = (People) Proxy.newProxyInstance(man.getClass().getClassLoader(), new Class[]{People.class}, handler); ProxyPeople.eat(); } public static void main(String[] args) { new MyClass().proxy(); } }
二 基于类实现的动态代理(CGLIB)
1.定义一个实现类 即和核心类
public class Dao { public void update() { System.out.println("PeopleDao.update()"); } public String select() { System.out.println("PeopleDao.select()"); return "hello,world"; } }
2 .定义一个回调
该回调必须 MethodInterceptor
public class DaoProxy implements MethodInterceptor { @Override public Object intercept(Object object, Method method, Object[] objects, MethodProxy proxy) throws Throwable { System.out.println("Before Method Invoke"); Object obj = proxy.invokeSuper(object, objects); System.out.println("After Method Invoke"); return obj; } }
3.定义一个 filter
该filter 必须实现 CallbackFilter
public class DaoFilter implements CallbackFilter { @Override public int accept(Method method) { if ("select".equals(method.getName())) { return 0; } return 1; } }
4.使用
public class MyClass { public static void main(String[] args){ DaoProxy daoProxy = new DaoProxy(); DaoProxy daoAnotherProxy = new DaoProxy(); Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(Dao.class); enhancer.setCallbacks(new Callback[]{daoProxy, daoAnotherProxy, NoOp.INSTANCE}); enhancer.setCallbackFilter(new DaoFilter()); Dao dao = (Dao)enhancer.create(); dao.update(); dao.select(); } }
当然 CGLIB 库也可实现基于接口的动态代理,更多使用场景,后续详细讲解