一、切入点表达式

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

环绕通知类似代码块

三、基于XML配置的代码示例

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();
}
}

测试类

四、基于注解的代码示例

1、代码结构和上面差不多

2、目标类的接口代码不变,目标类加注解后代码:

package hjp.springAOP.springAspectJAnnotation;

import org.springframework.stereotype.Service;

@Service("userServiceId")//<bean id="userServiceId" class="hjp.springAOP.springAspectJAnnotation.UserServiceImpl"></bean>
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");
} }

目标类

3、切面类加注解后代码(注意:代码里面使用了引用公共切入点表达式的方法):

package hjp.springAOP.springAspectJAnnotation;

import org.aspectj.lang.JoinPoint;
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;
import org.springframework.stereotype.Component; @Component//<bean id="myAspectId" class="hjp.springAOP.springAspectJAnnotation.MyAspect"></bean>
@Aspect//<aop:aspect ref="myAspectId">
public class MyAspect {
//@Before("execution(* hjp.springAOP.springAspectJAnnotation.*.*(..))")//<aop:before method="myBefore" pointcut="myPointCut"/>
public void myBefore(JoinPoint joinPoint) {
System.out.println("前置通知:" + joinPoint.getSignature().getName());
}
//@AfterReturning(value="execution(* hjp.springAOP.springAspectJAnnotation.*.*(..))",returning="ret")
public void myAfterReturning(JoinPoint joinPoint, Object ret) {
System.out.println("后置通知:方法名," + joinPoint.getSignature().getName() + ";返回值," + ret);
}
//编写共有的切入点表达式
@Pointcut("execution(* hjp.springAOP.springAspectJAnnotation.*.*(..))")
private void myPointCut(){}
//@Around("myPointCut()")//注意加括号
public Object myAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
System.out.println("环绕通知前");
// 手动执行目标方法
Object object = proceedingJoinPoint.proceed();
System.out.println("环绕通知后");
return object;
}
//@AfterThrowing(value="myPointCut()",throwing="e")
public void myAfterThrowing(JoinPoint joinPoint, Throwable e) {
System.out.println("目标类方法" + joinPoint.getSignature().getName() + "抛出异常:" + e.getMessage());
}
@After("myPointCut()")
public void myAfter(JoinPoint joinPoint) {
System.out.println("最终执行通知:方法:" + joinPoint.getSignature().getName());
}
}

切面类

4、beans.xml配置文件,注意新加context和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"
xmlns:context="http://www.springframework.org/schema/context"
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
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!-- spring注解扫描 -->
<context:component-scan base-package="hjp.springAOP.springAspectJAnnotation"></context:component-scan>
<!-- 使AOP注解生效 -->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
</beans>

5、测试类

package hjp.springAOP.springAspectJAnnotation;

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/springAspectJAnnotation/beans.xml";
ApplicationContext applicationContext=new ClassPathXmlApplicationContext(xmlPath);
UserService userService = (UserService)applicationContext.getBean("userServiceId");
userService.addUser();
userService.updateUser();
}
}

测试类

3、

