动态代理是AOP的实现原理,需要实现一个InvocationHandler接口,将需要执行的方法嵌入到被代理对象的方法中,不需要修改被代理的类。
记录一些实现方式,防止忘记。
不用说,要个接口和实现:
public interface UserDao {
void save();
}
public class UserDaoImpl implements UserDao{
@Override
public void save() {
System.out.println("UserDaoImpl saved.......");
}
}
必须要有接口,具体原因往下看:
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+被代理类的方法。
看客户端是怎么用Proxy的:
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