jdk 动态代理也是一种设计模式,动态代理模式可以在原有的方法前后添加判断,选择或者其他逻辑。
实现步骤如下:
1. 先写一个业务的接口
public interface UserService {
public UserT getById();
public int add(UserT userT);
public boolean delete(String userId);
}
2.写这个接口的实现类
public class UserServiceImpl implements UserService {
public UserT getById() {
System.out.println("执行了 getById 方法");
return null;
}
public int add(UserT userT) {
System.out.println("执行了 add 方法");
return 1;
}
public boolean delete(String userId) {
System.out.println("执行了 delete 方法");
return true;
}
}
3.写InvocationHandler (和反射的知识有关,不需要深入了解,步骤简单) 的实现类,这个实现类成为代理工厂。额外的切面逻辑在代理工厂的invoke方法添加。
method.invoke(target,args)是执行实际的业务方法,在这个方法的前后添加切面逻辑。target 是被代理的对象。
public class ProxyFactory implements InvocationHandler {
private Object target;
public ProxyFactory(Object target){
this.target=target;
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("传入参数是: "+args.toString());
Object result=method.invoke(target,args);
System.out.println("执行结果是:"+result);
return result;
}
public Object getProxy(){
return Proxy.newProxyInstance(target.getClass().getClassLoader(),
target.getClass().getInterfaces(),this);
}
}
4.使用:
public class ProxyDemo {
public static void main(String args[]){
UserService userService=new UserServiceImpl();
Class<?>[] interfaces = userService.getClass().getInterfaces();
UserService proxy=(UserService)new ProxyFactory(userService).getProxy();
proxy.add(new UserT());
//以下为测试不写业务接口的情况,测试结果为不写接口是不行的。
/*NewUserSerciceImpl userService=new NewUserSerciceImpl();
Class<?>[] interfaces = userService.getClass().getInterfaces();
NewUserSerciceImpl proxy=(NewUserSerciceImpl)new ProxyFactory(userService).getProxy();
proxy.add(new UserT());*/
}
}
使用结果:
传入参数是: [Ljava.lang.Object;@19e1023e
执行了 add 方法
执行结果是:1
以上就是实现步骤。
注意点: 不写被代理对象的接口行不行?答案是不行的。看源代码,从代理工厂获取代理有这么一段代码,是这样获取代理的:
public Object getProxy(){
return Proxy.newProxyInstance(target.getClass().getClassLoader(),
target.getClass().getInterfaces(),this);
}
可以看到,获取代理过程中,需要该对象的接口,没有的话,会报错的。