动态代理是AOP的实现原理,须要实现一个InvocationHandler接口,将须要执行的方法嵌入到被代理对象的方法中,不须要修改被代理的类。java
记录一些实现方式,防止忘记。web
不用说,要个接口和实现:ide
public interface UserDao {
void save();
}
public class UserDaoImpl implements UserDao{
@Override
public void save() {
System.out.println("UserDaoImpl saved.......");
}
}
必需要有接口,具体缘由往下看:svg
public class Interceptor implements InvocationHandler{
private Object target;
public Object getTarget() {
return target;
}
public void setTarget(Object target) {
this.target = target;
}
public void beforMethod(Method method) {
System.out.println("---method :" + method.getName() + " get started!!!");
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
beforMethod(method);
method.invoke(getTarget(), args);
return null;
}
}
咱们要把beforeMethod嵌入到被代理方法以前执行,这边invoke获得了被代理对象的方法,这个方法应该是一个接口,而不该该是具体子类实现了的方法,由于最后是代理对象去执行方法,这种实现方式的效果就如同继承同样,重写了接口的方法,将它实现为beforeMethod+被代理类的方法。this
看客户端是怎么用Proxy的:spa
public class App {
public static void main(String[] args) {
UserDao userDao = new UserDaoImpl();
Interceptor it = new Interceptor();
it.setTarget(userDao);
UserDao usrDaoProxy = (UserDao) Proxy.newProxyInstance(userDao.getClass().getClassLoader(), userDao.getClass().getInterfaces(), it);
usrDaoProxy.save();
System.out.println(usrDaoProxy.getClass().getName());
}
}
结果:
—method :save get started!!!
UserDaoImpl saved…….
com.sun.proxy.$Proxy0代理