`
zoudingrong
  • 浏览: 51651 次
  • 来自: ...
社区版块
存档分类
最新评论

spring aop aspect

阅读更多
package test;  
 
/** 
*  
* @author neu_20063500 
*  
*/ 
public class HelloWorld {  
 
    public void sayHello(String helloworld) {  
        System.out.println(helloworld);  
        throw new RuntimeException();  
                //这个异常是拿来测试,可有可无  
    }  

package test;

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

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


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

那么我们定义切面

view plaincopy to clipboardprint?
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对象可以在通知体内访问到的部分。 

*/ 

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管理:

view plaincopy to clipboardprint?
<?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> 
<?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>

然后使用客户端调用:

view plaincopy to clipboardprint?
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");  
}  

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没有抛出异常时,执行结果是:

view plaincopy to clipboardprint?
before sayHello  
around start  
hello world  
after sayHello  
method has returned  
around end 
before sayHello
around start
hello world
after sayHello
method has returned
around end

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

view plaincopy to clipboardprint?
around start  
hello world  
after sayHello  
throw runtime exception 
around start
hello world
after sayHello
throw runtime exception

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

view plaincopy to clipboardprint?
package test;  
 
import org.aspectj.lang.annotation.Aspect;  
import org.aspectj.lang.annotation.Pointcut;  
 
@Aspect 
public class SystemArchitecture {  
 
    /** 
     * A join point is in the web layer if the method is defined in a type in 
     * the com.xyz.someapp.web package or any sub-package under that. 
     */ 
    @Pointcut("within(com.xyz.someapp.web..*)")  
    public void inWebLayer() {  
    }  
 
    /** 
     * A join point is in the service layer if the method is defined in a type 
     * in the com.xyz.someapp.service package or any sub-package under that. 
     */ 
    @Pointcut("within(com.xyz.someapp.service..*)")  
    public void inServiceLayer() {  
    }  
 
    /** 
     * A join point is in the data access layer if the method is defined in a 
     * type in the com.xyz.someapp.dao package or any sub-package under that. 
     */ 
    @Pointcut("within(com.xyz.someapp.dao..*)")  
    public void inDataAccessLayer() {  
    }  
 
    /** 
     * A business service is the execution of any method defined on a service 
     * interface. This definition assumes that interfaces are placed in the 
     * "service" package, and that implementation types are in sub-packages. 
     *  
     * If you group service interfaces by functional area (for example, in 
     * packages com.xyz.someapp.abc.service and com.xyz.def.service) then the 
     * pointcut expression "execution(* com.xyz.someapp..service.*.*(..))" could 
     * be used instead. 
     */ 
    @Pointcut("execution(* com.xyz.someapp.service.*.*(..))")  
    public void businessService() {  
    }  
 
    /** 
     * A data access operation is the execution of any method defined on a dao 
     * interface. This definition assumes that interfaces are placed in the 
     * "dao" package, and that implementation types are in sub-packages. 
     */ 
    @Pointcut("execution(* com.xyz.someapp.dao.*.*(..))")  
    public void dataAccessOperation() {  
    }  




本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/neusoftware_20063500/archive/2009/04/27/4129957.aspx
分享到:
评论

相关推荐

    整理的Spring AOP Aspect切入点语法

    整理的Spring AOP Aspect切入点语法,老师整理的,2018.08.01最新版

    spring aop jar 包

    Spring AOP(Aspect Oriented Programming,面向切面编程)是Spring框架的重要组成部分,它提供了一种在不修改源代码的情况下,对程序进行功能增强的技术。这个"spring aop jar 包"包含了实现这一功能所需的类和接口,...

    简单spring aop 例子

    Spring AOP(面向切面编程)是Spring框架的重要组成部分,它提供了一种模块化和声明式的方式来处理系统中的交叉关注点问题,如日志、事务管理、安全性等。本示例将简要介绍如何在Spring应用中实现AOP,通过实际的...

    Spring AOP 16道面试题及答案.docx

    Spring AOP,全称为Aspect Oriented Programming,是面向切面编程的一种编程范式,它是对传统的面向对象编程(OOP)的一种补充。在OOP中,核心是对象,而在AOP中,核心则是切面。切面是关注点的模块化,即程序中的...

    Spring Aop四个依赖的Jar包

    Spring AOP,全称Aspect-Oriented Programming(面向切面编程),是Spring框架的一个重要模块,它通过提供声明式的方式来实现面向切面编程,从而简化了应用程序的开发和维护。在Spring AOP中,我们无需深入到每个...

    springboot+aspect实现springaop拦截指定方法.zip

    SpringBoot结合AspectJ实现SpringAOP拦截指定方法的知识点涵盖了多个方面,这包括Spring AOP的基本概念、SpringBoot的应用、切点(Pointcut)与通知(Advice)的定义、自定义注解以及AspectJ的使用。以下是这些知识...

    Spring AOP完整例子

    在Spring XML配置中,我们可以使用`&lt;aop:config&gt;`元素来定义切点表达式,然后使用`&lt;aop:aspect&gt;`元素来声明切面,并将通知方法与切点关联起来。此外,还可以使用注解驱动的配置,通过`@EnableAspectJAutoProxy`注解...

    spring aop依赖jar包

    现在,我们回到主题——"springaop依赖的jar包"。在Spring 2.5.6版本中,使用Spring AOP通常需要以下核心jar包: - `spring-aop.jar`:这是Spring AOP的核心库,包含了AOP相关的类和接口。 - `spring-beans.jar`:...

    spring aop 自定义注解保存操作日志到mysql数据库 源码

    3、对spring aop认识模糊的,不清楚如何实现Java 自定义注解的 4、想看spring aop 注解实现记录系统日志并入库等 二、能学到什么 1、收获可用源码 2、能够清楚的知道如何用spring aop实现自定义注解以及注解的逻辑...

    Spring AOP面向方面编程原理:AOP概念

    ### Spring AOP面向方面编程原理:AOP概念详解 #### 一、引言 随着软件系统的日益复杂,传统的面向对象编程(OOP)逐渐暴露出难以应对某些横切关注点(cross-cutting concerns)的问题。为了解决这一挑战,面向方面编程...

    Spring AOP实现机制

    **Spring AOP 实现机制详解** Spring AOP(面向切面编程)是Spring框架的核心特性之一,它允许程序员在不修改源代码的情况下,通过“切面”来插入额外的业务逻辑,如日志、事务管理等。AOP的引入极大地提高了代码的...

    spring AOP依赖三个jar包

    在这个版本中,Spring AOP支持基于注解的切面定义,比如`@Aspect`、`@Before`、`@After`等,同时也支持基于XML配置的切面定义。这个jar包使得Spring应用程序能够方便地利用AOP特性,无需引入额外的编译工具或构建...

    spring aop切面拦截指定类和方法实现流程日志跟踪

    为了解决这一问题,可以利用Spring框架中的AOP(Aspect Oriented Programming,面向切面编程)技术来实现。 #### 二、Spring AOP 概述 Spring AOP 是Spring框架提供的一种实现AOP的方法。通过AOP,开发者可以在不...

    springAop的配置实现

    Spring AOP(Aspect Oriented Programming,面向切面编程)是Spring框架的重要组成部分,它允许我们通过分离关注点来简化应用程序的开发。在传统的面向对象编程中,业务逻辑与日志记录、事务管理、性能监控等横切...

    spring aop demo 两种实现方式

    Spring AOP(面向切面编程)是Spring框架的重要组成部分,它允许程序员在不修改源代码的情况下,对应用程序的特定部分(如方法调用)进行拦截和处理。这为日志、事务管理、性能监控等提供了方便。本示例提供了一种...

    spring AOP 引入jar包,spring IOC 引入Jar包

    Spring AOP 和 Spring IOC 是 Spring 框架的两个核心组件,它们对于任何基于 Java 的企业级应用开发都至关重要。Spring AOP(面向切面编程)允许开发者在不修改源代码的情况下,通过“切面”来插入新的行为或增强已...

    spring aop 经典例子(原创)

    Spring AOP,全称Aspect-Oriented Programming,是Spring框架中的一个重要组成部分,它引入了面向切面编程的概念,使得开发者可以将关注点分离,更好地实现业务逻辑与系统服务的解耦。在这个经典例子中,我们将深入...

    springAOP所需jar包

    XML配置通常在Spring的配置文件中完成,如`&lt;aop:config&gt;`标签用于开启AOP支持,`&lt;aop:aspect&gt;`定义切面,`&lt;aop:pointcut&gt;`定义切点,`&lt;aop:advisor&gt;`定义通知。注解方式则更简洁,可以使用`@Aspect`、`@Before`、`@...

    反射实现 AOP 动态代理模式(Spring AOP 的实现原理)

    在Spring AOP中,我们通常使用@Aspect注解来定义切面类。切面类中可以包含多个通知(Advice),包括前置通知(Before)、后置通知(After)、返回通知(After-returning)、异常通知(After-throwing)和环绕通知...

    Spring AOP简单demo

    Spring AOP(Aspect Oriented Programming,面向切面编程)是Spring框架的一个重要模块,它扩展了传统的面向对象编程,允许开发者定义“横切关注点”(cross-cutting concerns),如日志、事务管理、性能监控等。...

Global site tag (gtag.js) - Google Analytics