AspectJ AOP学习基础

一、切入点表达式

  1、execution:匹配方法的执行

    格式:execution(修饰符 返回值类型 包.类.方法(参数) throw 异常)

      1.1修饰符,表示方法的修饰符,一般省略。

      1.2返回类型 String表示返回String;void表示没有返回值;*表示返回任意类型,包括无返回值。

      1.3包

        hjp.spring.service 表示指定的包

        hjp.spring.*.service 表示spring下子模块包含service的包

        hjp.spring.service.. 表示service目录及其子目录

        综合:hjp.spring.*.service..

      1.4类 UserService表示指定的类;*Service表示以Service结尾;Test*表示以Test开头;*表示任意类名。

      1.5方法(与类相似)

        addUser表示指定方法;add*表示以add开头;*Do表示以Do结尾;*表示任意。

      1.6参数 ()表示没有参数;(int)表示一个int类型参数;(int,int)表示两个int类型参数(如果是java.lang包下的可以省略,其他类型必须写完全限定类名);(..)表示

          任意,包括无参。

      1.7throws 异常,一般省略。

  综合:execution(* hjp.spring.*.service..*.*(..))

  2、within:匹配包或子包中的方法,如:within(hjp.spring.service..*)

  3、this:匹配实现接口的代理对象中的方法,如:this(hjp.spring.dao.UserDao)

  4、target:匹配实现接口的目标对象中的方法,如:target(hjp.spring.daoImpl.UserDao)

  5、args:匹配参数格式符合标准的方法,如args(int,int)

  6、bean:匹配指定的bean,如:bean("userServiceId")

二、AspectJ规定的通知类型

  1、before:前置通知(应用:各种校验),在方法执行前执行,如果通知抛出异常,阻止方法运行。

  2、afterReturning:后置通知(应用:常规数据处理),方法正常返回后执行,如果方法中抛出异常,通知无法执行;在方法执行后执行,所以才可以获得方法的返回值。

  3、around:环绕通知(应用:可以做任何事),方法执行前后分别执行,可以阻止方法的执行。

  4、afterThrowing:抛出异常通知(应用:包装异常信息),方法抛出异常后执行,如果方法没有抛出异常,无法执行。

  5、after:最终通知(应用:清理现场),方法执行完毕后执行,无论方法是否有异常出现。

  环绕通知类似代码块:  

try{
//前置通知(before)
//手动执行目标方法
//后置通知(after),可获得返回值
}catch{
//抛出异常通知(afterThrowing),可获得具体异常信息
}finally{
//最终(finally)
}

环绕通知类似代码块

三、代码示例

1、代码结构:

2、aspectj aop不是针对接口的,所有有没有接口不影响AOP实现,下面是UserService接口和UserServiceImpl实现类(目标类)代码

package hjp.springAOP.springAspectJXml;

public interface UserService {
    void addUser();

    void updateUser();
}

UserService

package hjp.springAOP.springAspectJXml;

public class UserServiceImpl implements UserService {

    @Override
    public void addUser() {
        // TODO Auto-generated method stub
        System.out.println("aspectj xml add user");
    }

    @Override
    public void updateUser() {
        // TODO Auto-generated method stub
        //int i=9/0;
        System.out.println("aspectj xml update user");
    }

}

UserServiceImpl

3、切面类MyAspect代码

package hjp.springAOP.springAspectJXml;

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

public class MyAspect {
    public void myBefore(JoinPoint joinPoint) {
        System.out.println("前置通知:" + joinPoint.getSignature().getName());
    }

    public void myAfterReturning(JoinPoint joinPoint, Object ret) {
        System.out.println("后置通知:方法名," + joinPoint.getSignature().getName() + ";返回值," + ret);
    }

    public Object myAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        System.out.println("环绕通知前");
        // 手动执行目标方法
        Object object = proceedingJoinPoint.proceed();
        System.out.println("环绕通知后");
        return object;
    }

    public void myAfterThrowing(JoinPoint joinPoint, Throwable e) {
        System.out.println("目标类方法" + joinPoint.getSignature().getName() + "抛出异常:" + e.getMessage());
    }

    public void myAfter(JoinPoint joinPoint) {
        System.out.println("最终执行通知:方法:" + joinPoint.getSignature().getName());
    }
}

