java中的AOP [
Aspect Oriented Programming
] 代理,本章需要对java中的【反射机制】有所了解。否则听起来可能似懂非懂的样子。
java中有自己的原生代理。在学习代理之前需要明白什么是代理。 假如方法的执行到得到返回值比喻成 电源 --- 电灯,那么代理就是开关。
在一般理解中 代理就是 目的出发点到目的结束点中间的非直接内容过程大概可以描述为
|----V----| 电源【方法】 --------- 开关【代理】 ---------电灯【返回值】
在没有代理的时候应该是
电源【方法】 ---------电灯【返回值】
中间的代理层环节就是我们需要理解的部分。一般,使用代理的时候都是在事务控制,权限控制上。 我们需要事务的一致性来保证数据库数据完整性,我们需要根据不同的角色界定不同的权限。事实上,这些东西完全可以用手动来控制,但是,在多数情况下,我们需要控制的事务、角色太多,就会偏离了我们本来应该关心的方面。
以上皆为扯淡,以下为正文
现在我们来实现代理过程
要实现代理,那么最好是面向接口的编程。
public interface User{
/**添加增加user的方法*/
public boolean addUser(String userName,String pass);
}
创建的接口,接下来就是写它的实现类
public class UserImpl implements User {
private Map<String,String> userMap = new HashMap<>();
public UserImpl () { /*something*/}
@Override
public boolean addUser(String userName,String pass){
boolean hasOne= userMap.containsKey(userName);
if(!hasOne){
userMap .put(userName,pass);
return true;
}
return false;
}
}
接下来就是实现代理接口【java.lang.reflect.InvocationHandler
】
public class UserProxy implements InvocationHandler {
private Object targetObject;//接受代理对象
public UserProxy(Object targetObject){
this.targetObject =targetObject;
}
/**复写代理接口调用方法
*@param proxy 代理对象
*@param method 目标方法
*@param args 目标方法参数
*@return Object 目标方法返回值
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args){
User user = (UserImpl)targetObject;//将传入的对象转成需要的对象
/*
*method【当前方法】
*method.invoke(targetObject【目标对象这里的就是User 】,args【方法参数】)
*/
Object result=method.invoke(targetObject, args);//调用method的反射方法执行
return result;
}
}
实现了接口代理之后,我们就来测试一下,我们使用【java.lang.reflect.Proxy
】来生成代理对象,传入类加载器,类的接口对象,代理对象
public class UserProxyEXEC {
public static void main(String[] arges){
User user = new UserImpl();
UserProxy proxy = new UserProxy(user);
User u = (User) Proxy.newProxyInstance(
user.getClass().getClassLoader(), user.getClass()
.getInterfaces(), proxy);
boolean bool = u.addUser("zhangsan", "lisi");
System.out.println(bool);
}
}
现在我们需要对原来的代理方法进行扩展,让他指定如果当前第一个参数userName是
admin
,就不让他添入。
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
User user = (UserImpl)targetObject;
Object result =null;
for (int i = 0; i < args.length; i++) {
if(args[i] == null||"".equals(args[i])){
System.out.println("第"+(i+1)+"个参数为null");
return false;}
if(args[0] instanceof String){
if("admin".equalsIgnoreCase((String)args[i])){
return false;
}
}
}
result=method.invoke(targetObject, args);
return result;
}
将当前的传入参数控制一下,就可以完成对方法的控制了,是不是很简单!
下一章
将前两章内容结合一下,使用注解+代理的方式,来实现注解对方法的控制