ImageVerifierCode 换一换
格式:DOCX , 页数:24 ,大小:23.57KB ,
资源ID:12642176      下载积分:10 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/12642176.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(spring aop 详解.docx)为本站会员(b****2)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

spring aop 详解.docx

1、spring aop 详解引用地址: 谨供参考感谢老许老师spring AOP(1) 2spring AOP(2) 9spring AOP(3) 16spring AOP(1) 分类: spring系列 2008-06-15 23:44 1082人阅读 评论(19) 收藏 举报 spring里面有个概念叫aop(面向切面编程),很好很强大又很让人费解,很多开发人员会用并且天天挂在嘴边但是不理解其核心原理,今天周末有空,我想用一个小系列的文章给大家把aop分析清楚。要理解aop,首先要掌握java中的代理模式。在日常生活中,会遇到各种各样的中介机构,比如猎头公司,律师事务所,婚姻介绍所,房产公司

2、等。在这些单位工作的人员均可称为代理人。代理人的共同特征是可以代替委托人去和第三方通信。譬如:律师代替委托人打官司,猎头代替委托人物色人才,红娘代替委托人寻找对象,房产代理人代替委托人出租房屋。代理人可以在第三方和委托人之间转发或过滤消息,但是不能取代委托人的任务。譬如你要找女朋友,委托你一要好的哥们去帮你物色,结果被他给物色了。这就不叫代理。代理模式的作用是:为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个客户不想或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。代理模式一般涉及到的角色有:抽象角色:声明真实对象和代理对象的共同接口;代理角色:代

3、理对象角色内部含有对真实对象的引用,从而可以操作真实对象,同时代理对象提供与真实对象相同的接口以便在任何时刻都能代替真实对象。同时,代理对象可以在执行真实对象操作时,附加其他的操作,相当于对真实对象进行封装。真实角色:代理角色所代表的真实对象,是我们最终要引用的对象。 我们来看个例子:package com.wepull.aop.staticProxy;/* * author leno *抽象角色 */public interface IHello String greeting(String who);package com.wepull.aop.staticProxy;/* * autho

4、r leno *真实角色 */public class HelloImpl implements IHello public String greeting(String who) System.out.println(greeting method is invoked.); return hello,+who; 试想一下,如果这时候我们要对问候的业务逻辑方法进行日志记录。我们当然可以这样做:package com.wepull.aop.staticProxy;/* * author leno *真实角色 */public class HelloImpl implements IHello

