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;}
将当前的传入参数控制一下,就可以完成对方法的控制了,是不是很简单!
下一章
将前两章内容结合一下,使用注解+代理的方式,来实现注解对方法的控制