MyAspect

4、beans.xml配置文件,记得添加aop命名空间和引用地址

<?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.xsd
                              http://www.springframework.org/schema/aop
                              http://www.springframework.org/schema/aop/spring-aop.xsd">
    <!-- 1、创建目标类 -->
    <bean id="userServiceId" class="hjp.springAOP.springAspectJXml.UserServiceImpl"></bean>
    <!-- 2、创建切面类 (通知) -->
    <bean id="myAspectId" class="hjp.springAOP.springAspectJXml.MyAspect"></bean>
    <!-- aop编程
         如果强制使用CGLIB,则设置aop:config 属性proxy-target-class="true"
     -->
    <aop:config>
        <!-- aspectj 编程
             ref指向切面类 -->
        <aop:aspect ref="myAspectId">
            <!-- 声明切入点,确定目标类上哪些方法需被增强 -->
            <aop:pointcut expression="execution(* hjp.springAOP.springAspectJXml.*.*(..))" id="myPointCut" />
            <!-- 声明通知方式 -->
            <!-- 1、前置通知
                 method切面类中具体方法名
                 pointcut-ref指向切入点(使用pointcut,也可以在通知里配置自己的切入点表达式)
            <aop:before method="myBefore" pointcut-ref="myPointCut"/>
             -->
             <!-- 2、后置通知,可获取到返回值
                   returning用于设置通知的第二个参数名称,类型为Object(注意:此处参数名称要与切面类后置通知方法第二个参数名称一致)
             <aop:after-returning method="myAfterReturning" pointcut-ref="myPointCut" returning="ret"/>
              -->
              <!-- 3、环绕通知
              <aop:around method="myAround" pointcut-ref="myPointCut"/>
               -->
               <!-- 4、抛出异常通知(测试此通知时,将目标类中updateUser方法中int i=9/0;代码注释去掉)
                       目标方法在抛出异常时执行,如果没有则不执行
                       throwing设置抛出异常通知的第二个参数,参数名称和此处设置的e一致,类型Throwable
                <aop:after-throwing method="myAfterThrowing" pointcut-ref="myPointCut" throwing="e"/>
                -->
                <!-- 5、最终通知,即任何情况下都会执行 -->
                <aop:after method="myAfter" pointcut-ref="myPointCut"/>
        </aop:aspect>
    </aop:config>
</beans>

beans.xml

5、测试类

package hjp.springAOP.springAspectJXml;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class TestApp {
    @Test
    public void demo1() {
        String xmlPath="hjp/springAOP/springAspectJXml/beans.xml";
        ApplicationContext applicationContext=new ClassPathXmlApplicationContext(xmlPath);
        UserService userService = (UserService)applicationContext.getBean("userServiceId");
        userService.addUser();
        userService.updateUser();
    }
}

测试类

时间: 2024-08-29 13:20:21

AspectJ AOP学习基础的相关文章

Spring AOP 学习例子

http://outofmemory.cn/code-snippet/3762/Spring-AOP-learn-example 工作忙,时间紧,不过事情再多,学习是必须的.记得以前的部门老大说过:“开发人员不可能一天到晚只有工作,肯定是需要自我学习.第一:为了更充实自己,保持进步状态.第二:为了提升技术,提高开发能力.第三:保持程序员对技术和学习的热情,工作的激情.程序员还是需要把基础打扎实,修炼自己的内功.” 所以赶紧把学习的东西总结一下,加深印象.之前有说了下AOP的原理 (http://

Spring IOC及AOP学习总结

