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

Spring2.5注解实现AOP(转)

    博客分类:
  • java
阅读更多

这个例子非常的简单,下面是实体类

Java代码
  1. package  test;  
  2.   
  3. /**  
  4.  *   
  5.  * @author neu_20063500  
  6.  *   
  7.  */   
  8. public   class  HelloWorld {  
  9.   
  10.  public   void  sayHello(String helloworld) {  
  11.   System.out.println(helloworld);  
  12.   throw   new  RuntimeException();  
  13.                 //这个异常是拿来测试,可有可无   
  14.  }  
  15. }  
package test;

/**
 * 
 * @author neu_20063500
 * 
 */
public class HelloWorld {

 public void sayHello(String helloworld) {
  System.out.println(helloworld);
  throw new RuntimeException();
                //这个异常是拿来测试,可有可无
 }
}

 

想使用AOP去处理这个sayHello方法

那么我们定义切面

 

Java代码
  1. package  test;     
  2.     
  3. import  org.aspectj.lang.ProceedingJoinPoint;     
  4. import  org.aspectj.lang.annotation.After;     
  5. import  org.aspectj.lang.annotation.AfterReturning;     
  6. import  org.aspectj.lang.annotation.AfterThrowing;     
  7. import  org.aspectj.lang.annotation.Around;     
  8. import  org.aspectj.lang.annotation.Aspect;     
  9. import  org.aspectj.lang.annotation.Before;     
  10. import  org.aspectj.lang.annotation.Pointcut;     
  11.     
  12. /**    
  13.  *     
  14.  * @author neu_20063500    
  15.  *     
  16.  */     
  17. @Aspect     
  18. public   class  AspectS {     
  19.     
  20.     // execution最常用,可以通过 & || !进行切入点表达式的连接      
  21.     // 可是是表达式,可以通过切入点标识重用表达式      
  22.     @Pointcut ( "execution(public void test.HelloWorld.sayHello(String))" )     
  23.     public   void  helloworld() {     
  24.     }     
  25.     
  26.     @Before ( "execution(public void test.HelloWorld.sayHello(String))" )     
  27.     public   void  beforeSayHello() {     
  28.         System.out.println("before sayHello" );     
  29.     }     
  30.     
  31.     @After ( "helloworld()" )     
  32.     public   void  afterSayHello() {     
  33.         System.out.println("after sayHello" );     
  34.     }     
  35.     
  36.     @AfterThrowing ( "test.AspectS.helloworld()" )     
  37.     public   void  exceptionSayHello() {     
  38.         System.out.println("throw runtime exception" );     
  39.     }     
  40.     
  41.     @AfterReturning ( "test.AspectS.helloworld()" )     
  42.     public   void  returnSayHello() {     
  43.         System.out.println("method has returned" );     
  44.     }     
  45.     
  46.     @Around ( "test.AspectS.helloworld()" )     
  47.     public  Object aroundSayHello(ProceedingJoinPoint pjp) {     
  48.         Object obj = null ;     
  49.         try  {     
  50.             System.out.println("around start" );     
  51.             obj = pjp.proceed();     
  52.             System.out.println("around end" );     
  53.         } catch  (Throwable e) {     
  54.             e.printStackTrace();     
  55.         }     
  56.         return  obj;     
  57.     }     
  58.          
  59.     /*    
  60.    
  61. 任意公共方法的执行:    
  62.    
  63. execution(public * *(..))    
  64. 任何一个以“set”开始的方法的执行:    
  65.    
  66. execution(* set*(..))    
  67. AccountService 接口的任意方法的执行:    
  68.    
  69. execution(* com.xyz.service.AccountService.*(..))    
  70. 定义在service包里的任意方法的执行:    
  71.    
  72. execution(* com.xyz.service.*.*(..))    
  73. 定义在service包或者子包里的任意方法的执行:    
  74.    
  75. execution(* com.xyz.service..*.*(..))    
  76. 在service包里的任意连接点(在Spring AOP中只是方法执行) :    
  77.    
  78. within(com.xyz.service.*)    
  79. 在service包或者子包里的任意连接点(在Spring AOP中只是方法执行) :    
  80.    
  81. within(com.xyz.service..*)    
  82. 实现了 AccountService 接口的代理对象的任意连接点(在Spring AOP中只是方法执 行) :    
  83.    
  84. this(com.xyz.service.AccountService)    
  85. 'this'在binding form中用的更多:- 请常见以下讨论通知的章节中关于如何使得代理对象可以在通知 体内访问到的部分。    
  86. 实现 了 AccountService 接口的目标对象的任意连接点(在Spring AOP中只是方法执行) :    
  87.    
  88. target(com.xyz.service.AccountService)    
  89. 'target'在binding form中用的更多:- 请常见以下讨论通知的章节中关于如何使得目标对象可以在 通知体内访问到的部分。    
  90. 任何一个只接受 一个参数,且在运行时传入的参数实现了 Serializable 接口的连接点 (在Spring AOP中只是方法执行)     
  91.    
  92. args(java.io.Serializable)    
  93. 'args'在binding form中用的更多:- 请常见以下讨论通知的章节中关于如何使得方法参数可以在通知 体内访问到的部分。    
  94. 请注意在例子中给出 的切入点不同于 execution(* *(java.io.Serializable)): args只有在动态运行时候传入参数是可序列化的 (Serializable)才匹配,而execution 在传入参数的签名声明的类型实现了 Serializable 接口时候匹配。    
  95.    
  96. 有一 个 @Transactional 注解的目标对象中的任意连接点(在Spring AOP中只是方法执行)     
  97.    
  98. @target(org.springframework.transaction.annotation.Transactional)    
  99. '@target' 也可以在binding form中使用:请常见以下讨论通知的章节中关于如何使得 annotation对象可以在通知体内访问到的部分。    
  100. 任何一个目标对象声明的类型有一个 @Transactional 注解的连接点(在Spring AOP中只是方法执 行)    
  101.    
  102. @within(org.springframework.transaction.annotation.Transactional)    
  103. '@within'也可以在binding form中使用:- 请常见以下讨论通知的章节中关于如何使得 annotation对象可以在通知体内访问到的部分。    
  104. 任何一个执行的方法有一个 @Transactional annotation的连接点(在Spring AOP中只 是方法执行)     
  105.    
  106. @annotation(org.springframework.transaction.annotation.Transactional)    
  107. '@annotation' 也可以在binding form中使用:- 请常见以下讨论通知的章节中关于如何使得 annotation对象可以在通知体内访问到的部分。    
  108. 任何一个接受一个参数,并且传入的参数在运行时的类型实现了 @Classified annotation的连接点 (在Spring AOP中只是方法执行)     
  109.    
  110. @args(com.xyz.security.Classified)    
  111. '@args'也可以在binding form中使用:- 请常见以下讨论通知的章节中关于如何使得 annotation对象可以在通知体内访问到的部分。    
  112.    
  113. */     
  114. }    
