刚刚学习JAVA的动态代理,是用java.lang.reflect.InvocationHandler类和java.lang.reflect.InvocationHandler接口来实现的。很好用,记录下来和大家分享一下。
采用自己的代理调用被代理对象的方法,并且可以在方法运行前后加上自己的切面业务逻辑(AOP),比如说日志、测试方法运行时间等等。
其中被代理对象必须是实现了某个接口的类对象;
自己的代理实现InvocationHandler接口,在该接口的invoke方法中实现自己的业务。
在这里被代理对象实现的接口为UserDao.java
package com.proxy.dao;
import com.proxy.model.User;
public interface UserDao {
/**
* 保存
* @param u
*/
public void saveUser(User u);
/**
* 删除
*/
public void deleteUser();
}
被代理对象的类为UserDaoImpl.java,我们是要在运行这里面的方法时,前面后面加一些逻辑。
package com.proxy.dao.impl;
import com.proxy.dao.UserDao;
import com.proxy.model.User;
public class UserDaoImpl implements UserDao {
@Override
public void saveUser(User u) {
System.out.println("人员保存~~");
}
@Override
public void deleteUser() {
System.out.println("人员删除~~");
}
}
自己的代理对象LogHandler.java需实现java.lang.reflect.InvocationHandler接口
其中在invoke方法中定义自己的业务逻辑。
package com.proxy.myproxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class LogHandler implements InvocationHandler {
/**被代理的对象*/
private Object o;
public LogHandler(Object o) {
super();
this.o = o;
}
/**
* 自己的开始业务
* @param str
*/
private void beforeMethod(String str){
System.out.println("方法"+str+"()开始~~");
}
/**
* 自己的结束业务
* @param str
*/
private void afterMethod(String str){
System.out.println("方法"+str+"()结束~~");
}
@Override
public Object invoke(Object arg0, Method arg1, Object[] arg2)
throws Throwable {
//自己的业务
beforeMethod(arg1.getName());
//被代理对象的业务,是通过反射来实现的
arg1.invoke(o, arg2);
//自己的业务
afterMethod(arg1.getName());
return null;
}
}
在使用时需要调用java.lang.reflect.Proxy类的newProxyInstance方法来获得自己的代理对象,该方法有3个参数分别为
1.获得这个类对象的加载器与被代理对象相同即可在这里为UD.getClass().getClassLoader()
2.被代理对象实现的接口在这里为UD.getClass().getInterfaces()
3.自己的切面业务对象在这里为IH
package com.proxy.main;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
import com.proxy.dao.UserDao;
import com.proxy.dao.impl.UserDaoImpl;
import com.proxy.model.User;
import com.proxy.myproxy.LogHandler;
public class TestMain {
public static void main(String[] args) {
//被代理对象
UserDao UD = new UserDaoImpl();
//与切面的业务结合
InvocationHandler IH = new LogHandler(UD);
//生成我们自己的代理对象,来实现别的切面业务
UserDao UserProxy = (UserDao)Proxy.newProxyInstance(UD.getClass().getClassLoader(), UD.getClass().getInterfaces(),IH);
UserProxy.saveUser(new User());
System.out.println("************************");
UserProxy.deleteUser();
}
}
运行结果为
方法saveUser()开始~~
人员保存~~
方法saveUser()结束~~
************************
方法deleteUser()开始~~
人员删除~~
方法deleteUser()结束~~