我们知道Spring主要有两大思想,一个是IoC,另一个就是AOP,对于IoC,依赖注入就不用多说了,而AOP的原理就是java的动态代理机制
在java的动态代理机制中,有两个重要的类或接口,一个是InvocationHandler(Interface)、另一个则是 Proxy(Class)
实例:在现在常见的系统中,登录和退出是用户必备的操作之一,下面我就设计这么一个接口,用于处理用户的登录和退出操作
public interface User {
/**
* 登录
* @param name 用户名
* @param pwd 密码
* @return
*/
public boolean login(String username, String pwd);
/**
* 退出
*/
public void logout(String username);
}```
委托类:
public class UserImpl implements User{
@Override
public boolean login(String username, String pwd) {
// 简化问题,直接登录成功
System.out.println(username+" 登录成功.");
return true;
}
@Override
public void logout(String username) {
System.out.println(username+" 成功退出.");
}
}```
代理类:
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* 继承动态代理接口的代理类
*/
public class UserDynamicProxy implements InvocationHandler{
// 在线人数
public static int count = 0;
// 委托对象
private Object target;
/**
* 返回代理对象
* @param target
* @return
*/
@SuppressWarnings("unchecked")
public <T> T getProxyInstance(Object target) {
// 委托对象,真正的业务对象
this.target = target;
// 获取Object类的ClassLoader
ClassLoader cl = target.getClass().getClassLoader();
// 获取接口数组
Class<?>[] cs = target.getClass().getInterfaces();
// 获取代理对象并返回
return (T)Proxy.newProxyInstance(cl, cs, this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object r = null;
// 执行之前
r = method.invoke(target, args);
// 判断如果是登录方法
if("login".equals(method.getName())) {
if((boolean)r == true) {
// 当前在线人数+1
count += 1;
}
}
// 判断如果是退出方法
else if("logout".equals(method.getName())) {
// 当前在线人数-1
count -= 1;
}
showCount(); // 输出在线人数
// 执行之后
return r;
}
/**
* 输出在线人数
*/
public void showCount() {
System.out.println("当前在线人数:"+count+" 人.");
}
}```
测试类:
public class Main {
public static void main(String[] args) {
// 真实角色,委托人
User user = new UserImpl(); // 可执行真正的登录退出功能
// 代理类
UserDynamicProxy proxy = new UserDynamicProxy();
// 获取委托对象user的代理对象
User userProxy = proxy.getProxyInstance(user);
// 系统运行,用户开始登录退出
userProxy.login("小明", "111");
userProxy.login("小红", "111");
userProxy.login("小刚", "111");
userProxy.logout("小明");
userProxy.logout("小刚");
userProxy.login("小黄", "111");
userProxy.login("小黑", "111");
userProxy.logout("小黄");
userProxy.login("小李", "111");
userProxy.logout("小李");
userProxy.logout("小黄");
userProxy.logout("小红");
}
}```
输出结果如下:
小明 登录成功.
当前在线人数:1 人.
小红 登录成功.
当前在线人数:2 人.
小刚 登录成功.
当前在线人数:3 人.
小明 成功退出.
当前在线人数:2 人.
小刚 成功退出.
当前在线人数:1 人.
小黄 登录成功.
当前在线人数:2 人.
小黑 登录成功.
当前在线人数:3 人.
小黄 成功退出.
当前在线人数:2 人.
小李 登录成功.
当前在线人数:3 人.
小李 成功退出.
当前在线人数:2 人.
小黄 成功退出.
当前在线人数:1 人.
小红 成功退出.
当前在线人数:0 人.```