技术开发 频道

Spring AOP: Spring之面向方面编程

无论你怎么创建AOP代理,你都可以使用org.springframework.aop.framework.Advised 接口来操作它们。任何AOP代理无论实现其它什么接口,都可以类型转换为这个接口。这个接口包括下列方法:

void addInterceptor(Interceptor interceptor) throws AopConfigException; void addInterceptor(int pos, Interceptor interceptor) throws AopConfigException; void addAdvisor(Advisor advisor) throws AopConfigException; void addAdvisor(int pos, Advisor advisor) throws AopConfigException; int indexOf(Advisor advisor); boolean removeAdvisor(Advisor advisor) throws AopConfigException; void removeAdvisor(int index) throws AopConfigException; boolean replaceAdvisor(Advisor a, Advisor b) throws AopConfigException; boolean isFrozen();

 getAdvisors()方法为工厂中的每个advisor,拦截器或者其它通知类型返回一个Advisor。 如果你添加一个Advisor,使用当前索引返回的advisor就是你添加的对象。如果你添加拦截器或其它通知类型, Spring将当前对象和一个满足要求的切入点封装在一个advisor里。因此,如果你添加 MethodInterceptor, 使用当前索引返回的advisor是一个DefaultPointcutAdvisor,这个advisor返回 MethodInterceptor和满足所有类和方法的切入点。

addAdvisor()被用来添加Advisor。通常会是一个普通的 DefaultPointcutAdvisor,它可以和任何通知或切入点(除了引用)一起使用。

缺省情况下,在每次代理被创建的时候添加或删除advisor或拦截器。唯一的限制是不能添加或删除 引入advisor,因为工厂提供的已存在的代理不反映接口的变化。(你可以从工厂得到一个新的代理来避免这个问题)

是否建议在产品中修改业务对象的通知还值得怀疑,虽然毫无疑问存在合理的使用情况。但是, 在开发中这是非常有用的:例如,在测试中。我有时候发现以拦截器或其它通知的形式来添加测试代码非常有用, 这样就可以进入我想要测试的方法调用。(例如,通知可以进入为这个方法创建的事务中: 在为回滚事务作标记前,运行SQL检查数据库是否被正确更新。)
根据你创建代理的方式,你通常可以设置frozen标记,这样Advised 的isFrozen()就返回true,任何添加或删除通知都将导致 AopConfigException。这种冻结被通知对象状态的方法在一些情况下是非常有用的: 例如,为了阻止调用代码删除一个安全拦截器。如果已知运行时修改通知不被允许,这还可以被Spring 1.1用来 作优化。

0
相关文章