导读:请注意,只是用代码简单的实现了一下,并未深追源码或者做详细的解释。
正文:
Spring的Aop是基于Java的动态代理来实现的,java中动态代理有两种实现方式:
- cglib
- jdk
下面的例子是基于jdk动态代理的简单实现:
UserLogin:
public interface UserLogin {
String login(String username, String password);
}
UserLoginImpl:
public class UserLoginImpl implements UserLogin {
@Override
public String login(String username, String password) {
String msg = "login="+username+"+"+password;
System.out.println(msg);
return msg;
}
}
LoginProxy:
public class LoginProxy {
public static Object getInstance(final UserLogin object){
return Proxy.newProxyInstance(LoginProxy.class.getClassLoader(), object.getClass().getInterfaces(), new InvocationHandler() {
/**
*
* @param proxy 代理对象
* @param method 方法
* @param args 方法的参数
* @return
* @throws Throwable
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println(method.getName()+" 要执行了");
Object invoke = method.invoke(object,args);
System.out.println(method.getName()+" 执行完了");
return invoke;
}
});
}
public static void main(String[] args) {
UserLogin userLogin = new UserLoginImpl();
UserLogin object = (UserLogin) LoginProxy.getInstance(userLogin);
object.login("user","456");
}
}
测试结果:
login 要执行了
login=user+456
login 执行完了
标红出不可以换成:
UserLogin.class.getInterfaces()
否则会报错如下:
Exception in thread "main" java.lang.ClassCastException: com.sun.proxy.$Proxy0 cannot be cast to com.ph.UserLogin
at com.ph.LoginProxy.main(LoginProxy.java:31)
原因是:getInterfaces方法在java反射中的作用是:获取对象的所有接口。而在测试的过程中(main方法内),给getInstance()方法传的是实现接口的对象,提供了接口的信息,符合要求。UserLogin本身就是接口,用UserLogin.class会报错。(未深究,欢迎批评指正)