Java 设计模式之动态代理
普通代理的缺点是要针对每个接口和实现类写一个代理类,动态代理从代码上简化了此项工作。
在JDK中通过继承InvocationHandler 实现动态代理,根据一个实现类自动生成一个继承了该实现类接口的实现对象,并可以自定义在接口方法执行前后的操作。
一、接口定义
package com.casic.test.JdkProxy;
public interface UserService {
// 添加用户
public void addUser();
// 删除用户
public void deleteUser();
// 查询用户
public void queryUsers();
}
二、实现类定义
package com.casic.test.JdkProxy;
public class UserServiceImpl implements UserService {
public void addUser() {
System.out.println("添加 一个用户 ");
}
public void deleteUser() {
System.out.println("删除一个用户 ");
}
public void queryUsers() {
System.out.println("查询所有用户 ");
}
}
三、代理类定义
package com.casic.test.JdkProxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* 继承InvocationHandler 实现动态代理
* @author ht
*/
public class LogProxy implements InvocationHandler{
// 源对象
private Object target;
// 使用构造函数传入源对象
public LogProxy(Object target) {
this.target = target;
}
/**
* 获取代理的实例,根据构造方法中传入的源对象,生成一个代理对象
* 生成的代理对象同样实现了源对象的继承的接口方法
* @return
*/
public Object CreateProxyInstance(){
return Proxy.newProxyInstance(//
getClass().getClassLoader(),//
this.target.getClass().getInterfaces(), this);
}
/**
* 重写此方法使得代理对象能够执行源对象所有方法
* 并且可以在执行前后做其他的操作
*/
public Object invoke(Object proxy,//
Method method, Object[] args) throws Throwable{
System.out.println("=========开始执行================");
/*源对象方法的执行,target 为源对象,args 为源对象的参数*/
Object result = method.invoke(target, args);
System.out.println("=========执行完毕================");
return result;
}
}
四、代理类调用
package com.casic.test.JdkProxy;
import org.junit.Test;
public class UserServiceTest {
@Test
public void test() {
UserService userService = new UserServiceImpl();
userService = (UserService) //
new LogProxy(userService).CreateProxyInstance();
userService.addUser();
}
}