package test;   
  
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.Around;   
import org.aspectj.lang.annotation.Aspect;   
import org.aspectj.lang.annotation.Before;   
import org.aspectj.lang.annotation.Pointcut;   
  
/**  
 *   
 * @author neu_20063500  
 *   
 */  
@Aspect  
public class AspectS {   
  
    // execution最常用,可以通过 & || !进行切入点表达式的连接   
    // 可是是表达式,可以通过切入点标识重用表达式   
    @Pointcut("execution(public void test.HelloWorld.sayHello(String))")   
    public void helloworld() {   
    }   
  
    @Before("execution(public void test.HelloWorld.sayHello(String))")   
    public void beforeSayHello() {   
        System.out.println("before sayHello");   
    }   
  
    @After("helloworld()")   
    public void afterSayHello() {   
        System.out.println("after sayHello");   
    }   
  
    @AfterThrowing("test.AspectS.helloworld()")   
    public void exceptionSayHello() {   
        System.out.println("throw runtime exception");   
    }   
  
    @AfterReturning("test.AspectS.helloworld()")   
    public void returnSayHello() {   
        System.out.println("method has returned");   
    }   
  
    @Around("test.AspectS.helloworld()")   
    public Object aroundSayHello(ProceedingJoinPoint pjp) {   
        Object obj = null;   
        try {   
            System.out.println("around start");   
            obj = pjp.proceed();   
            System.out.println("around end");   
        } catch (Throwable e) {   
            e.printStackTrace();   
        }   
        return obj;   
    }   
       
