java架构解密——深入再造AOP

来源:互联网 发布:淮南大数据展示中心 编辑:程序博客网 时间:2024/05/29 18:49

       在上篇博客中,大家和我一起研究了AOP的基本实现,但是,也给大家遗留了很多问题,在这篇博客,咱们一起研究如何针对这些问题进行持续的优化,看看在咱们的手里,AOP会成长为一个什么样的东西!

回顾:

看看上篇博客中,咱们一起实现的AOP类图:



咱们看看在CGLIB类里的问题

<span style="font-size:18px;">public class CGLibDynamicProxy implements MethodInterceptor {       private static CGLibDynamicProxy instance = new CGLibDynamicProxy();           private CGLibDynamicProxy() {      }       public static CGLibDynamicProxy getInstance() {          return instance;      }       @SuppressWarnings("unchecked")      public <T> T getProxy(Class<T> cls) {          return (T) Enhancer.create(cls, this);      }       @Override     public Object intercept(Object target, Method method, Object[] args, MethodProxy proxy) throws Throwable {          before();          Object result = proxy.invokeSuper(target, args);          after();          return result;      }     private void before() {          System.out.println("Before");      }       private void after() {          System.out.println("After");      } }


1,扩展服务


        这样我们的扩展就会变得困难,大家试想一下这个场景,我们写好的业务,需要增加一个功能,就要写一个代理类,功能的变化,也必须修改代码,这就给我们的代码维护带来了很大的负担!如果我们要第一次要扩展2个方法,写了代理,下一次扩展3个,写了代理,下一次扩展1个写了代理,下一次不想要第一次的第2个方法了,怎么办?的确,这样的维护,是我们不想看到的,所以,我们将扩展的公共服务放到了一个容器中,大家看类图:



1.1封装公共服务类:

<span style="font-size:18px;">public class ProxyMehds  {//盛放方法执行前的对象的容器private  HashMap<String,Object> beforBeans;    private  HashMap<String,Object> afterBeans;    //配制方法执行前要执行哪些方法private  HashMap<String,String> beforMethods;    private  HashMap<String,String> afterMethods;        @Override    public void beforeBean()  {              try{            for (HashMap.Entry<String, Object> entry : beforBeans.entrySet()) {        String objectKey = entry.getKey();        Object objectValure = entry.getValue();        Method beforMehod = objectValure.getClass().getMethod(beforMethods.get(objectKey));        beforMehod.invoke(objectValure);    }        }catch(Exception ex){    ex.printStackTrace();    }    //Method sAge = c.getMethod("setAge");    }       @Override    public void afterBean() {          try{            for (HashMap.Entry<String, Object> entry : afterBeans.entrySet()) {        String objectKey = entry.getKey();        Object objectValure = entry.getValue();        Method beforMehod = objectValure.getClass().getMethod(afterMethods.get(objectKey));        beforMehod.invoke(objectValure);    }        }catch(Exception ex){    ex.printStackTrace();    }            }public HashMap<String, Object> getBeforBeans() {return beforBeans;}public void setBeforBeans(HashMap<String, Object> beforBeans) {this.beforBeans = beforBeans;}public HashMap<String, Object> getAfterBeans() {return afterBeans;}public void setAfterBeans(HashMap<String, Object> afterBeans) {this.afterBeans = afterBeans;}public HashMap<String, String> getBeforMethods() {return beforMethods;}public void setBeforMethods(HashMap<String, String> beforMethods) {this.beforMethods = beforMethods;}public HashMap<String, String> getAfterMethods() {return afterMethods;}public void setAfterMethods(HashMap<String, String> afterMethods) {this.afterMethods = afterMethods;}}</span>

1.2封装代理类:

<span style="font-size:18px;">public class CGLibDynamicProxy implements MethodInterceptor {       private static CGLibDynamicProxy instance = new CGLibDynamicProxy();       private ProxyMehds proxyMehds;                private CGLibDynamicProxy() {      }       public static CGLibDynamicProxy getInstance() {          return instance;      }       @SuppressWarnings("unchecked")      public <T> T getProxy(Class<T> cls) {          return (T) Enhancer.create(cls, this);      }               @Override     public Object intercept(Object target, Method method, Object[] args, MethodProxy proxy) throws Throwable {      proxyMehds.beforeBean();          Object result = proxy.invokeSuper(target, args);          proxyMehds.afterBean();          System.out.println("");                return result;      }public ProxyMehds getProxyMehds() {return proxyMehds;}public void setProxyMehds(ProxyMehds proxyMehds) {this.proxyMehds = proxyMehds;}           }</span>

1.3服务类:

<span style="font-size:18px;">public class AspectClass1 {public void SayHello(){System.out.println("This is AspectClass1.SayHello!");}}</span>



1.4客户端:

<span style="font-size:18px;">public class Client {public static void main(String[] args) { HashMap<String,Object> beforBeans;    HashMap<String,Object> afterBeans;HashMap<String,String> beforMethods;    HashMap<String,String> afterMethods;        beforMethods=new HashMap();    beforBeans=new HashMap();    beforBeans.put("AspectClass1", new AspectClass1());        beforMethods.put("AspectClass1", "SayHello");    beforMethods.put("AspectClass2", "SayGoodBye");        afterMethods=new HashMap();    afterBeans=new HashMap();    afterBeans.put("AspectClass3", new AspectClass3());    afterBeans.put("AspectClass4", new AspectClass4());    afterMethods.put("AspectClass3", "SayHi");    afterMethods.put("AspectClass4", "Eat");        ProxyMehds proxyMehds =new ProxyMehds();    proxyMehds.setBeforBeans(beforBeans);    proxyMehds.setBeforMethods(beforMethods);    proxyMehds.setAfterBeans(afterBeans);    proxyMehds.setAfterMethods(afterMethods);    //实例代理类        CGLibDynamicProxy cglib =CGLibDynamicProxy.getInstance();                //接受切面        cglib.setProxyMehds(proxyMehds);                //接受要代理的对象        Greeting greeting = cglib.getProxy(GreetingImpl.class);                //执行对象的某个方法        greeting.sayHello("Jack");      } }</span>

总结:

        这样封装之后的好处是什么呢,就是我们的服务不再固定,而是在代理中定义了一个空壳子,这样每次使用,都是复用的空壳子,也是我们常说的框架,而后期的服务类是后加入的,在客户端动态初始化制定的,这样我们的扩展就变得方便,写好一个类,我们就可以直接配置下xml(类似于客户端的组装)就可以实现这样的功能!让功能的扩充变得简单!
        在代码的实现上,功能实现是编写代码的第一步,而我们的大多程序员都做到了第一步,想要获得更高的薪水,就要有些和其他人不一样的东西,那么,这时候,业务来理解水平,抽象能力,实现能力,优化能力,逐渐在以后的晋升中起到至关重要的作用,而这些能力有一个公共的父类,就是全局观,在全局上考虑问题,包含时间与空间两个方向,当时间长了,变化怎么办?人数多了,数据量大了怎么办?

        成为一个优秀的架构人员,我们要学习的还有很多!

2 0
原创粉丝点击