AOP,为Aspect OrientedProgramming的缩写,意为:面向切面,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。
说了一堆很官方的话,大家可能不是特别明白,不过这些算是我们实践的理论寄出去,还是很有必要知道的,但是现在不必要很懂,接下来从最简单的代码开始,一步步的慢慢深入了解,到底什么是AOP,什么是代理模式。学习,就是这样一个理论与实践相结合的过程。
先来看一下最基本的,没有任何优化的代码:
/** * 业务接口类 * @author sunliduan * */ public interface Greeting { void sayHello(String name); }
package com.tgb.sld; /** * 业务实现类 * @author sunliduan * */ public class GreetingImpl implements Greeting { @Override public void sayHello(String name) { System.out.println("Hello! " + name); } }
由于业务变动,我需要在执行sayHello之前,插入一段代码b,实现某项功能,例如日志或者工作流等。最简单的就是直接在业务实现类里直接插入这段代码,然后在sayHello方法中调用这段代码。详见以下代码:
package com.tgb.sld; /** * 业务实现类 * @author sunliduan * */ public class GreetingImpl implements Greeting { @Override public void sayHello(String name) { before(); System.out.println("Hello! " + name); after(); } private void before() { System.out.println("Before==我在被切类的里面"); } private void after() { System.out.println("After==我在被切类的里面"); } }
可是这样有很多缺点:首先是插入的方法before()和after()不能得到复用,某一个需要插入这两个方法的类都需要复制粘贴到本类中;而过多的复制粘贴也必然造成维护极不方便,我们需要修改每一处复制粘贴的地方,一不小心有一个地方忘记修改了,那可就麻烦啦。其次要想插入新的功能方法,我们必须停止已经运行的服务,重新编译部署,这对用户来说是很不友好的。
为了解决以上的问题,我们可以使用代理模式,且看下面代理模式的一步步发展。
第一步:静态代理,其实就是设计模式中的Proxy模式。
/** * 业务接口类 * @author sunliduan * */ public interface Greeting { void sayHello(String name); }
/** * 业务实现类 * @author sunliduan * */ public class GreetingImpl implements Greeting { @Override public void sayHello(String name) { System.out.println("Hello! " + name); } }
为了实现切入方法和业务方法的解耦,我们加入了一个代理类:
/** * 静态代理类 * * @author sunliduan * */ public class GreetingStaticProxy implements Greeting { private Greeting greeting; // 用静态代理类GreetingProxy代替Greeting类 public GreetingStaticProxy(Greeting greeting) { super(); this.greeting = greeting; } @Override public void sayHello(String name) { before(); greeting.sayHello(name); after(); } private void before() { System.out.println("Before==通过静态代理把我加到被切方法之前"); } private void after() { System.out.println("After==通过静态代理把我加到被切方法之后"); } }
来看一看客户端如何调用:
public class Client { public static void main(String[] args) { Greeting staticProxyGreeting = new GreetingStaticProxy(new GreetingImpl()); staticProxyGreeting.sayHello("sunliduan"); } }
业务不需要专门去调用,而是走到静态代理类里的sayHello方法,顺理成章的执行了切入方法,并调用了原来的业务方法。
可以说静态代理也就是设计模式中的代理模式,它是AOP的雏形。不过从这段代码看:1、要实现代理方式,必须要定义接口。2、每个业务类,必须有一个代理类。
但是一个业务类需要对应一个代理类,这样的代码还是有坏味道的,还是不能实现很好的复用。接下来动态代理就来了,敬请期待下一篇博客~~