    /*  
 
任意公共方法的执行:  
 
execution(public * *(..))  
任何一个以“set”开始的方法的执行:  
 
execution(* set*(..))  
AccountService 接口的任意方法的执行:  
 
execution(* com.xyz.service.AccountService.*(..))  
定义在service包里的任意方法的执行:  
 
execution(* com.xyz.service.*.*(..))  
定义在service包或者子包里的任意方法的执行:  
 
execution(* com.xyz.service..*.*(..))  
在service包里的任意连接点(在Spring AOP中只是方法执行) :  
 
within(com.xyz.service.*)  
在service包或者子包里的任意连接点(在Spring AOP中只是方法执行) :  
 
within(com.xyz.service..*)  
实现了 AccountService 接口的代理对象的任意连接点(在Spring AOP中只是方法执行) :  
 
this(com.xyz.service.AccountService)  
'this'在binding form中用的更多:- 请常见以下讨论通知的章节中关于如何使得代理对象可以在通知体内访问到的部分。  
实现了 AccountService 接口的目标对象的任意连接点(在Spring AOP中只是方法执行) :  
 
target(com.xyz.service.AccountService)  
'target'在binding form中用的更多:- 请常见以下讨论通知的章节中关于如何使得目标对象可以在通知体内访问到的部分。  
任何一个只接受一个参数,且在运行时传入的参数实现了 Serializable 接口的连接点 (在Spring AOP中只是方法执行)   
 
args(java.io.Serializable)  
'args'在binding form中用的更多:- 请常见以下讨论通知的章节中关于如何使得方法参数可以在通知体内访问到的部分。  
请注意在例子中给出的切入点不同于 execution(* *(java.io.Serializable)): args只有在动态运行时候传入参数是可序列化的(Serializable)才匹配,而execution 在传入参数的签名声明的类型实现了 Serializable 接口时候匹配。  
 
有一个 @Transactional 注解的目标对象中的任意连接点(在Spring AOP中只是方法执行)   
 
@target(org.springframework.transaction.annotation.Transactional)  
'@target' 也可以在binding form中使用:请常见以下讨论通知的章节中关于如何使得annotation对象可以在通知体内访问到的部分。  
任何一个目标对象声明的类型有一个 @Transactional 注解的连接点(在Spring AOP中只是方法执行)  
 
@within(org.springframework.transaction.annotation.Transactional)  
'@within'也可以在binding form中使用:- 请常见以下讨论通知的章节中关于如何使得annotation对象可以在通知体内访问到的部分。  
任何一个执行的方法有一个 @Transactional annotation的连接点(在Spring AOP中只是方法执行)   
 
@annotation(org.springframework.transaction.annotation.Transactional)  
'@annotation' 也可以在binding form中使用:- 请常见以下讨论通知的章节中关于如何使得annotation对象可以在通知体内访问到的部分。  
任何一个接受一个参数,并且传入的参数在运行时的类型实现了 @Classified annotation的连接点(在Spring AOP中只是方法执行)   
 
@args(com.xyz.security.Classified)  
'@args'也可以在binding form中使用:- 请常见以下讨论通知的章节中关于如何使得annotation对象可以在通知体内访问到的部分。  
 
*/  
}  

 

然后定义配置文件,注意将切面对象和实体对象交给Spring管理:

 

