JAVA动态代理实现 Proxy InvocationHandler

来源:互联网 发布:小学课程同步软件免费 编辑:程序博客网 时间:2024/05/16 23:38

  刚刚学习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 {@Overridepublic void saveUser(User u) {System.out.println("人员保存~~");}@Overridepublic 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+"()结束~~");}@Overridepublic 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()结束~~

 

源码下载地址为:http://download.csdn.net/detail/best198706/5817375