`
zhaohaolin
  • 浏览: 984819 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

开源框架spring详解-----AOP的深刻理解

 
阅读更多
    AOP是一种不同于OOP(面向对象编程)的编程模式,它不是OOP的替代,而是对OOP的一种有益补充。

AOP的理解

1、AOP的概述

AOP是一种不同于OOP(面向对象编程)的编程模式,它不是OOP的替代,而是对OOP的一种有益补充。

2、spring AOP的原理

3、spring AOP的实现

在spring2.5中,常用的AOP实现方式有两种。第一种是基于xml配置文件方式的实现,第二种是基于注解方式的实现。

接下来,以具体的是理智讲解这两种方式的使用。

Java代码

package  com.zxf.service;     
	
/**    
 * 业务逻辑接口    
 * @author z_xiaofei168    
 */     
public   interface  AccountService {     
	 public   void  save(String loginname, String password);     
}     
	
它的实现类     
	
package  com.zxf.service;     
import  com.zxf.dao.AccountDao;     
	
/**    
 * AccountService的实现类    
 * @author z_xiaofei168    
 */     
public   class  AccountServiceImpl  implements  AccountService {     
	 private   AccountDao accountDao;     
		 
	 public  AccountServiceImpl() {}     
		 
	 /** 带参数的构造方法 */     
	 public  AccountServiceImpl(AccountDao accountDao){     
		 this .accountDao = accountDao;     
	}     
		 
	 public   void  save(String loginname, String password) {     
		accountDao.save(loginname, password);     
		 throw   new  RuntimeException( "故意抛出一个异常。。。。" );     
	}     
		 
	 /** set方法 */     
	 public   void  setAccountDao(AccountDao accountDao) {     
		 this .accountDao = accountDao;     
	}     
}  
 

 

对于业务系统来说,AccountServiceImpl类就是目标实现类,它的业务方法,如save()方法的前后或代码会出现异常的地方都是AOP的连接点。

下面是日志服务类的代码:

Java代码

package  com.zxf.aspect;     

import  org.aspectj.lang.JoinPoint;     
import  org.aspectj.lang.ProceedingJoinPoint;     
 

/**    
 * 日志切面类    
 * @author z_xiaofei168    
 */     
public   class  LogAspect {     

     //任何通知方法都可以将第一个参数定义为 org.aspectj.lang.JoinPoint类型      
     public   void  before(JoinPoint call) {     
         //获取目标对象对应的类名     
        String className = call.getTarget().getClass().getName();     
         //获取目标对象上正在执行的方法名     
        String methodName = call.getSignature().getName();     
        System.out.println( "前置通知:"  + className +  "类的"  + methodName +  "方法开始了" );     
    }     

     public   void  afterReturn() {     
        System.out.println( "后置通知:方法正常结束了" );     
    }     

     public   void  after(){     
        System.out.println( "最终通知:不管方法有没有正常执行完成,一定会返回的" );     
    }     

     public   void  afterThrowing() {     
        System.out.println( "异常抛出后通知:方法执行时出异常了" );     
    }     
  
     //用来做环绕通知的方法可以第一个参数定义为org.aspectj.lang.ProceedingJoinPoint类型     
     public  Object doAround(ProceedingJoinPoint call)  throws  Throwable {     
        Object result =  null ;     
         this .before(call); //相当于前置通知     
         try  {     
            result = call.proceed();     
             this .afterReturn();  //相当于后置通知     
        }  catch  (Throwable e) {     
             this .afterThrowing();   //相当于异常抛出后通知     
             throw  e;     
        } finally {     
             this .after();   //相当于最终通知     
        }     
         return  result;     
    }     
}  
 

 

这个类属于业务服务类,如果用AOP的术语来说,它就是一个切面类,它定义了许多通知。Before()、afterReturn()、after()和afterThrowing()这些方法都是通知。

<1>.基于xml配置文件的AOP实现

这种方式在实现AOP时,有4个步骤。

Xml代码

<xml   version = "1.0"   encoding = "UTF-8" ?>     
<beans   xmlns = "http://www.springframework.org/schema/beans"     
         xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"     
         xmlns:aop = "http://www.springframework.org/schema/aop"     
         xsi:schemaLocation ="     
            http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd     
            http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd>     

     <bean   id = "accountDaoImpl"   class = "com.zxf.dao.AccountDaoImpl" />     

     <bean   id = "accountService"   class = "com.zxf.service.AccountServiceImpl">     
         <property   name = " accountDaoImpl "   ref = " accountDaoImpl " />     
     </bean>     

     <bean   id = "logAspectBean"   class = "com.zxf.aspect.LogAspect" />     
     <aop:config>     
         <aop:aspect   id = "logAspect"   ref = "logAspectBean">     
             <aop:pointcut   id = "allMethod"       
                 expression = "execution(* com.zxf.service.*.*(..))" />     
             <aop:before   method = "before"   pointcut-ref = "allMethod"   />     
             <aop:after-returning   method = "afterReturn"   pointcut-ref = "allMethod" />     
             <aop:after   method = "after"   pointcut-ref = "allMethod" />     
             <aop:after-throwing   method = "afterThrowing"   pointcut-ref = "allMethod" />     
         </aop:aspect>     
     </aop:config>     
</beans>
 

上述配置针对切入点应用了前置、后置、最终,以及抛出异常后通知。这样在测试执行AccountServiceImpl类的save()方法时,控制台会有如下结果输出。

前置通知:com.zxf.service.AccountServiceImpl类的save方法开始了。

针对MySQL的AccountDao实现中的save()方法。

后置通知:方法正常结束了。

最终通知:不管方法有没有正常执行完成,一定会返回的。

<2>基于注解的AOP的实现

首先创建一个用来作为切面的类LogAnnotationAspect,同时把这个类配置在spring的配置文件中。

在spring2.0以后引入了JDK5.0的注解Annotation的支持,提供了对AspectJ基于注解的切面的支持,从而 更进一步地简化AOP的配置。具体的步骤有两步。

Spring的配置文件是如下的配置:

Xml代码

<xml   version = "1.0"   encoding = "UTF-8" ?>     
    <beans   xmlns = "http://www.springframework.org/schema/beans"     
             xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"     
             xmlns:aop = "http://www.springframework.org/schema/aop"     
             xsi:schemaLocation ="     
                http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd     
                http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd>     
        
         <bean   id = "accountDao"   class = "com.zxf.dao.AccountDaoImpl" />     
         <bean   id = "accountService"   class = "com.zxf.service.AccountServiceImpl">     
             <property   name = "accountDao"   ref = "accountDao" />     
         </bean>     
             
         <bean   id = "logAspectBean"   class = "com.zxf.aspect.LogAnnotationAspect" />     
             
         <aop:aspectj-autoproxy />     
    </beans>
 

这是那个切面的类LogAnnotationAspect

Java代码

package  com.zxf.aspect;     
	
import  org.aspectj.lang.JoinPoint;     
import  org.aspectj.lang.ProceedingJoinPoint;     
import  org.aspectj.lang.annotation.After;     
import  org.aspectj.lang.annotation.AfterReturning;     
import  org.aspectj.lang.annotation.AfterThrowing;     
import  org.aspectj.lang.annotation.Aspect;     
import  org.aspectj.lang.annotation.Before;     
import  org.aspectj.lang.annotation.Pointcut;     
	
/**    
 * 日志切面类    
 */     
@Aspect    //定义切面类     
public   class  LogAnnotationAspect {     
	 @SuppressWarnings ( "unused" )     
	 //定义切入点     
	 @Pointcut ( "execution(* com.zxf.service.*.*(..))" )     
	 private   void  allMethod(){}     
		 
	 //针对指定的切入点表达式选择的切入点应用前置通知     
	 @Before ( "execution(* com. zxf.service.*.*(..))" )     
	 public   void  before(JoinPoint call) {     
			 
		String className = call.getTarget().getClass().getName();     
		String methodName = call.getSignature().getName();     
			 
		System.out.println( "【注解-前置通知】:"  + className +  "类的"       
				+ methodName +  "方法开始了" );     
	}     
	 //访问命名切入点来应用后置通知     
	 @AfterReturning ( "allMethod()" )     
	 public   void  afterReturn() {     
		System.out.println( "【注解-后置通知】:方法正常结束了" );     
	}     
		 
	 //应用最终通知     
	 @After ( "allMethod()" )     
	 public   void  after(){     
		System.out.println( "【注解-最终通知】:不管方法有没有正常执行完成,"       
				+  "一定会返回的" );     
	}     
		 
	 //应用异常抛出后通知     
	 @AfterThrowing ( "allMethod()" )     
	 public   void  afterThrowing() {     
		System.out.println( "【注解-异常抛出后通知】:方法执行时出异常了" );     
	}     
		 
	 //应用周围通知     
	 //@Around("allMethod()")     
	 public  Object doAround(ProceedingJoinPoint call)  throws  Throwable{     
		Object result =  null ;     
		 this .before(call); //相当于前置通知     
		 try  {     
			result = call.proceed();     
			 this .afterReturn();  //相当于后置通知     
		}  catch  (Throwable e) {     
			 this .afterThrowing();   //相当于异常抛出后通知     
			 throw  e;     
		} finally {     
			 this .after();   //相当于最终通知     
		}     
			 
		 return  result;     
	}     
}  
 

备注:输出结果和前面的一样。

【编辑推荐】

  1. Spring Hibernate简单讨论
  2. OSGi与Spring:设置Spring DM开发环境
  3. 使用Spring DM创建Hello World,以及OSGi服务
  4. Spring MVC总结:善用注解,生活更轻松
  5. 概括spring hibernate集成
分享到:
评论

相关推荐

    Spring5 框架 ---- AOP ---- 代码

    Spring5 框架 ---- AOP ---- 代码 Spring5 框架 ---- AOP ---- 代码 Spring5 框架 ---- AOP ---- 代码 Spring5 框架 ---- AOP ---- 代码 Spring5 框架 ---- AOP ---- 代码 Spring5 框架 ---- AOP ---- 代码 Spring5 ...

    spring-aop.jar各个版本

    spring-aop-1.1.1.jar spring-aop-1.2.6.jar spring-aop-1.2.9.jar spring-aop-2.0.2.jar spring-aop-2.0.6.jar spring-aop-2.0.7.jar spring-aop-2.0.8.jar spring-aop-2.0.jar spring-aop-2.5.1.jar spring-aop-...

    开发工具 spring-aop-4.3.6.RELEASE

    开发工具 spring-aop-4.3.6.RELEASE开发工具 spring-aop-4.3.6.RELEASE开发工具 spring-aop-4.3.6.RELEASE开发工具 spring-aop-4.3.6.RELEASE开发工具 spring-aop-4.3.6.RELEASE开发工具 spring-aop-4.3.6.RELEASE...

    spring-aop-5.2.0.RELEASE-API文档-中文版.zip

    赠送jar包:spring-aop-5.2.0.RELEASE.jar; 赠送原API文档:spring-aop-5.2.0.RELEASE-javadoc.jar; 赠送源代码:spring-aop-5.2.0.RELEASE-sources.jar; 赠送Maven依赖信息文件:spring-aop-5.2.0.RELEASE.pom;...

    spring-aop-5.0.8.RELEASE-API文档-中英对照版.zip

    赠送jar包:spring-aop-5.0.8.RELEASE.jar; 赠送原API文档:spring-aop-5.0.8.RELEASE-javadoc.jar; 赠送源代码:spring-aop-5.0.8.RELEASE-sources.jar; 赠送Maven依赖信息文件:spring-aop-5.0.8.RELEASE.pom;...

    spring-aop-5.3.10-API文档-中文版.zip

    赠送jar包:spring-aop-5.3.10.jar; 赠送原API文档:spring-aop-5.3.10-javadoc.jar; 赠送源代码:spring-aop-5.3.10-sources.jar; 赠送Maven依赖信息文件:spring-aop-5.3.10.pom; 包含翻译后的API文档:spring...

    spring-aop-jar

    aopalliance.jar、spring-aop-4.1.6.RELEASE.jar、spring-aspects-4.1.6.RELEASE.jar

    spring-aop-3.2.5.RELEASE.jar ;spring-aop-3.2.5.jar

    spring-aop-3.2.5.RELEASE.jar

    spring-aop-5.3.12-API文档-中英对照版.zip

    赠送jar包:spring-aop-5.3.12.jar; 赠送原API文档:spring-aop-5.3.12-javadoc.jar; 赠送源代码:spring-aop-5.3.12-sources.jar; 赠送Maven依赖信息文件:spring-aop-5.3.12.pom; 包含翻译后的API文档:spring...

    spring-aop-5.0.10.RELEASE-API文档-中文版.zip

    赠送jar包:spring-aop-5.0.10.RELEASE.jar; 赠送原API文档:spring-aop-5.0.10.RELEASE-javadoc.jar; 赠送源代码:spring-aop-5.0.10.RELEASE-sources.jar; 赠送Maven依赖信息文件:spring-aop-5.0.10.RELEASE....

    spring-aop-5.1.3.RELEASE-API文档-中英对照版.zip

    赠送jar包:spring-aop-5.1.3.RELEASE.jar; 赠送原API文档:spring-aop-5.1.3.RELEASE-javadoc.jar; 赠送源代码:spring-aop-5.1.3.RELEASE-sources.jar; 赠送Maven依赖信息文件:spring-aop-5.1.3.RELEASE.pom;...

    spring-aop-4.0.4.RELEASE

    spring-aop-4.0.4.RELEASE 的jar包,亲测可用。。。。

    spring-aop-5.1.0.RELEASE.jar

    spring-**core**-4.3.6.RELEASE.jar :包含spring框架基本的核心工具类,spring其他组件都要用到这个包里的类,其他组件的基本核心 spring-**beans**-4.3.6.RELEASE.jar:所有应用都要用到的jar包,它包含访问配置...

    spring-aop-5.0.4.RELEASE.jar

    spring-aop-5.0.4.RELEASE.jar。

    spring-aop-2.0.8.jar

    spring-aop-2.0.8.jar

    spring-aop-3.2.0.RELEASE.jar

    spring-aop-3.2.0.RELEASE.jar,一个Spring中AOP的jar包

    spring-aop-4.2.2.RELEASE-API文档-中文版.zip

    赠送jar包:spring-aop-4.2.2.RELEASE.jar; 赠送原API文档:spring-aop-4.2.2.RELEASE-javadoc.jar; 赠送源代码:spring-aop-4.2.2.RELEASE-sources.jar; 赠送Maven依赖信息文件:spring-aop-4.2.2.RELEASE.pom;...

    spring-aop-4.3.20.RELEASE-API文档-中英对照版.zip

    赠送jar包:spring-aop-4.3.20.RELEASE.jar 赠送原API文档:spring-aop-4.3.20.RELEASE-javadoc.jar 赠送源代码:spring-aop-4.3.20.RELEASE-sources.jar 包含翻译后的API文档:spring-aop-4.3.20.RELEASE-...

    spring-aop-5.3.15-API文档-中英对照版.zip

    赠送jar包:spring-aop-5.3.15.jar; 赠送原API文档:spring-aop-5.3.15-javadoc.jar; 赠送源代码:spring-aop-5.3.15-sources.jar; 赠送Maven依赖信息文件:spring-aop-5.3.15.pom; 包含翻译后的API文档:spring...

Global site tag (gtag.js) - Google Analytics