AspectJ AOP学习基础的更多相关文章

  1. Spring AOP 学习例子

    http://outofmemory.cn/code-snippet/3762/Spring-AOP-learn-example     工作忙,时间紧,不过事情再多,学习是必须的.记得以前的部门老大 ...

  2. AOP技术基础

    1.引言 2.AOP技术基础 3.Java平台AOP技术研究 4..Net平台AOP技术研究 2.1 AOP技术起源 AOP技术的诞生并不算晚,早在1990年开始,来自Xerox Palo Alto ...

  3. AOP技术基础(转)

    1.引言 2.AOP技术基础 3.Java平台AOP技术研究 4..Net平台AOP技术研究 2.1 AOP技术起源 AOP技术的诞生并不算晚,早在1990年开始,来自Xerox Palo Alto ...

  4. springBoot AOP学习(一)

    AOP学习(一) 1.简介 AOp:面向切面编程,相对于OOP面向对象编程. Spring的AOP的存在目的是为了解耦.AOP可以让一切类共享相同的行为.在OOP中只能通过继承类或者实现接口,使代码的 ...

  5. Spring AOP学习笔记

      Spring提供了一站式解决方案:          1) Spring Core  spring的核心功能: IOC容器, 解决对象创建及依赖关系          2) Spring Web ...

  6. spring 学习(三):aop 学习

    spring 学习(三):aop 学习 aop 概念 1 aop:面向切面(方面)编程,扩展功能不修改源代码实现 2 AOP采取横向抽取机制,取代了传统纵向继承体系重复性代码 3 aop底层使用动态代 ...

  7. Spring入门IOC和AOP学习笔记

    Spring入门IOC和AOP学习笔记 概述 Spring框架的核心有两个: Spring容器作为超级大工厂,负责管理.创建所有的Java对象,这些Java对象被称为Bean. Spring容器管理容 ...

  8. Spring IOC 和Aspectj AOP

    1.Aspectj AOP 是一套独立的AOP 解决方案,不仅限于java应用,不依赖其他方案,属于编译时增强,有自己单独的编译器.Spring AOP 是基于Spring 容器的的AOP解决方式,属 ...

  9. 现代3D图形编程学习-基础简介(2) (译)

    本书系列 现代3D图形编程学习 基础简介(2) 图形和渲染 接下去的内容对渲染的过程进行粗略介绍.遇到的部分内容不是很明白也没有关系,在接下去的章节中,会被具体阐述. 你在电脑屏幕上看到的任何东西,包 ...

随机推荐

  1. Navi.Soft20.WinCE使用手册

    1.概述 1.1应用场景 随着物联网的普及,越来越多的制造商对货品从原料配备,加工生产,销售出库等环节的要求和把控越来越高.在此情况之下,传统的ERP软件已经无法满足现有的流程. 移动设备的应用,在很 ...

  2. Ace 动画应用实例 ------启动欢迎界面

    仔细观察手机应用很多都用到了动画效果 那么咱们也做一个 除了位移没有使用 其他都有 布局随便放张图片 public class SplashActivity extends Activity { pr ...

  3. 20135220谈愈敏Linux Book_3

    第3章 进程管理 进程是Unix操作系统抽象概念中最基本的一种,进程管理是操作系统的心脏所在. 3.1 进程 进程:处于执行期的程序以及相关的资源的总称. 线程:在进程中活动的对象,拥有独立的程序计数 ...

  4. <实训|第四天>Linux下的vim你真的掌握了吗?附上ftp远程命令上传。

    期待已久的linux运维.oracle"培训班"终于开班了,我从已经开始长期四个半月的linux运维.oracle培训,每天白天我会好好学习,晚上回来我会努力更新教程,包括今天学到 ...

  5. ASP.NET MVC5 插件化机制简单实现

    一.前言 nopCommerce的插件机制的核心是使用BuildManager.AddReferencedAssembly将使用Assembly.Load加载的插件程序集添加到应用程序域的引用中.具体 ...

  6. [1015][JSOI2008]星球大战starwar(并查集)

    1015: [JSOI2008]星球大战starwar Time Limit: 3 Sec  Memory Limit: 162 MBSubmit: 2124  Solved: 909[Submit] ...

  7. jQuery基础之(三)jQuery功能函数前缀及与window.onload冲突

    1.jQuery功能函数前缀 在javascript中,开发者通常会编写一些小函数来处理各种操作细节,例如在用户提交表单时,要将文本框最前端和最末端的空格内容清理掉.而javascript中没有类似t ...

  8. angularJS中-$route路由-$http(ajax)的使用

    后台请求使用的是nodeJS驱动(后面帖代码),很简单的RESTFUL, 页面使用的是bottstarp3.0(懒人神器); 第一个例子: 在本地架设NODEJS, angular的所有请求都是请求本 ...

  9. html 中添加背景音乐

    Embed (一).基本语法: embed src=url 说明:embed可以用来插入各种多媒体,格式可以是 Midi.Wav.AIFF.AU.MP3等等, Netscape及新版的IE 都支持.u ...

  10. Kettle_设置变量的两种方法

    一个复杂的kettle作业一般包括很多子作业和转换,在主作业Start后通常会添加一个[设置变量]的流程,该流程的功能是为所有流程的公共变量设置通用值.       主作业添加的[设置变量]针对的是所 ...