动态代理可以在不修改被代理对象源码的情况下,为代理对象添加其他的逻辑功能,可以使用继承和组合两种方式实现,但是那样如果被代理对象很多的情况下实现是不太可能的。
首先,新建一个类,实现InvocationHandler,在里面加上自己的逻辑
public class LogInterceptor implements InvocationHandler {
private Object target;//被代理对象
public Object getTarget() {
return target;
}
public void setTarget(Object target) {
this.target = target;
}
private void beforeMethod(Method method){
//自己添加的业务逻辑
System.out.println(method.getName()+" start");
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
beforeMethod(method);//先调用自己的逻辑
method.invoke(target, args);//然后调用被代理对象的方法
return null;
}
}
测试类:
@Test
public void testProxy(){
//首先新建一个被代理对象
UserDAO userDAO = new UserDAOImpl();
LogInterceptor interceptor = new LogInterceptor();
//将被代理对象设置进去
interceptor.setTarget(userDAO);
//新建代理
UserDAO userDAOProxy = (UserDAO)Proxy.newProxyInstance(userDAO.getClass().getClassLoader(), userDAO.getClass().getInterfaces(), interceptor);
userDAOProxy.save(new User());
userDAOProxy.delete();
}
控制台输出:
save start
user saved!
delete start
user deleted
通过实验可以知道,这个userDAOProxy的类是$Proxy4,它实现了接口UserDAO,当它调用save(user)方法的时候,由于InvocationHandler的实现类interceptor已经传给它,在这个时候,它首先通过接口UserDAO取得其中的方法Method method = userDAO.getClass().getMethod(),然后调用自身的invoke()方法。