Xml代码
  1. <? xml   version = "1.0"   encoding = "UTF-8" ?>      
  2. < beans   xmlns = "http://www.springframework.org/schema/beans"     
  3.     xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"   xmlns:context = "http://www.springframework.org/schema/context"     
  4.     xmlns:aop = "http://www.springframework.org/schema/aop"   xmlns:tx = "http://www.springframework.org/schema/tx"     
  5.     xsi:schemaLocation ="        
  6.     http://www.springframework.org/schema/beans         
  7.     http://www.springframework.org/schema/beans/spring-beans-2.5.xsd         
  8.     http://www.springframework.org/schema/context         
  9.     http://www.springframework.org/schema/context/spring-context-2.5.xsd        
  10.     http://www.springframework.org/schema/aop        
  11.     http://www.springframework.org/schema/aop/spring-aop-2.5.xsd        
  12.     http://www.springframework.org/schema/tx        
  13.     http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">      
  14.     < context:annotation-config   />      
  15.     < aop:aspectj-autoproxy   />      
  16.     < bean   id = "aspects"   class = "test.AspectS" > </ bean >      
  17.     < bean   id = "helloworld"   class = "test.HelloWorld" > </ bean >      
  18. </ beans >     
  19.    
<?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:context="http://www.springframework.org/schema/context"  
    xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"  
    xsi:schemaLocation="      
    http://www.springframework.org/schema/beans       
    http://www.springframework.org/schema/beans/spring-beans-2.5.xsd       
    http://www.springframework.org/schema/context       
    http://www.springframework.org/schema/context/spring-context-2.5.xsd      
    http://www.springframework.org/schema/aop      
    http://www.springframework.org/schema/aop/spring-aop-2.5.xsd      
    http://www.springframework.org/schema/tx      
    http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">   
    <context:annotation-config />   
    <aop:aspectj-autoproxy />   
    <bean id="aspects" class="test.AspectS"></bean>   
    <bean id="helloworld" class="test.HelloWorld"></bean>   
</beans>  
 

 

然后使用客户端调用:

 

Java代码
  1. package  test;     
  2.     
  3. import  org.springframework.context.ApplicationContext;     
  4. import  org.springframework.context.support.ClassPathXmlApplicationContext;     
  5.     
  6. public   class  Client {     
  7.     
  8.  public   static   void  main(String[] args) {     
  9.   ApplicationContext cx = new  ClassPathXmlApplicationContext(     
  10.     "applicationContext.xml" );     
  11.   HelloWorld bean = (HelloWorld)cx.getBean("helloworld" );     
  12.   bean.sayHello("hello world" );     
  13.  }     
  14. }   
package test;   
  
import org.springframework.context.ApplicationContext;   
import org.springframework.context.support.ClassPathXmlApplicationContext;   
  
public class Client {   
  
 public static void main(String[] args) {   
  ApplicationContext cx = new ClassPathXmlApplicationContext(   
    "applicationContext.xml");   
  HelloWorld bean = (HelloWorld)cx.getBean("helloworld");   
  bean.sayHello("hello world");   
 }   
} 

 

 

当sayHello没有抛出异常时,执行结果是:

 

Java代码
  1. before sayHello     
  2. around start     
  3. hello world     
  4. after sayHello     
  5. method has returned     
  6. around end    
before sayHello   
around start   
hello world   
after sayHello   
method has returned   
around end  

 

 

当sayHello执行抛出异常时候,执行结果是

 

Java代码
  1. around start     
  2. hello world     
  3. after sayHello     
  4. throw  runtime exception    
around start   
hello world   
after sayHello   
throw runtime exception  

 

 

给出一个比较典型和常用的切点:

