知识大全 面向方面编程(AOP)和Jboss

Posted

篇首语:真正的知识使人真正地、实实在在地胜过他人。本文由小常识网(cha138.com)小编为大家整理,主要介绍了知识大全 面向方面编程(AOP)和Jboss相关的知识,希望对你有一定的参考价值。

面向方面编程(AOP)和Jboss  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!

  概述

  面向方面编程(Aspect Oriented Programming AOP)是一个令人兴奋的新模式 就开发软件系统而言 它的影响力将会和有 到 年的面向对象一样 面向方面编程和面向对象编程不但不是互相竞争的技术而且是可以很好的互补 面向对象编程主要用于为同一对象层次的公用行为建模 它的弱点是将公共行为应用于多个无关对象模型之间 而这恰恰是AOP适合的地方 AOP允许定义交叉的关系 那些关系应用于跨国分开的 非常不同的对象模型 AOP允许你层次化功能性而不是嵌入功能性 那使得代码有更好的可度性和易于维护性 我喜欢认为OOP是自上而下的软件开发 而AOP是自左而右的软件开发 它们是完全直交的技术 并且互相很好的补充

  在OOP的工具里是继承 封装和多态 而AOP的组件是通知/拦截器 导言 元数据和pintcuts 让我们看一下这些定义

  通知/拦截器

  一个通知是一个逻辑 这个逻辑有特定的事件触发 它是行为 这个行为能够被插入在调用者和被调用者之间 在一个方法调用者和实际的方法之间 通知是AOP真正的关键 通知允许你去透明的应用一些事物 像日志和记录到一个存在的对象模型

  在 JBoss AOP中 我们用拦截器是实现了通知 你能够定义拦截器 它拦截方法调用 构造器调用和域访问 后面 我们将阐明怎样应用这些拦截器到一个存在的对象模型

  导言

  导言是一个增加方法或者域到一个存在的类中的途径 它们甚至允许你改变当前存在的类是显的接口 并且引入一个混合的类 这个类是实现了新的接口 导言允许你带入多继承到一般的Java类 导言一个主要的用例是当你有一个方面 你想让这个方面有一个运行时间借口时 你想应用你的方面跨越不同的对象层次 但是你仍然要应用开发者去能够调用特定方面的APIs

  Apple apple = new Apple();  LoggingAPI logging = (LoggingAPI)apple;  Apple setLoggingLevel(VERBOSE);  导言能够是一个方法 它将一个新的API绑定到一个存在的对象模型

  元数据

  元数据是能够绑定到一个类的附加信息 在静态或者运行时间 元数据更加有力力量的是 你能够动态绑定元数据到一个给定的对象实例 元数据非常强大的 当你真正编写应用于任何对象的一般方面 而逻辑需要知道制定类的信息时 在使用的一个好的元数据类比就是EJB规范 在EJB的XML发布描述符中 你需要定义基于每一个方法的事务属性 应用服务器指导什么时候 什么地方开始 挂起或者提交一个事务 因为你在BEAN的XML的配置文件中的元数据内已经定义如方法 Required RequiresNew Support等等 它们绑定在你的EJB类和事务管理之间

  C#把元数据成为了这个语言的组成部分 XDoclet是另一个动作的元数据的例子 如果你曾经用过XDoclet生成过EJB文件和发布描述符 你就会知道元数据的力量 在JDK 中 当元数据被加入java语言中 JCP一致同意 (见JSR ) 尽管直到JSR 成为了事实 一个好的AOP框架也应该提供一种机制去定义在运行时间有效的类级元数据 Pointcuts

  如果拦截器 导言和元数据是AOP的特征 那么pointcuts就是粘合剂 Pointcuts告诉AOP框架 那些拦截器绑定到那些类 什么原数据将应用于那些类或者那一个导言将被传入那些类 Pointcuts定义各种AOP特征将怎样应用于你应用中的类

