Spring AOP使用整理:使用@AspectJ风格的切面声明

要启用基于@AspectJ风格的切面声明,需要进行以下的配置:

<!-- 启用@AspectJ风格的切面声明 -->
<aop:aspectj-autoproxy proxy-target-class="true"/>

<!-- 通过注解定义bean。默认同时也通过注解自动注入 -->
<context:component-scan base-package="com.cjm"/>

基于@AspectJ风格的切面声明的源码:

/**
 * 声明本类为一个切面
 */
@Component
@Aspect
public class MyAspectJ {
    /**
     * 声明一个切入点(包括切入点表达式和切入点签名)
     */
    @Pointcut("execution(* com.cjm.model..*.*(..))")
    public void pointcut1(){}

    /**
     * 声明一个前置通知
     */
    @Before("pointcut1()")
    public void beforeAdvide(JoinPoint point){
        System.out.println("触发了前置通知!");
    }

    /**
     * 声明一个后置通知
     */
    @After("pointcut1()")
    public void afterAdvie(JoinPoint point){
        System.out.println("触发了后置通知,抛出异常也会被触发!");
    }

    /**
     * 声明一个返回后通知
     */
    @AfterReturning(pointcut="pointcut1()", returning="ret")
    public void afterReturningAdvice(JoinPoint point, Object ret){
        System.out.println("触发了返回后通知,抛出异常时不被触发,返回值为:" + ret);
    }

    /**
     * 声明一个异常通知
     */
    @AfterThrowing(pointcut="pointcut1()", throwing="throwing")
    public void afterThrowsAdvice(JoinPoint point, RuntimeException throwing){
        System.out.println("触发了异常通知,抛出了RuntimeException异常!");
    }

    /**
     * 声明一个环绕通知
     */
    @Around("pointcut1()")
    public Object aroundAdvice(ProceedingJoinPoint point)throws Throwable{
        System.out.println("触发了环绕通知 开始");
        Object o = point.proceed();
        System.out.println("触发了环绕通知 结束");
        return o;
    }
}

1、切入点表达式的格式:execution([可见性] 返回类型 [声明类型].方法名(参数) [异常])

2、切入点表达式通配符:       *:匹配所有字符       ..:一般用于匹配多个包,多个参数       +:表示类及其子类

3、切入点表达式支持逻辑运算符:&&、||、!

4、切入点表达式关键词:

1)execution:用于匹配子表达式。

//匹配com.cjm.model包及其子包中所有类中的所有方法,返回类型任意,方法参数任意             @Pointcut("execution(* com.cjm.model..*.*(..))")             public void before(){}

2)within:用于匹配连接点所在的Java类或者包。

//匹配Person类中的所有方法

@Pointcut("within(com.cjm.model.Person)")

public void before(){}

//匹配com.cjm包及其子包中所有类中的所有方法

@Pointcut("within(com.cjm..*)")

public void before(){}

3) this:用于向通知方法中传入代理对象的引用。

@Before("before() && this(proxy)")

public void beforeAdvide(JoinPoint point, Object proxy){

//处理逻辑

}

4)target:用于向通知方法中传入目标对象的引用。

@Before("before() && target(target)

public void beforeAdvide(JoinPoint point, Object proxy){

//处理逻辑

}

5)args:用于将参数传入到通知方法中。

@Before("before() && args(age,username)")

public void beforeAdvide(JoinPoint point, int age, String username){

//处理逻辑

}

6)@within:用于匹配在类一级使用了参数确定的注解的类,其所有方法都将被匹配。

@Pointcut("@within(com.cjm.annotation.AdviceAnnotation)") - 所有被@AdviceAnnotation标注的类都将匹配

public void before(){}

  @Retention(RetentionPolicy.RUNTIME)
  @Target({ElementType.TYPE, ElementType.METHOD})
  @Documented
  @Inherited
  public @interface AdviceAnnotation {

  }

7)@target:和@within的功能类似,但必须要指定注解接口的保留策略为RUNTIME。

@Pointcut("@target(com.cjm.annotation.AdviceAnnotation)")

public void before(){}

8)@args:传入连接点的对象对应的Java类必须被@args指定的Annotation注解标注。

@Before("@args(com.cjm.annotation.AdviceAnnotation)")

public void beforeAdvide(JoinPoint point){

//处理逻辑

}

public class Person {
    public void say(Address address){
          //处理逻辑
   }
}

 @AdviceAnnotation
 public class Address {

 }

如果需要在Person类的say方法被调用时触发beforeAdvide通知,那么say方法的参数对应的Java类型Address类必须要被@AdviceAnnotation标注。

9)@annotation:匹配连接点被它参数指定的Annotation注解的方法。也就是说,所有被指定注解标注的方法都将匹配。

@Pointcut("@annotation(com.cjm.annotation.AdviceAnnotation)")

public void before(){}

public class Person {
      @AdviceAnnotation
      public void say(Address address){
              //处理逻辑
    }
}