Java代码
  1. package  test;     
  2.     
  3. import  org.aspectj.lang.annotation.Aspect;     
  4. import  org.aspectj.lang.annotation.Pointcut;     
  5.     
  6. @Aspect     
  7. public   class  SystemArchitecture {     
  8.     
  9.     /**    
  10.      * A join point is in the web layer if the method is defined in a type in    
  11.      * the com.xyz.someapp.web package or any sub-package under that.    
  12.      */     
  13.     @Pointcut ( "within(com.xyz.someapp.web..*)" )     
  14.     public   void  inWebLayer() {     
  15.     }     
  16.     
  17.     /**    
  18.      * A join point is in the service layer if the method is defined in a type    
  19.      * in the com.xyz.someapp.service package or any sub-package under that.    
  20.      */     
  21.     @Pointcut ( "within(com.xyz.someapp.service..*)" )     
  22.     public   void  inServiceLayer() {     
  23.     }     
  24.     
  25.     /**    
  26.      * A join point is in the data access layer if the method is defined in a    
  27.      * type in the com.xyz.someapp.dao package or any sub-package under that.    
  28.      */     
  29.     @Pointcut ( "within(com.xyz.someapp.dao..*)" )     
  30.     public   void  inDataAccessLayer() {     
  31.     }     
  32.     
  33.     /**    
  34.      * A business service is the execution of any method defined on a service    
  35.      * interface. This definition assumes that interfaces are placed in the    
  36.      * "service" package, and that implementation types are in sub-packages.    
  37.      *     
  38.      * If you group service interfaces by functional area (for example, in    
  39.      * packages com.xyz.someapp.abc.service and com.xyz.def.service) then the    
  40.      * pointcut expression "execution(* com.xyz.someapp..service.*.*(..))" could    
  41.      * be used instead.    
  42.      */     
  43.     @Pointcut ( "execution(* com.xyz.someapp.service.*.*(..))" )     
  44.     public   void  businessService() {     
  45.     }     
  46.     
  47.     /**    
  48.      * A data access operation is the execution of any method defined on a dao    
  49.      * interface. This definition assumes that interfaces are placed in the    
  50.      * "dao" package, and that implementation types are in sub-packages.    
  51.      */     
  52.     @Pointcut ( "execution(* com.xyz.someapp.dao.*.*(..))" )     
  53.     public   void  dataAccessOperation() {     
  54.     }     
  55. }    
  56.   
  57.  
分享到:
评论

