再见西城 发表于 2015-1-18 11:38:39

JAVA编程:AOP编程进门--Java篇

你希望java的IDE整合。这个是没有必要的,重要的是你理解java有多深以及怎么组织你的代码,即使没有IDE,代码照样能够编译运行的。编程AspectOrientedProgramming(AOP),面向切面编程,是一个对照抢手的话题。AOP次要完成的目标是针对营业处置过程当中的切面举行提取,它所面临的是处置过程当中的某个步骤或阶段,以取得逻辑过程当中各部分之间低耦合性的断绝效果。好比我们最多见的就是日记纪录了,举个例子,我们如今供应一个服务查询先生信息的,可是我们但愿纪录有谁举行了这个查询。假如依照传统的OOP的完成的话,那我们完成了一个查询先生信息的服务接口(StudentInfoService)和实在现类(StudentInfoServiceImpl.java),同时为了要举行纪录的话,那我们在完成类(StudentInfoServiceImpl.java)中要增加实在现纪录的历程。如许的话,假设我们要完成的服务有多个呢?那就要在每一个完成的类都增加这些纪录历程。如许做的话就会有点烦琐,并且每一个完成类都与纪录服务日记的举动紧耦合,违背了面向对象的划定规矩。那末如何才干把纪录服务的举动与营业处置过程当中分别出来呢?看起来仿佛就是查询先生的服务本人在举行,可是面前日记纪录对这些举动举行纪录,可是查询先生的服务不晓得存在这些纪录历程,这就是我们要会商AOP的目标地点。AOP的编程,仿佛就是把我们在某个方面的功效提出来与一批对象举行断绝,如许与一批对象之间下降了耦合性,能够就某个功效举行编程。
我们间接从代码动手吧,要完成以上的方针,我们可使用一个静态代办署理类(Proxy),经由过程拦阻一个对象的举动并增加我们必要的功效来完成。Java中的java.lang.reflect.Proxy类和java.lang.reflect.InvocationHandler接口为我们完成静态代办署理类供应了一个计划,可是该计划针对的对象要完成某些接口;假如针对的目标是类的话,cglib为我们供应了别的一个完成计划。等下会申明二者的区分。
1、接口的完成计划:
1)起首编写我们的营业接口(StudentInfoService.java):
publicinterfaceStudentInfoService{
voidfindInfo(StringstudentName);
}
及实在现类(StudentInfoServiceImpl.java):
publicclassStudentInfoServiceImplimplementsStudentInfoService{
publicvoidfindInfo(Stringname){
System.out.println("你今朝输出的名字是:"+name);
}
}
2)如今我们必要一个日记功效,在findInfo举动之前实行并纪录其举动,那末我们就起首要拦阻该举动。在实践实行的过程当中用一个代办署理类来替我们完成。Java中为我们供应了完成静态代办署理类的计划:

1处置拦阻目标的类(MyHandler.java)
importorg.apache.log4j.Logger;
importjava.lang.reflect.InvocationHandler;
importjava.lang.reflect.Proxy;
importjava.lang.reflect.Method;

publicclassMyHandlerimplementsInvocationHandler{
privateObjectproxyObj;
privatestaticLoggerlog=Logger.getLogger(MyHandler.class);

publicObjectbind(Objectobj){
this.proxyObj=obj;
returnProxy.newProxyInstance(obj.getClass().getClassLoader(),obj.getClass().getInterfaces(),this);
}

publicObjectinvoke(Objectproxy,Methodmethod,Object[]args)throwsThrowable{
Objectresult=null;
try{
//请在这里拔出代码,在办法前挪用
log.info("挪用log日记办法"+method.getName());
result=method.invoke(proxyObj,args);//原办法
//请在这里拔出代码,办法后挪用
}catch(Exceptione){
e.printStackTrace();
}
returnresult;
}
}
2我们完成一个工场,为了便利我们利用该拦阻类(AOPFactory.java):
publicclassAOPFactory{
privatestaticObjectgetClassInstance(StringclzName){
Objectobj=null;
try{
Classcls=Class.forName(clzName);
obj=(Object)cls.newInstance();
}catch(ClassNotFoundExceptioncnfe){
System.out.println("ClassNotFoundException:"+cnfe.getMessage());
}catch(Exceptione){
e.printStackTrace();
}
returnobj;
}

publicstaticObjectgetAOPProxyedObject(StringclzName){
Objectproxy=null;
MyHandlerhandler=newMyHandler();
Objectobj=getClassInstance(clzName);
if(obj!=null){
proxy=handler.bind(obj);
}else{
System.out.println("Cantgettheproxyobj");
//throw
}
returnproxy;
}
}