Person类的say方法被@AdviceAnnotation标注,所以它匹配。

10)bean:通过受管Bean的名字来限定连接点所在的Bean。该关键词是Spring2.5新增的。

@Pointcut("bean(person)")

public void before(){}

id为person的受管Bean中的所有方法都将匹配。

时间: 2024-08-12 18:31:05

Spring AOP使用整理:使用@AspectJ风格的切面声明的相关文章

Spring AOP使用整理:各种通知类型的介绍

2.PersonImpl类的源码 public class PersonImpl implements Person { private String name; private int age; public void setName(String name) { this.name = name; } public void setAge(int age) { this.age = age; } public void info() { System.out.println("\t我叫&qu

Spring AOP使用整理:自动代理以及AOP命令空间

三.自动代理的实现 1.使用BeanNameAutoProxyCreator 通过Bean的name属性自动生成代理Bean. <bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator"> <property name="beanNames"> <list> <value>*Target</value>

Spring -- AOP入门基础

动态代理 我们在日常开发过程中是否会遇到下图中的这种状况 红框中的是我们要输出的日志,你是否发现,日志中大部分信息都是相同的,并且如果我们要修改一个地方,所有的地方都需要改,而且代码看起来还比较冗余 下面我们就可以通过动态代理的方式解决这个问题 看下代码 public interface Calculation { public int add(int x, int y); public int sub(int x, int y); public int mul(int x, int y); p

Spring AOP—注解配置方法的使用

Spring除了支持Schema方式配置AOP,还支持注解方式:使用@AspectJ风格的切面声明. 1 启用对@AspectJ的支持 Spring默认不支持@AspectJ风格的切面声明,为了支持需要使用如下配置: 这样Spring就能发现@AspectJ风格的切面并且将切面应用到目标对象. 2 声明切面 @AspectJ风格的声明切面非常简单,使用@Aspect注解进行声明: 然后将该切面在配置文件中声明为Bean后,Spring就能自动识别并进行AOP方面的配置: 该切面就是一个POJO,

关于 Spring AOP (AspectJ) 你该知晓的一切

[版权申明]未经博主同意,谢绝转载!(请尊重原创,博主保留追究权) http://blog.csdn.net/javazejian/article/details/54629058 出自[zejian的博客] 关联文章: 关于Spring IOC (DI-依赖注入)你需要知道的一切 关于 Spring AOP (AspectJ) 你该知晓的一切 本篇是年后第一篇博文,由于博主用了不少时间在构思这篇博文,加上最近比较忙,所以这篇文件写得比较久,也分了不同的时间段在写,已尽最大能力去连贯博文中的内容

关于 Spring AOP (AspectJ) 该知晓的一切

关联文章: 关于Spring IOC (DI-依赖注入)你需要知道的一切 关于 Spring AOP (AspectJ) 你该知晓的一切 本篇是年后第一篇博文,由于博主用了不少时间在构思这篇博文,加上最近比较忙,所以这篇文件写得比较久,也分了不同的时间段在写,已尽最大能力去连贯博文中的内容,尽力呈现出简单易懂的文字含义,如文中有错误请留言,谢谢. OOP的新生机 OOP新生机前夕 神一样的AspectJ-AOP的领跑者 AspectJ的织入方式及其原理概要 基于Aspect Spring AOP

Spring源码阅读:使用标准AOP的API模拟Spring AOP + AspectJ的设计与实现

在上一篇博客中,提到了标准AOP与Spring AOP.这一篇就来把他们模拟出来. 在模拟之前,还需要提及的是,在Spring框架中,对于AOP的支持: Spring 支持的AOP AspectJ是另外一个有名的AOP框架,Spring也集成AspectJ,同时Spring AOP与AspectJ有一定程度的集成,这样一来Spring中就支持两种AOP:1)Spring AOP.2)AspectJ.而使用AOP的方式却又三种: 1)完全使用Spring AOP 2)完全使用AspectJ(分为注

Spring Aop详尽教程

一.概念 AOP(Aspect Oriented Programming):面向切面编程. 面向切面编程(也叫面向方面编程),是目前软件开发中的一个热点,也是Spring框架中的一个重要内容.利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率. 二.用途 日志记录,性能统计,安全控制,权限管理,事务处理,异常处理,资源池管理. 三.详解 注意:代码请见下篇博文 1. 切面(Aspect) 官方的抽象定义为“一个关注点的模块

Spring AOP 的实现 原理

反射实现 AOP 动态代理模式实例说明(Spring AOP 的实现 原理) 比如说,我们现在要开发的一个应用里面有很多的业务方法,但是,我们现在要对这个方法的执行做全面监控,或部分监控.也许我们就会在要一些方法前去加上一条日志记录, 我们写个例子看看我们最简单的解决方案 我们先写一个接口IHello.java代码如下: [java] view plaincopyprint? package sinosoft.dj.aop.staticaop; public interface IHello {