在动作中的AOP

  例 .使用拦截器

  JBoss 带了一个AOP框架 这个框架和JBoss应用服务器紧密地结合 但是你也能够在你的应用中 单独的运行它 直到你看了动作中看到它 你才会完全的理解这个概念 所以让我们用一个来自于JBoss AOP的例子 来说明这个模块所有的部分是如何一起工作的 在这章余下的部分 我们将建立一个例子来跟踪使用AOP的框架

  定义一个拦截器

  为了实现我们对于框架的跟踪 我们必须作的第一件事是定义一个拦截器 它将作实际的工作 在JBOSS AOP中 所有的拦截器必须实现 jboss aop Interceptor 接口

public interface Interceptorpublic String getName();public InvocationResponse invoke(Invocation invocation) throws Throwable;  在JBoss AOP中 被拦截的所有域 构造器和方法被转成一般的invoke调用 方法的参数被填入一个Invocation对象 并且方法的返回值 域的存取或者构造器被填入一个InvocationResponse对象 这个Invocation对象也驱动这个拦截链 为了清楚地说明这个 让我们看一下 在这个例子中 所有的对象是如何配合到一起的

import jboss aop *;import java lang reflect *;

public class TracingInterceptor implements Interceptorpublic String getName() return TracingInterceptor; public InvocationResponse invoke(Invocation invocation) throws ThrowableString message = null;

if (invocation getType() == InvocationType METHOD)Method method = MethodInvocation getMethod(invocation);message = method: + method getName();else if (invocation getType() == InvocationType CONSTRUCTOR)Constructor c = ConstructorInvocation getConstructor(invocation);message = constructor: + c toString();else// Do nothing for fields Just too verbose //对于域什么也不做 太繁琐 return invocation invokeNext();

System out println(Entering + message);

// Continue on Invoke the real method or constructor

// 继续 调用真正的方法或者构造器InvocationResponse rsp = invocation invokeNext();System out println(Leaving + message);return rsp;  上面的拦截器将拦截所有的对一个域 构造器或方法的调用 如果调用的类型是一个方法或者构造器 一个带有方法或构造器签名的消息将输出到控制平台

  绑定拦截器

  好了 这样我们就定义了拦截器 但是怎么绑定这个拦截器到实际的类?为了做这个 我们需要定义一个pointcut 对于JBoss AOP pointcuts 是在一个XML文件中定义的 让我们看一下这看起来象什么

<?xml version= encoding= UTF ><aop><interceptor pointcut class= POJO ><interceptors><interceptor class= TracingInterceptor /></interceptors></interceptor pointcut></aop>  上面的pointcut绑定TracingInterceptor到一个叫做POJO的类 这看起来有一点麻烦 我们不得不为每一个想跟踪的类创建一个pointcut吗?幸运的是 interceptor pointcut的类属性可以用任何的正规表达式 所以如果你想跟踪由JVM载入的类 类表达式将变为 * 如果你仅仅想跟踪一个特定的包 那么表达式将是 acme mypackge *

  当单独运行JBoss AOP时 任何符合 META INF/jboss aop xml模式的XML文件将被JBoss AOP 运行时间所载入 如果相关的路径被包含在任何JAR或你的CLASSPATH的目录中 那个特定的XML文件将在启动时 由JBoss AOP 运行时间所载入

  运行这个例子

  我们将用上面定义的pointcut去运行例子 POJO类看起来如下

public class POJOpublic POJO() public void helloWorld() System out println(Hello World!); public static void main(String[] args)POJO pojo = new POJO();pojo helloWorld();  TracingInterceptor将拦截对main() POJO()和helloWorld()的调用 输出看起来如下:

Entering method: mainEntering constructor: public POJO()Leaving constructor: public POJO()Entering method: helloWorldHello World!Leaving method: helloWorldLeaving method: main  你能够在这里下载JBoss AOP和离子代码 编译和执行:

