读书人

Spring AOP 学习(1) 代理模式

发布时间: 2013-03-10 09:38:39 作者: rapoo

Spring AOP 学习(一) 代理模式
public interface Service {public void sayHello();}

?

2.ServiceImpl实现类:主要是打印HelloWord,但是日常项目中,在主要业务前后可能会添加日志记录,或者开启事务等其他必要操作。

public class ServiceImpl implements Service{@Overridepublic void sayHello() {System.out.println("前置日记:打印、启动事务等..");System.out.println("Hello world!");System.out.println("后置日记:打印、关闭事务等..");}}

?

例子很简单,那么假设,我们不光拥有sayHello ,还有sayBye 等多个方法,并且都需要其他操作呢?那么你是不是会写很多个这样的,重复的代码?

当然,你可以减少一部分工作量,你可以这样:

public class ServiceImpl implements Service{@Overridepublic void sayHello() {before();System.out.println("Hello world!");after();}@Overridepublic void sayBye() {before();System.out.println("Bye bye!");after();}public static void before(){System.out.println("前置日记:打印、启动事务等..");}public static void after(){System.out.println("后置日记:打印、关闭事务等..");}}

?

我们再次假设,如果我们拥有更多的业务方法:sayHi(),sayOther()....,需要更多的其他操作:打印信息,传输记录....。并且其他ServiceImpl 里面的方法也需要这些方法呢?那么我们是不是每个类又要继续添加呢?

当然,你可以这样做:建立一个对Service 添加额外功能的类,统一提供。

public class ServiceFactory {public static void before(){System.out.println("前置日记:打印、启动事务等..");}public static void after(){System.out.println("后置日记:打印、关闭事务等..");}public static void other(){System.out.println("做其他的事..");}}

?

ServiceImpl 就成这样:

public class ServiceImpl implements Service{@Overridepublic void sayHello() {ServiceFactory.before();System.out.println("Hello world!");ServiceFactory.after();}@Overridepublic void sayBye() {ServiceFactory.before();System.out.println("Bye bye!");ServiceFactory.after();}@Overridepublic void sayHi() {ServiceFactory.before();System.out.println("Hi");ServiceFactory.after();ServiceFactory.other();}}

?

?这样代码,感觉是少了一些,但是我们的原则是尽量 别重复同样的代码,提高代码的复用性,改动最小为基准。也许业务很复杂,比较多,那么你要重复多少代码,整个类要写得多麻烦所啊!如果到时候有些假设before 和after 需要变化位置,你又要改动多少呢?

?

当然,目前的的JDK (大于1.3)为了解决这些问题,为我们提供的反射机制,动态代理机制。看看如何更好的解决这个问题。这里先copy 下,什么是代理:

?

Java的动态代理机制
代理模式是常用的Java设计模式。代理类主要负责为委托类预处理消息、过滤信息、把消息转发给委托类,以及事后处理信息等。
??? 理论 - -总是那么抽象(~。~),简单点说,就是:1.我的目的是去学校,那么校服 早餐 校车,这些我都需要,但是不由我做,全部代理给我父母搞定了(当然我是自己搞定的。)2.再简单的说就是:我只关注我主要的事情,其他附加的事情,全部交给别人搞定。看代码..

MyPorxy 我的代理类:

import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;public class MyProxy implements InvocationHandler{// 目标对象,也就是我们主要的业务,主要目的要做什么事private Object delegate;/** * 和你额外需要做得事情,进行绑定,返回一个全新的对象(写法,基本上固定的) * @param delegate * @return */public Object bind(Object delegate){this.delegate = delegate;return Proxy.newProxyInstance(this.delegate.getClass().getClassLoader(), this.delegate.getClass().getInterfaces(), this);}/** * 你刚才需要执行的方法,都需要通过该方法进行动态调用 */@Overridepublic Object invoke(Object proxy, Method method, Object[] args)throws Throwable {Object obj = null;// 执行前置的方法ServiceFactory.before();// 通过反射,执行目标方法,也就是你的主要目的obj = method.invoke(this.delegate, args);// 执行后置的方法ServiceFactory.after();// 返回值给调用者return obj;}}

?

这里运用的反射知识,还需要去看看,这里就不解释了。

?

ServiceImpl 变化:

public class ServiceImpl implements Service{@Overridepublic void sayHello() {System.out.println("Hello world!");}@Overridepublic void sayBye() {System.out.println("Bye bye!");}@Overridepublic void sayHi() {System.out.println("Hi");}}

?

?? 测试类:

?

public class Test {/** * 测试类 * @param args */public static void main(String[] args) {// 不启用代理//Service service = new ServiceImpl();// 使用代理Service service = (Service)new MyProxy().bind(new ServiceImpl());service.sayHello();service.sayBye();service.sayHi();}}

?

?

OK,那么你现在看看,我们的业务实现类ServiceImpl 是不是干净多了,代码是不是在某些地方见过呢?即时你再进行添加更多的方法,也可以同样实现了对吗?当然,在Test里面,假设我们有的方法想用,有的方法不想用,那么又该怎么实现呢?

?

读书人网 >编程

热点推荐