Java中动态代理实现示例

动态代理就是利用java中的Proxy和Invocationhandler实现的。实现动态代理你可以在某个类的每个方法执行前后加上你想要执行的代码。比如,你想要测试方法执行时间,那么你可以写个动态代理,在想要测试的方法执行前获得时间然后在方法执行完后再获取时间,取两次时间差便可得要测试方法的执行时间。仅用文字描述难免让你觉得抽象,何况动态代理本身就是挺抽象的概念。 在此,你要记住一条,动态代理就是对被代理的类进行一次封装包裹以便加上你需要加的业务逻辑。

下面看看具体的代码。这个例子是我学习spring的时候看到的一个示例,其实代码网上都有,类似的文章也有,我之所以在此再写一遍也是为了加深对动态代理的印象和理解。此例中包括User、UserDAO、UserDAOImpl、UserService、UserDAOProxy类组成,测试是用junit测试用例而不是写main函数测试的。

User.java

package com.learn.model; public class User { private String username; private String password; public String getUsername() { return username; } public void setUsername(String name) { this.username = name; } public String getPassword(){ return this.password; } public void setPassword(String pwd){ this.password = pwd; } }

UserDAO.java

package com.learn.dao; import com.learn.model.User; public interface UserDAO { void save(User user); }

UserDAOImpl.java

package com.learn.daoimpl; import org.springframework.stereotype.Component; import com.learn.dao.UserDAO; import com.learn.model.User; @Component public class UserDAOImpl implements UserDAO{ @Override public void save(User user) { // TODO Auto-generated method stub System.out.println("User saved!"); } }

UserService.java

package com.learn.service; import javax.annotation.Resource; import org.springframework.beans.factory.annotation.Autowired; import com.learn.model.User; import com.learn.dao.*; public class UserService { private UserDAO userDAO; public void add(User user) { userDAO.save(user); } public UserDAO getUserDAO(){ return userDAO; } @Resource //@Autowired public void setUserDAO(UserDAO userDAO){ this.userDAO=userDAO; } }

UserDAOProxy.java

package com.learn.proxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; public class UserDAOProxy implements InvocationHandler{ private Object target; public void setTarget(Object target) { this.target = target; } public void beforeMethod(Method m) { System.out.println(m.getName()+" start..."); } public void afterMethod(Method m) { System.out.println(m.getName()+" end..."); } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { // TODO Auto-generated method stub beforeMethod(method); method.invoke(target, args); afterMethod(method); return null; } }



测试用例如下:

package com.learn.service; import java.lang.reflect.Proxy; import org.junit.Test; import org.springframework.beans.factory.BeanFactory; import org.springframework.context.support.ClassPathXmlApplicationContext; import com.learn.dao.UserDAO; import com.learn.daoimpl.UserDAOImpl; import com.learn.model.User; import com.learn.proxy.UserDAOProxy; public class UserServiceTest { @Test public void testProxy(){ UserDAO userDAO = new UserDAOImpl(); // 要使用动态代理,必须要先new一个被代理的对象(要不然代理代理什么呢?对吧) UserDAOProxy uDaoProxy = new UserDAOProxy(); // 使用动态代理也要new一个代理所要完成的业务逻辑 uDaoProxy.setTarget(userDAO); // 这步算是绑定,将你想要的额外完成的东西与被代理对象联系起来 UserDAO userDAOProxy = (UserDAO)Proxy.newProxyInstance(userDAO.getClass().getClassLoader(), userDAO.getClass().getInterfaces(), uDaoProxy); // 这步是创建代理对象了,第一个参数指定类加载器:使得这个代理类能访问被代理对象,第二个参数指定代理类应该具有哪些接口:要不然怎么去代理被代理对象(被代理对象所能做的,你代理也应该能完成,对不对?),第二个参数就是指定,代理对象额外完成的业务逻辑了:如前面所述的获取被代理类的执行时间。 userDAOProxy.save(new User()); // 最后使用代理,代理具有被代理对象的所有方法,而且你还可以在被代理对象的方法执行前或执行后加上额外的业务逻辑。 } }


输出结果:
save start...
User saved!
save end...

其中:save start...和save end...两句输出都是由代理完成的,User saved!是被代理对象完成的。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值