$ cd oreilly aop/example $ export CLASSPATH= ;jboss mon jar;jboss aop jar;javassist jar$ javac * java$ java Djava system class loader= jboss aop standalone SystemClassLoader POJO  JBoss AOP 对绑定的拦截器做字节码操作 因为没有编译步骤 AOP运行时间必须有ClassLoader的总控 如果你正运行在非JBoss应用服务器 你必须用JBoss制定的一个类载入器覆蓋系统的类载入器

  TraceingInterceptor不跟踪域访问 因为它有一点繁琐 对于开发者 实现get()和set()方法去封装域访问是一个一般的实践 如果TracingInterceptor能够过滤出 并且不跟踪这些方法 那是非常好的 这个例子显示你能够用JBoss AOP 元数据去实现基于任一方法的过滤 一般 元数据用于更复杂的事情 如定义事务属性 每个方法的安全角色或者持久性映射 但是这个例子应该足够说明元数据能够怎样用在 AOP使能的应用中 定义类的元数据

  为了增加这个过滤功能 我们将提供一个标志 你能够用这个标著去关闭跟踪 我们将回到我们的AOP的XML文件去定义标签 那将删除对get()和set()方法的跟踪 事实上 对于main()函数的跟踪毫无意义 所以我们也过滤出它

<?xml version= encoding= UTF ><aop><class metadata group= tracing class= POJO ><method name= (get *)|(set *) ><filter>true</filter></method><method name= main ><filter>true</filter></method></class metadata></aop>  上面的XML定义了一组叫做tracing的属性 这个过滤属性将绑定到每一个以get或者set开始的方法上 正则表达式格式用JDK 定义的表达式 元数据通过Invocation对象 在TracingInterceptor内访问

  访问Metadata

  为了用元数据 它在运行时间必须是可达的 类的元数据是通过Invocation对象可达的 为了在我们的例子使用它 TracingInterceptor必须要修改一点点

public class TracingInterceptor implements Interceptorpublic String getName() return TracingInterceptor; public InvocationResponse invoke(Invocation invocation) throws ThrowableString filter=(String)invocation getMetaData(tracing filter);if (filter != null && filter equals(true))return invocation invokeNext();

String message = null;

if (invocation getType() == InvocationType METHOD)Method method = MethodInvocation getMethod(invocation);message = method: + method getName();else if (invocation getType() == InvocationType CONSTRUCTOR)Constructor c = ConstructorInvocation getConstructor(invocation);message = constructor: + c toString();else// Do nothing for fields Just too verbose return invocation invokeNext();

System out println(Entering + message);

// Continue on Invoke the real method or constructor InvocationResponse rsp = invocation invokeNext();System out println(Leaving + message);return rsp;  运行例子 : POJO类将扩展一点 增加get()和set()方法

public class POJOpublic POJO() public void helloWorld() System out println(Hello World!);

private int counter = ;

public int getCounter() return counter; public void setCounter(int val) counter = val; public static void main(String[] args)POJO pojo = new POJO();pojo helloWorld();pojo setCounter( );System out println(counter is: + pojo getCounter());  TracingInterceptor将拦截对main() POJO()和helloWorld()调用 输出应该看起来如下

Entering constructor: public POJO()Leaving constructor: public POJO()Entering method: helloWorldHello World!Leaving method: helloWorld  你能够在这里下载JBoss AOP和离子代码 编译和执行: $ cd oreilly aop/example

$ export CLASSPATH= ;jboss mon jar;jboss aop jar;javassist jar$ javac * java$ java Djava system class loader= jboss aop standalone SystemClassLoader POJO  例子 使用导言

  如果我们能够为特定的实例关闭和打开 那将很酷 JBoss AOP有一个API 他绑定元数据到一个对象实例 但是让我们伪装一个实际的跟踪API是一个更好的方案 在这例子中 我们通过用一个导言 将改变POJO类的本身的定义 我们将强制POJO类去实现一个跟踪借口和提供混合类 这个混合类处理新的跟踪API 这将是跟踪借口:

public interface Tracingpublic void enableTracing();public void disableTracing();  定义一个混合的类

  Tracing接口将在混合类中实现 当一个POJO是实例时 一个混合对象混合类将绑定到POJO类 下面是实现: import jboss aop Advised;

public class TracingMixin implements TracingAdvised advised;

Public TracingMixin(Object obj)this advised = (Advised)obj;

public void enableTracing()advised _getInstanceAdvisor() getMetaData() addMetaData( tracing filter true);

public void disableTracing()advised _getInstanceAdvisor() getMetaData() addMetaData( tracing filter false);   enableTracing()方法绑定filter属性到对象实例 在disableTracing()方法作同样的事 但是制定filter属性为false 这两个方法是元数据能够怎么样用于超过一个类级别 元数据也能够实例级的应用 元数据应用在实例级别

  绑定一个导言

  好了 所以我们定义跟踪接口 并且实现这个混合类 下一步是应用导言到POJO类 像拦截器 我们必须在XML中定义一个ponitcut 让我们看一下这项什么

<?xml version= encoding= UTF ><aop><introduction pointcut class= POJO ><mixin><interfaces>Tracing</interfaces><class>TracingMixin</class><construction>new TracingMixin(this)</construction></mixin></introduction pointcut></aop>  上面的pointcuts将强制POJO类实现Tracing接口 现在 当一个POJO实例被初始化 一个TracingMixin也将被实例化 TracingMixin被初始化的途径被定义在标签中 你能够把想要的任一行Java代码放入在标签中

运行例子

  POJO类为了显示TracingAPI怎么被访问 它已经被扩展了一点 TracingInterceptor仍然和例子 一样

public class POJOpublic POJO() public void helloWorld() System out println(Hello World!);

public static void main(String[] args)POJO pojo = new POJO();Tracing trace = (Tracing)this;pojo helloWorld();

System out println( Turn off tracing );

trace disableTracing();pojo helloWorld();

System out println( Turn on tracing );trace enableTracing();pojo helloWorld();  注意我们转换POJO到Tracing接口 输出应该看起来这样: Entering constructor: POJO()

Leaving constructor: POJO()Entering method: helloWorldHello World!Leaving method: helloWorldTurn off tracing Entering method: disableTracingLeaving method: disableTracingHello World!Turn on tracing Entering method: helloWorldHello World!Leaving method: helloWorld  注意被增加到TracingInterceptor 中的interceptor pointcut也应用到那些通过Tracing 导言导入的方法中 为了编译和运行这个例子 $ cd oreilly aop/example

cha138/Article/program/Java/ky/201311/29217

相关参考

知识大全 .NET面向上下文、AOP架构模式

.NET面向上下文、AOP架构模式  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  上下文Cont

知识大全 试简单概括面向对象接口编程

  本文不是为了论证面向对象方法论那需要深厚的理论知识和丰富的实践经验本人两方面都差得很远  这里只是试图给出一个对面象接口的深入浅出的简单原则  就象数学很难数论很难但是九九表不难各位数字之和被整除

知识大全 Java编程—Spring AOP本质(6)

Java编程—SpringAOP本质(6)  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 

知识大全 反向控制和面向切面编程在Spring的应用

反向控制和面向切面编程在Spring的应用  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  摘要针

知识大全 Java中消除实现继承和面向接口的编程

Java中消除实现继承和面向接口的编程  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  在匆忙之际

知识大全 Delphi面向对象的编程方法(五)

Delphi面向对象的编程方法(五)  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  过程和函数的

知识大全 PHP面向对象编程快速入门

PHP面向对象编程快速入门  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  面向对象编程(OOP)

知识大全 面向Java开发人员的Scala指南: 面向对象的函数编程

面向Java开发人员的Scala指南:面向对象的函数编程  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下

知识大全 PHP中实现面向对象编程的研究

PHP中实现面向对象编程的研究  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  面向对象编程的概念

知识大全 Javascript面向对象编程

Javascript面向对象编程  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  Javascri