3)基础的拦阻与其工场我们都完成了,如今测试(ClientTest.java):
publicclassClientTest{
publicstaticvoidmain(String[]args){
StudentInfoServicestudentInfo=(StudentInfoService)AOPFactory.getAOPProxyedObject("StudentInfoServiceImpl");
studentInfo.findInfo("阿飞");
}
}
输入了局(看你的log4j设置):
挪用log日记办法findInfo
你今朝输出的名字是:阿飞
如许我们必要的效果就出来了,营业处置本人在举行,可是我们完成了日记功效,而营业处置(StudentInfoService)基本不晓得存在该举动的。可是Java中供应的静态代办署理类的完成是针对完成了某些接口的类,假如没有完成接口的话,不克不及创立代办署理类,看以上部分:
returnProxy.newProxyInstance(obj.getClass().getClassLoader(),obj.getClass().getInterfaces(),this);
看到了没有?obj.getClass().getInterfaces()请求完成了某些接口。以下供应哪些没有完成接口的完成计划:

2、子类的完成计划。
起首,请上彀下CGLib的包,http://sourceforge.net/project/showfiles.php?group_id=56933。设置好classpath路径,CGLib与java尺度库供应的完成计划分歧,cglib次要是基于完成类(如StudentInfoServiceImpl.java)扩大一个子类来完成。与DynamicProxy中的Proxy和InvocationHandler绝对应,net.sf.cglib.proxy.Enhancer和MethodInterceptor在CGLib中卖力完成代办署理对象创立和办法截获处置,发生的是方针类的子类而不是经由过程接口来完成办法拦阻的,Enhancer次要是用于机关静态代办署理子类来完成拦阻,MethodInterceptor(扩大了Callback接口)次要用于完成aroundadvice(AOP中的观点):
1)我们的营业处置(StudentInfoServiceImpl.java):
publicclassStudentInfoServiceImpl{
publicvoidfindInfo(Stringname){
System.out.println("你今朝输出的名字是:"+name);
}
}
2)实施一个工具来处置日记功效(AOPInstrumenter.java):
importnet.sf.cglib.proxy.MethodInterceptor;
importnet.sf.cglib.proxy.Enhancer;
importnet.sf.cglib.proxy.MethodProxy;
importjava.lang.reflect.Method;
importorg.apache.log4j.Logger;

publicclassAOPInstrumenterimplementsMethodInterceptor{
privateLoggerlog=Logger.getLogger(AOPInstrumenter.class);
privateEnhancerenhancer=newEnhancer();

publicObjectgetInstrumentedClass(Classclz){
enhancer.setSuperclass(clz);
enhancer.setCallback(this);
returnenhancer.create();
}

publicObjectintercept(Objecto,Methodmethod,Object[]args,MethodProxyproxy)throwsThrowable{
log.info("挪用日记办法"+method.getName());
Objectresult=proxy.invokeSuper(o,args);
returnresult;
}

}
3)我们来测试一下(AOPTest.java):
publicclassAOPTest{
publicstaticvoidmain(String[]args){
AOPInstrumenterinstrumenter=newAOPInstrumenter();
StudentInfoServiceImplstudentInfo=(StudentInfoServiceImpl)instrumenter.getInstrumentedClass(StudentInfoServiceImpl.class);
studentInfo.findInfo("阿飞");
}
}
输入了局与以上不异。
CGLib中为完成以上目标,次要供应的类
1)Enhancer:setCallback(Callback),setSuperclass(Class),create()前往静态子类Object
2)MethodInterceptor必需完成的接口:intercept(Object,Method,Object[],MethodProxy)前往的是原办法挪用的了局。和Proxy道理一样。

3、以上的两个复杂完成AOP的计划都为你筹办好了,你能够本人编写测试一下,以下复杂先容一下AOP的基础观点:
1)aspect(切面):完成了cross-cutting功效,是针对切面的模块。最多见的是logging模块,如许,程序按功效被分为好几层,假如按传统的承继的话,贸易模子承继日记模块的话基本没有甚么意义,而经由过程创立一个logging切面就能够利用AOP来完成不异的功效了。
2)jointpoint(毗连点):毗连点是切面拔出使用程序的中央,该点能被办法挪用,并且也会被抛出不测。毗连点是使用程序供应给切面拔出的中央,能够增加新的办法。好比以上我们的切点能够以为是findInfo(String)办法。
3)advice(处置逻辑):advice是我们切面功效的完成,它关照程序新的举动。如在logging里,loggingadvice包含logging的完成代码,好比像写日记到一个文件中。advice在jointpoint处拔出到使用程序中。以上我们在MyHandler.java中完成了advice的功效
4)pointcut(切点):pointcut能够把持你把哪些advice使用于jointpoint上往,一般你利用pointcuts经由过程正则表达式来把分明的名字和形式举行婚配使用。决意了谁人jointpoint会取得关照。
5)introduction:同意增加新的办法和属性到类中。
6)target(方针类):是指那些将利用advice的类,通常为指自力的那些商务模子。好比以上的StudentInfoServiceImpl.

7)proxy(代办署理类):利用了proxy的形式。是指使用了advice的对象,看起来和target对象很类似。
8)weaving(拔出):是指使用aspects到一个target对象创立proxy对象的历程:complietime,classloadtime,runtime


我们AOP编程复杂进门就到此为止了,但愿这篇文章对列位读者有匡助,对这篇Blog有甚么倡议的话能够留言给我:gdanthrowwy@126.com



