场景
动态代理就是为了实现一些业务功能增强的设计模式;
比如说 现在有一个添加用户的功能,我们需要不改变原有代码的情况下对其功能做出增强(增加),我们可以使用静态代理(不方便再次修改,代码有冗余),或者继承过来再重写一下(代码冗余太多,不推荐);
所有就用动态代理处理。
实现代码
现在有一个原本的业务接口 UserService.java
public interface UserService {
//添加用户的方法
int addUser(String name);
}
然后就是他原本的实现类
UserServiceImpl.java
public class UserServiceImpl implements UserService {
@Override
public int addUser(String name) {
System.out.println("添加的用户是:" + name);
if (name != null && name.trim() != null) {
//添加成功
return 1;
} else {
//添加失败
return 0;
}
}
}
这个时候我们对这个add方法进行一波强化,就是打印一下日志;创建动态代理增强类 MyUserServiceProcessor.java
//必须实现InvocationHandler 接口
public class MyUserServiceProcessor implements InvocationHandler {
private Object target;
//有参构造赋值被代理对象
public MyUserServiceProcessor(Object target){
this.target=target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
int res=0;
//调用原本接口的add方法 并且拿到add方法的返回值invoke
Object invoke = method.invoke(target, args);
//将返回值invoke转换为 int类型
res=(Integer) invoke;
//根据原本接口的方法返回值 进行日志打印
if (res==1){
System.out.println("添加成功:时间是:"+new Date());
}else {
System.out.println("添加失败:时间是:"+new Date());
}
//返回返回值
return res;
}
}
测试Test.java
public static void main(String[] args) {
//创建被代理类对象
UserService userService = new UserServiceImpl();
//创建代理类对象
InvocationHandler invocationHandler = new MyUserServiceProcessor(userService);
//使用java反射包的Proxy类进行创建动态代理
UserService us = (UserService)Proxy.newProxyInstance(
userService.getClass().getClassLoader(),
userService.getClass().getInterfaces(),
invocationHandler);
//调用增强之后的方法
int tom = us.addUser("tom");
System.out.println("tom = " + tom);
}
输出
总结
代理的作用:
1、功能增强(原有基础功能上增加额外功能)原有功能不该变的情况下,实现
2、控制访问(不能直接访问,只能通过代理访问)
2、动态代理:
实现方式
1、jdk动态代理
使用Java反射包中的类和接口实现动态代理功能
重要的类以及方法:
java.lang.reflect
InvocationHandler
Proxy
Method
2、cglib动态代理
第三方的工具库,创建代理对象
原理就是继承 就是重写方法的方式
要求目标类以及其方法不能是final修饰