Spring2.5注解实现AOP

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

package test;

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

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

 
 

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

那么我们定义切面

 

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 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>  
 

 

然后使用客户端调用:

 

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

 

before sayHello   
around start   
hello world   
after sayHello   
method has returned   
around end  

 

 

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

 

around start   
hello world   
after sayHello   
throw runtime exception  

 

 

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

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

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值