相关推荐

    Spring 2.5 AOP 例子

    Spring 2.5 AOP(面向切面编程)...综上所述,Spring 2.5 AOP例子展示了如何利用类扫描和XML配置实现面向切面编程。通过理解这些概念和实践,我们可以更高效地管理和维护我们的应用程序,使其更具可扩展性和可维护性。

    Spring2.5使用AOP需要的aspectJ

    AspectJ是一个成熟的AOP框架,Spring在其AOP实现中整合了AspectJ,提供了更强大的面向切面编程能力。本篇文章将详细探讨在Spring 2.5中使用AspectJ进行AOP开发所需的知识点。 首先,我们需要理解AOP的核心概念: 1....

    spring2.5注解驱动

    Spring 2.5还支持基于注解的AOP(面向切面编程)。`@Aspect`注解用于定义一个切面,`@Before`、`@After`、`@Around`、`@AfterReturning`和`@AfterThrowing`注解用于声明前置通知、后置通知、环绕通知、返回后通知和...

    Spring 2.5 基于注解驱动的Spring MVC

    Spring 2.5引入了一种基于注解的新方式来驱动Spring MVC框架,使得开发者能够更加简洁、直观地配置和管理控制器。这一变化显著提升了开发效率,减少了XML配置文件的复杂性,同时也使得代码更加模块化。 ### 1. 基于...

    精通Spring2.5pdf书籍proSpring2.5

    《精通Spring2.5》是一本深度探讨Spring框架的权威指南,主要针对Spring 2.5版本进行深入解析。Spring是Java企业级应用开发中最受欢迎的框架之一,它以其轻量级、模块化的设计,以及对IoC(Inversion of Control,...

    Spring2.5注解(标注)学习笔记

    ### Spring2.5注解(标注)学习笔记 在探讨Spring2.5中常见的四个注解之前,我们先简要回顾一下Spring框架的基本概念。Spring框架是一个轻量级的Java应用开发框架,它通过依赖注入(DI)和面向切面编程(AOP)等...

    Spring2.5-中文参考手册chm

    Spring2.5版本是该框架的一个重要里程碑,它在2008年发布,带来了许多新特性和改进,提升了开发者在构建应用程序时的灵活性和效率。 **依赖注入(DI)和控制反转(IoC)** Spring的核心特性之一是依赖注入(Dependency...

    Spring2.5 源代码

    Spring 2.5增加了对注解驱动的切面的支持,`@Aspect`、`@Before`、`@After`等注解使得AOP的使用更加直观。 4. **Bean工厂与ApplicationContext**: Spring 2.5中的Bean工厂是容器的基础,而ApplicationContext是更...

    struts2.0 spring2.5 hibernate3.2 注解最新框架

    Spring2.5是核心的依赖注入(DI)和面向切面编程(AOP)框架,它可以管理对象的生命周期和依赖关系。在Spring2.5中,注解如`@Autowired`、`@Service`、`@Repository`和`@Controller`引入了无XML配置的可能性。`@...

    spring 2.5框架图

    在Spring 2.5中,AOP支持更灵活的切入点表达式和更多类型的切面,如注解驱动的切面,这使得AOP更加易用和强大。 3. **Beans包**:这是Spring框架的基础,包含Bean的定义、实例化、配置和管理。在Spring 2.5中,对...

    spring_2.5_aop_lib.zip

    AspectJ是Spring AOP实现的基础,它提供了一种声明式的方式来定义切面,包括切入点、通知等,极大地简化了代码的组织结构。 接着是spring-beans.jar,这是Spring的核心组件,它负责Bean的创建、配置和管理。在AOP中...

    spring2.5的所有jar包

    9. **事务管理**:Spring 2.5的事务管理支持包括编程式和声明式两种方式,可以在不侵入业务代码的情况下实现事务的控制。 10. **国际化(i18n)支持**:Spring 2.5提供了更好的国际化支持,使得应用可以轻松地根据...

    spring2.5中文文档

    3. **AOP增强**:Spring的面向切面编程(AOP)在2.5版本中也有所改进,新增了`@Aspect`注解,允许开发者直接在类级别定义切面。此外,还支持了注解驱动的通知,如`@Before`、`@After`、`@Around`和`@AfterThrowing`。 ...

    传智播客spring2.5源代码

    3. **AOP(Aspect-Oriented Programming,面向切面编程)**:在Spring 2.5中,AOP支持更加丰富,包括注解式切面定义,如`@Before`、`@After`、`@Around`等,以及基于注解的切入点表达式,让切面的定义更加直观。...

    Spring2.5 中文文档 chm格式

    其次,Spring2.5在AOP(面向切面编程)方面也有所加强。AOP是Spring用于实现横切关注点,如日志、事务管理的关键特性。在2.5版本中,AOP支持更灵活的切入点表达式,可以基于方法参数类型和注解进行匹配,增强了切面...

    Spring2.5-中文参考手册chm.zip

    这个"Spring2.5-中文参考手册chm.zip"文件包含了关于Spring 2.5版本的详细中文指南,对于学习和理解Spring框架具有很高的价值。 Spring框架的核心特性包括依赖注入(Dependency Injection,DI)、面向切面编程...

    spring2.5基于注解例子程序

    综上所述,这个"spring2.5基于注解的例子程序"涵盖了Spring 2.5的核心特性,包括注解驱动的配置、自动扫描、基于注解的事务管理、AOP支持、MVC框架的使用,以及依赖注入等。通过学习和理解这个例子,开发者可以更好...

    spring 2.5中文帮助文档

    通过阅读《Spring2.5-中文参考手册.chm》这份文档,开发者可以深入了解Spring 2.5的各种特性和用法,解决实际开发中遇到的问题,提升开发效率。文档不仅包含详细的API参考,还包含丰富的示例和最佳实践指导,是学习...

    spring2.5中文文档(PDF)

    Spring框架是一个开源的Java平台,它主要简化了企业级应用的开发工作,通过依赖注入(Dependency Injection, DI)和面向切面编程(Aspect-Oriented Programming, AOP)等核心特性,实现了代码的解耦和模块化。...

Global site tag (gtag.js) - Google Analytics