5、private Logger logger = Logger.getLogger(this.getClass().getName(); public void log(String message) logger.log(Level.INFO, message); public String greeting(String who) log( starting.); System.out.println(greeting method is invoked.); log(stopping.); return hello,+who; 可问题来了,项目经理发话,不容许修改现存的类的实现。怎么办?这

6、时候我们就要就想到代理模式了。我们再加一个代理类:静态代理类:package com.wepull.aop.staticProxy;import java.util.logging.Level;import java.util.logging.Logger;public class HelloLoggerProxy implements IHello private Logger logger = Logger.getLogger(this.getClass().getName(); private IHello helloImpl; public HelloLoggerProxy(IHell

7、o helloImpl) super(); this.helloImpl = helloImpl; public String greeting(String who) log( starting.); String hello = helloImpl.greeting(who); log(stopping.); return hello; public void log(String message) logger.log(Level.INFO, message); 客户端测试代码:package com.wepull.aop.staticProxy;public class TestSta

8、ticProxy public static void main(String args) IHello hello = new HelloLoggerProxy(new HelloImpl(); hello.greeting(leno); 由以上代码可以看出,客户实际需要调用的是HelloImpl类的greeting()方法,现在用HelloLoggerProxy来代理HelloImpl类,同样达到目的,同时还在方法调用的前后都做了日志记录。这就是静态代理。 但是,如果要按照上述的方法使用代理模式,那么真实角色必须是事先已经存在的,并将其作为代理对象的内部属性。但是实际使用时,一个真实色必须

9、对应角一个代理角色,如果大量使用会导致类的急剧膨胀;而且,如果项目中要做日志的类有100个,每个类里面有100个方法。重复代码就太可怕了。有人说,不怕,我就一愚公。好,有天项目经理突然要求修改做日志的方式,你再看看这些方法,估计撞墙的心都有了。那怎么办?我们就改用动态代理。JDK1.3以后提供了动态代理的支持,程序员通过实现java.lang.reflect.InvocationHandler接口提供一个执行处理器,然后通过java.lang.reflect.Proxy得到一个代理对象,通过这个代理对象来执行商业方法,在商业方法被调用的同时,执行处理器会被自动调用。 动态代理类:package

10、 com.wepull.aop.dynamicProxy;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;import java.util.logging.Level;import java.util.logging.Logger;public class DynamicLoggerProxy implements InvocationHandler private Logger logger = Logger.getLogger(

11、this.getClass().getName(); private Object delegate; SuppressWarnings(unchecked) public Object bind(Object delegate) this.delegate = delegate; Class cls = delegate.getClass(); return Proxy.newProxyInstance(cls.getClassLoader(), cls.getInterfaces(), this); public Object invoke(Object o, Method method,

12、 Object args) throws Throwable log( starting.); Object obj = method.invoke(delegate, args); log(stopping.); return null; public void log(String message) logger.log(Level.INFO, message); 客户端测试代码:package com.wepull.aop.dynamicProxy;public class TestDynamicProxy public static void main(String args) IHe

13、llo hello = (IHello) new DynamicLoggerProxy().bind(new HelloImpl(); hello.greeting(leno); 大家看到,一个动态代理类就代替了无数个静态代理类。一劳永逸。这里涉及到一些java反射的知识,我会在以后单独讲述。java的动态代理非常实用和强大,可它有一个前提,需要我们的处理业务逻辑的类必须至少实现一个接口,虽然面向接口编程是需要提倡的,但如果我们有些现存的类就是没有实现接口,那如何代理呢?这就需要CGLIB的帮助了。继续改进我们的代码:没有实现任何接口的类:package com.wepull.aop.cgli

14、bProxy;public class Hello public void greeting(String who) System.out.println(hello,+who); CGLIB代理类:package com.wepull.aop.cglibProxy;import java.lang.reflect.Method;import java.util.logging.Level;import java.util.logging.Logger;import net.sf.cglib.proxy.Enhancer;import net.sf.cglib.proxy.MethodInte

15、rceptor;import net.sf.cglib.proxy.MethodProxy;public class CGLIBLoggerProxy implements MethodInterceptor private final Logger logger = Logger.getLogger(this.getClass().getName(); public Object bind(Object delegate) Enhancer enhancer = new Enhancer(); enhancer.setCallback(this); enhancer.setSuperclas

16、s(delegate.getClass(); return enhancer.create(); public Object intercept(Object o, Method method, Object args, MethodProxy proxy) throws Throwable log( starting.); proxy.invokeSuper(o, args); log(stopping.); return null; public void log(String message) logger.log(Level.INFO,message); 客户端测试代码:package

17、 com.wepull.aop.cglibProxy;public class TestCGLIBProxy public static void main(String args) Hello hello = (Hello) new CGLIBLoggerProxy().bind(new Hello(); hello.greeting(leno); 好了,有了动态代理和CGLIB,那我们就可以给任何实际的类提供代理了。从而可以在我们的代理类中加入一些与业务逻辑无关的系统级的功能服务,如:日志记录,事务处理,安全管理等。而且不会影响到我们现有的系统。看起来似乎很完美了。但是且慢,如果我们的应用

18、中有些需要这些系统级的功能服务,而有些又不需要呢?如果把代码写死了显然达不到我们的要求。怎么办?这时候就要用到一个非常重要的思想:用配置代替编码spring AOP(2) 分类: spring系列 2008-10-07 22:26 590人阅读 评论(2) 收藏 举报 前面写过一篇关于Spring AOP方面的文章,探讨了Spring AOP底层实现的一些细节知识,这里面涉及到了JAVA反射机制,代理模式以及CGLIB库的使用。也就是说,Spring AOP底层实现就是靠动态代理(针对有接口的类)和CGLIB(针对没有实现接口的一般类),那么,有了这些知识,再辅佐对核心配置XML文件解析的能力

19、,其实就可以实现一个简易的基于IOC和AOP的小框架,大家可以自己尝试着写一下。下面呢我们就由浅入深地来看看在Spring中AOP是怎么实现的。 最简单的AOP实现只需要涉及3个概念:目标(Target),通知(Advice)和代理(Proxy)。目标呢,当然就是真实的需要被代理的对象,一般它会实现至少一个接口。通知呢,就是当目标的方法调用时需要调用的代码,也叫拦截器。而代理,毫无疑问就是加入了通知的目标了,它可以作为目标的替身出现。为了说明这三者的关系,我们来看一个网上有趣的小例子:一间书店开始打折促销,规则是每一名顾客只能买一本书,并且当顾客来到书店时,要说喜欢您来。顾客走的时候,还要说喜

20、欢您再来!(麦当劳啊_) 顾客如果买到这本书,要抛出异常,告知他没有存货!呵呵,好啦,洪哥,我们动手吧!package com.wepull.spring.book;public class NoThisBookException extends Exception public NoThisBookException(String msg) super(msg); package com.wepull.spring.book;public interface BuyBook public void buyBook(String customer,String book) throws NoT

21、hisBookException;package com.wepull.spring.book;public class MyBuyBook implements BuyBook public void buyBook(String customer, String book) throws NoThisBookException if(book.equals() throw new NoThisBookException(对不起,没有+book+的存货了!); System.out.println(customer+,你好,你已经购买了一本+book+!); 看上面,我们做了一个异常类和一个

22、简单买书的接口,并且目标MyBuyBook也已经出现。OK,再来看看通知吧!Spring中主要有以下四种通知类型:(1)Around通知(2)Before通知(3)Throws通知(4)After Returning通知例子分别如下:package com.wepull.spring.book;import java.util.HashSet;import java.util.Set;import org.aopalliance.intercept.MethodInterceptor;import org.aopalliance.intercept.MethodInvocation;publi

23、c class MyAroundAdvice implements MethodInterceptor private Set customers=new HashSet(); /保存购过书的顾客信息 public Object invoke(MethodInvocation invocation) throws Throwable Object args= invocation.getArguments(); if(customers.contains(args0) System.out.println(对不起,一名顾客只能买一本打折书!); return null; customers.a

24、dd(args0); return invocation.proceed(); package com.wepull.spring.book;import java.lang.reflect.Method;import org.springframework.aop.MethodBeforeAdvice;public class MyBeforeAdvice implements MethodBeforeAdvice public void before(Method arg0, Object arg1, Object arg2) throws Throwable String custome

25、r=(String)arg10; /第2个参数组就是被通知的方法传入的参数,本例中即customer,book System.out.println(喜欢您来!+customer+!); /显示欢迎信息!,在buyBook方法前调用 package com.wepull.spring.book;import java.lang.reflect.Method;import org.springframework.aop.ThrowsAdvice;public class MyThrowsAdvice implements ThrowsAdvice public void afterThrowin

26、g(Method method, Object args, Object target, NoThisBookException e) /可以定义多个方法,只要传入的参数是不同异常 System.out.println(对不起+args0+,没货了。通知仓库,赶紧加书!); package com.wepull.spring.book;import java.lang.reflect.Method;import org.springframework.aop.AfterReturningAdvice;public class MyAfterAdvice implements AfterRetu

27、rningAdvice public void afterReturning(Object arg0, Method arg1, Object arg2, Object arg3) throws Throwable String customer=(String)arg20; /同前置通知一样,参数组3为传入参数,具体见spring doc System.out.println(喜欢您再来!+customer+!); /显示欢送信息! 现在目标类有了,通知类也写好了,写了就要配,这是框架的基本使用原则。呵呵,下面就来看看核心配置文件src/applicationContext.xml: bean id=buyBookTarget class=

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1