一.Spring IOC体系学习总结: Spring中有两个容器体系,一类是BeanFactory.另一类是ApplicationContext.BeanFactory提供了基础的容器功能.ApplicationContext则是基于BeanFactory建立的一套更加丰富的容器体系,基于ApplicationContext构建了Spring AOP体系(基于AOP体系又构建了声明式事务模型),I18n的支持,基于观察者模式的事件模型,多渠道的Bean资源的载入(比如从文件系统,从interne

java框架--Spring XML AOP 配置基础(二)

 1. AOP的原理  点击查看 Spring有两大核心,IOC和AOP.IOC在java web项目中无时无刻不在使用.然而AOP用的比较少,的确也是一般的项目用的场所不多.事务控制基本都用,但却是Spring封装的不需要我们再去实现,但Spring的AOP远 不止这些,不能因为项目中没有使用,而不去学习及理解.我觉得这是作为一个java web软件开发人员必须具备的技能.业内很多将AOP应用在日志记录上,可惜我们项目没这么做,后面需要学习下.在这先把Spring    AOP的基本用法,在脑

Spring入门IOC和AOP学习笔记

Spring入门IOC和AOP学习笔记 概述 Spring框架的核心有两个: Spring容器作为超级大工厂,负责管理.创建所有的Java对象,这些Java对象被称为Bean. Spring容器管理容器中Bean之间的依赖关系,使用一种叫做"依赖注入"的方式来管理bean之间的依赖关系. Spring有两个核心接口:BeanFactory和ApplicationContext,ApplicationContext是BeanFactory的子接口.它们都可以代表Spring容器,Spri

springBoot AOP学习(一)

AOP学习(一) 1.简介 AOp:面向切面编程,相对于OOP面向对象编程. Spring的AOP的存在目的是为了解耦.AOP可以让一切类共享相同的行为.在OOP中只能通过继承类或者实现接口,使代码的耦合度增强,且类继承只能为单继承,阻碍更多行为添加到一组类上,AOP弥补了OOP的不足. Spring支持AspectJ的注解式切面编程. (1)使用@Aspect声明是一个切面: (2)使用@After.@Before.@Around定义通知(Advice),可直接将拦截规则(切点)作为参数: (

php学习基础-文件系统(一) 文件处理,文件权限

一.PHP系统文件处理 /* PHP文件系统处理 * 所有文件处理都是使用系统函数完成的. * 是基于Linux/Unix系统为模型 * * 文件系统处理的作用: * 1. 所有的项目离不开文件处理 * 2. 可以用文件长时间保存数据 * 3. 建立缓存, 服务器中文件操作 * * 文件处理 * 1. 文件类型 * 以Linux为模型的, 在Windows只能获取file, dir或unknow 三种类型 * 在Linux/Unix下, block, char, dir, fifo, file,

php学习基础-文件系统(二) 文件读写操作、文件资源处理

一.文件的打开与关闭 /* *读取文件中的内容 * file_get_contents(); //php5以上 * file() * readfile(); * * 不足:全部读取, 不能读取部分,也不能指定的区域 * * fopen() * fread() * fgetc() * fgets() * * * * * 写入文件 * file_put_contents("URL", "内容字符串"); //php5以上 * 如果文件不存在,则创建,并写入内容 * 如果

关于集成学习基础的简单描述

关于集成学习基础的简单描述 什么是集成学习? 集成建模是优化模型表现的一条重要途径.通常来说,将集成学习方法运用在你所构建的诸多模型之上是十分值得的,而同道中人们也一次又一次地证明着这一点.他们在诸如Kaggle之类的数据建模竞赛中往往会不约而同地采用集成学习,并且从中受益. 集成学习其实是一个很宽泛的概念,对于它的定义,可谓仁者见仁智者见智.接下来,本文将介绍一些集成建模的基本概念和思想,这些知识应该足以让你起步,从而去构建你自己的集成模型.同时,和往常一样,我们将尽量让它们看起来简单一些.

Yii学习——基础(1)

Yii采用MVC设计模式. Yii还引入了一个称作front-controller的东西,并命名为application. application封装了对用户请求的处理. application会收集用户的请求信息,并交予对应的控制器进一步处理. 这是一张交互流程图. 典型的Yii应用的工作流程 见图. index.php作为bootstrap脚本,创建了application并run它. 通过组件request,application获得用户请求的详细信息. 通过组件urlManager,ap