为什么需要代理?
如何创建代理
注意:
实现类和代理需要实现同一个接口
接口
public interface Star {
String sing(String song);
void dance();
}
实现类
public class BigStar implements Star {
private String name;
public BigStar(String name) {
this.name = name;
}
public String sing(String song) {
System.out.println(name + " is singing " + song);
return "success";
}
public void dance() {
System.out.println(name + " is dancing " );
}
}
代理类
public class ProxyUtil {
public static Star createProxy(Star target) {
/**
* ClassLoader loader, 加载类的类加载器 一般使用当前类的类加载器
* Class<?>[] interfaces, 代理类要实现的接口列表 有哪些方法需要代理
* InvocationHandler h 代理类的调用处理程序 实现接口 怎么代理这些方法
*/
Star starProxy = (Star) Proxy.newProxyInstance(ProxyUtil.class.getClassLoader(),
new Class[]{Star.class},
// 代理类的调用处理程序
new InvocationHandler() {
@Override
// 参数一:代理对象 参数二:当前调用的方法 参数三:方法的参数
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object result = null;
if ("sing".equals(method.getName())) {
beforeSing();
result = method.invoke(target, args);
afterSing();
} else if ("dance".equals(method.getName())) {
beforeDance();
result = method.invoke(target, args);
afterDance();
}
return result;
}});
return starProxy;
}
// 前置增强
public static void beforeSing() {
System.out.println("唱歌之前");
}
// 后置增强
public static void afterSing() {
System.out.println("唱歌之后");
}
// 前置增强
public static void beforeDance() {
System.out.println("跳舞之前");
}
// 后置增强
public static void afterDance() {
System.out.println("跳舞之后");
}
}
使用代理对象
- 生成实现类对象
- 将实现类对象传递给代理对象
- 使用代理对象调用对应的方法(代理对象不仅会调用原本实现类的方法,还会调用前置增强和后置增强)
// 生成具体的类
Star star = new BigStar("Jay");
// 生成代理类
Star proxy = ProxyUtil.createProxy(star);
String sing = proxy.sing("七里香");
System.out.println(sing );
proxy.dance();
实际案例
需求
接口
public interface UserService {
// 登录功能
void login(String username, String password) throws Exception;
// 删除功能
void delete() throws Exception;
// 查询功能
String[] selectUsers() throws Exception;
}
实现类
public class UserServiceImpl implements UserService{
@Override
public void login(String username, String password) throws Exception {
if ("admin".equals(username) && "123456".equals(password)) {
System.out.println("登录成功");
} else {
System.out.println("登录失败");
}
Thread.sleep(1000);
}
@Override
public void delete() throws Exception {
System.out.println("删除用户");
Thread.sleep(1500);
}
@Override
public String[] selectUsers() throws Exception {
System.out.println("查询用户");
String[] users = new String[]{"张三", "李四", "王五"};
Thread.sleep(2000);
return users;
}
}
代理类
public class ProxyUtil {
public static UserService createProxy(UserService target) {
// 如果只执行了原本的方法,但是没有执行前置增强和后置增强,那么就是没有代理成功
// 原因一般是返回了最开始的target对象,而不是代理对象
return (UserService) Proxy.newProxyInstance(ProxyUtil.class.getClassLoader(),
new Class[]{UserService.class},
(proxy, method, args) -> {
Object result = null;
long start = before();
result = method.invoke(target, args);
long end = after();
takeTime(start, end);
return result;
});
}
private static long before() {
System.out.println("前置增强");
return System.currentTimeMillis();
}
private static long after() {
System.out.println("后置增强");
return System.currentTimeMillis();
}
private static void takeTime(long start,long end) {
System.out.println("耗时:" + (end - start)/1000 + "s");
}
}
使用
public class Main {
public static void main(String[] args) throws Exception {
UserService userService = new UserServiceImpl();
UserService proxy = ProxyUtil.createProxy(userService);
proxy.login("admin", "123456");
proxy.delete();
proxy.selectUsers();
}
}