而学习JAVA我觉得最应该避免的就是:只学习,不思考,只记忆,不实践!

愤怒的大鸟 发表于 2015-1-21 11:50:02

Java 不同于一般的编译执行计算机语言和解释执行计算机语言。它首先将源代码编译成二进制字节码(bytecode),然后依赖各种不同平台上的虚拟机来解释执行字节码。从而实现了“一次编译、到处执行”的跨平台特性。

简单生活 发表于 2015-1-25 09:38:55

自从Sun推出Java以来,就力图使之无所不包,所以Java发展到现在,按应用来分主要分为三大块:J2SE,J2ME和J2EE,这也就是Sun ONE(Open Net Environment)体系。J2SE就是Java2的标准版,主要用于桌面应用软件的编程;J2ME主要应用于嵌入是系统开发,如手机和PDA的编程;J2EE是Java2的企业版,主要用于分布式的网络程序的开发,如电子商务网站和ERP系统。

兰色精灵 发表于 2015-1-30 21:55:19

象、泛型编程的特性,广泛应用于企业级Web应用开发和移动应用开发。

不帅 发表于 2015-1-31 14:32:17

Java 编程语言的风格十分接近C、C++语言。

乐观 发表于 2015-2-6 19:42:48

如果你学过HTML,那么事情要好办的多,如果没有,那你快去补一补HTML基础吧。其实JSP中的Java语法也不多,它更象一个脚本语言,有点象ASP。

冷月葬花魂 发表于 2015-2-13 18:47:52

是一种简化的C++语言 是一种安全的语言,具有阻绝计算机病毒传输的功能

再见西城 发表于 2015-2-28 05:27:57

是一种语言,用以产生「小应用程序(Applet(s))

海妖 发表于 2015-3-9 21:21:08

设计模式是高级程序员真正掌握面向对象核心思想的必修课。设计模式并不是一种具体"技术",它讲述的是思想,它不仅仅展示了接口或抽象类在实际案例中的灵活应用和智慧

活着的死人 发表于 2015-3-12 21:24:28

一般学编程语言都是从C语开始学的,我也不例外,但还是可能不学过程语言而直接学面向对象语言的,你是刚接触语言,还是从C开始学比较好,基础会很深点,如果你直接学习JAVA也能上手,一般大家在学语言的时候都记一些语言的关键词,常有的包和接口等。再去做逻辑代码的编写,以后的学习过程都是从逻辑代码编写中提升的,所以这方面都是经验积累的。你要开始学习就从

若天明 发表于 2015-3-20 02:46:57

是一种突破用户端机器环境和CPU

蒙在股里 发表于 2015-3-22 22:09:41

是一种使网页(Web Page)产生生动活泼画面的语言

透明 发表于 2015-3-23 17:34:25

设计模式是高级程序员真正掌握面向对象核心思想的必修课。设计模式并不是一种具体"技术",它讲述的是思想,它不仅仅展示了接口或抽象类在实际案例中的灵活应用和智慧

爱飞 发表于 2015-3-23 18:20:57

科学超级计算机、移动电话和互联网,同时拥有全球最大的开发者专业社群。

只想知道 发表于 2015-3-28 09:00:41

在全球云计算和移动互联网的产业环境下,Java更具备了显著优势和广阔前景。

山那边是海 发表于 2015-4-1 01:10:53

你现在最缺的是实际的工作经验,而不是书本上那些凭空想出来的程序。

小魔女 发表于 2015-4-14 21:03:02

所以现在应用最广泛又最好学的就是J2EE了。 J2EE又包括许多组件,如Jsp,Servlet,JavaBean,EJB,JDBC,JavaMail等。要学习起来可不是一两天的事。那么又该如何学习J2EE呢?当然Java语法得先看一看的,I/O包,Util包,Lang包你都熟悉了吗?然后再从JSP学起。

仓酷云 发表于 2015-4-23 15:13:17

你现在最缺的是实际的工作经验,而不是书本上那些凭空想出来的程序。

莫相离 发表于 2015-4-30 15:11:01

如果你学过HTML,那么事情要好办的多,如果没有,那你快去补一补HTML基础吧。其实JSP中的Java语法也不多,它更象一个脚本语言,有点象ASP。

变相怪杰 发表于 2015-5-3 15:37:01

Jive的资料在很多网站上都有,大家可以找来研究一下。相信你读完代码后,会有脱胎换骨的感觉。遗憾的是Jive从2.5以后就不再无条件的开放源代码,同时有licence限制。不过幸好还有中国一流的Java程序员关注它,外国人不开源了,中国人就不能开源吗?这里向大家推荐一个汉化的Jive版本—J道。Jive(J道版)是由中国Java界大名 鼎鼎的banq在Jive 2.1版本基础上改编而成, 全中文,增加了一些实用功能,如贴图,用户头像和用户资料查询等,而且有一个开发团队在不断升级。你可以访问banq的网站
页: [1]
查看完整版本: JAVA编程:AOP编程进门--Java篇