首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 软件管理 > 软件架构设计 >

(入门)什么是AOP?什么是代理模式?如何设计日志拦截器

2012-11-15 
(入门)什么是AOP?什么是代理模式?怎么设计日志拦截器??什么是AOP(Aspect?Oriented?Programming)?  面向切

(入门)什么是AOP?什么是代理模式?怎么设计日志拦截器?

?

什么是AOP(Aspect?Oriented?Programming)?

  面向切面编程(也叫面向方面编程):Aspect?Oriented?Programming(AOP),是目前软件开发中的一个热点,也是Spring框架中的一个重要内容。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。


(入门)什么是AOP?什么是代理模式?如何设计日志拦截器

  主要的功能是:日志记录,性能统计,安全控制,事务处理,异常处理等等。

  主要的意图是:将日志记录,性能统计,安全控制,事务处理,异常处理等代码从业务逻辑代码中划分出来,通过对这些行为的分离,我们希望可以将它们独立到非指导业务逻辑的方法中,进而改??变这些行为的时候不影响业务逻辑的代码。

  AOP的底层实现技术是JDK动态代理。可以通过预编译方式和运行期动态代理实现在不修改源代码的情况下给程序动态统一添加功能的一种技术。AOP实际是GoF设计模式(GoF强调的是接口或抽象类在实际案例中的灵活应用和智慧)的延续,设计模式孜孜不倦追求的是调用者和被调用者之间的解耦,AOP可以说也是这种目标的一种实现。

?

代理模式Proxy?Pattern,23种java常用设计模式之一。代理模式的定义:对其他对象提供一种代理以控制对这个对象的访问。代理模式的主要作用是为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个对象不想或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。代理模式的思想是为了提供额外的处理或者不同的操作而在实际对象与调用者之间插入一个代理对象。这些额外的操作通常需要与实际对象进行通信。

-----------------------------------------------------

//Junit测试类

@Test

public?void?testProxy()?{

??UserDAO?userDAO?=?new?UserDAOImpl();//新建被拦截类

??LogInterceptor?li?=?new?LogInterceptor();//新建日志拦截器

??li.setTarget(userDAO);//把被拦截的类添加到拦截器里面去

??UserDAO?userDAOProxy?=?(UserDAO)Proxy.newProxyInstance

(userDAO.getClass().getClassLoader(),

userDAO.getClass().getInterfaces(),?li);//根据拦截器生成代理类,下面有解释

??System.out.println(userDAOProxy.getClass());//输出代理类的名

??userDAOProxy.save(new?User());//往代理类进行操作

??userDAOProxy.delete();

}

-----------------------------------------------------

//LogInterceptor日志拦截类

import?java.lang.reflect.InvocationHandler;

import?java.lang.reflect.Method;

//拦截器类要继承自InvocationHandler,InvocationHandler?是代理实例的调用处理程序实现的接口

public?class?LogInterceptor?implements?InvocationHandler?{

private?Object?target;

//拦截器的setter和getter方法

public?Object?getTarget()?{

return?target;

}

public?void?setTarget(Object?target)?{

this.target?=?target;

}

//Method是方法,beforeMethod就是方法在执行之前的方法

public?void?beforeMethod(Method?m)?{

System.out.println(m.getName()?+?"?start");

}

?

//Object?invoke(Object?proxy,?Method?method,?Object[]?args)?方法是在代理实例上处理方法调用并返回结果。每个代码实例都具有一个关联的调用处理程序。对代理实例调用方法时,将对方法调用进行编码并将其指派到它的调用处理程序的?invoke?方法。也就是说:调用一个功能,不直接调用原类而去调用它的代理,代理通过反射机制找到它的这个功能的方法。然后代理自己去执行,所以invoke()会自动执行.

public?Object?invoke(Object?proxy,?Method?m,?Object[]?args)

throws?Throwable?{

beforeMethod(m);

m.invoke(target,?args);//关于加不加这句请看下面分析

return?null;

}

}

-----------------------------------------------------

//加m.invoke(target,?args)的输出结果:

class?$Proxy4

save?start

user?saved!

save?start

user?saved!

save?start

user?saved!

delete?start

user?deteleted

//不加m.invoke(target,?args)的输出结果:

class?$Proxy4

save?start

save?start

save?start

delete?start

//save start是beforeMethod()的输出,

user?saved是UserDAOImpl的save()的输出。不知道怎么解释了?求大神,大家帮忙。意会意会一下.....

?

?

?

*。关于代理类,JDK?中具体的动态代理类是怎么产生的呢?

?

1.产生代理类$Proxy0?类:

执行了?Proxy.?newProxyInstance(ClassLoader?loader,?Class[]?interfaces,?InvocationHandler?h)将产生$Proxy0?类,它继承Proxy?对象,并根据第二个参数,实现了被代理类的所有接口,自然就可以生成接口要实现的所有方法了(这时候会重写hashcode?,toString?和equals?三个方法),但是还没有具体的实现体。

?

2.将代理类$Proxy0类加载到JVM中,这时候是根据?Proxy.?newProxyInstance(ClassLoader?loader,?Class[]?interfaces,?InvocationHandler?h)?它的第一个参数----?就是被代理类的类加载器,把当前的代理类加载到JVM?中。

?

3.创建代理类$Proxy0类的对象,调用的$Proxy0类的$Proxy0?(InvocationHandler?)构造函数,生成$Proxy0?类的对象,参数就是?Proxy.?newProxyInstance(ClassLoader?loader,?Class[]?interfaces,?InvocationHandler?h)?它的第三个参数,这个参数就是我们自己实现的InvocationHandler?对象,我们知道InvocationHandler?对象中组合加入了代理类代理的接口类的实现类;所以,$Proxy0?对象调用所有要实现的接口的方法,都会调用InvocationHandler?对象的invoke?()方法实现。

4.生成代理类的class?byte,动态代理生成的都是二进制class?字节码。

?

?

?

⊙_⊙最后,按照我的惯例,附上本次的项目源码,类库用到三个(spring.jar ?junit.jar(eclipse自带) commons-logging.jar 缺少类库到http://moshowgame.iteye.com/admin/blogs/1606825下载)。

^_^还有什么好方法或者疑问和意见欢迎大家提出来一起讨论!

热点排行