在spring中使用aspectj有2种方式:

  • xml配置
  • 注解配置(推荐)

这2种方式需要添加的jar包都一样(待修改):

  • spring-aop.RELEASE.jar
  • aspectjweaver.jar

在spring中使用aspectj,不需要添加aspectjrt.jar,也不需要专门的ajc编译器,使用javac编译即可。


xml配置方式

(1)目标接口、目标类

新建包com.chy.dao,包下新建接口UserDao、实现类UserDaoImpl:

public interface UserDao {
public void addUser();
public void deleteUser();
}
public class UserDaoImpl implements UserDao{
@Override
public void addUser() {
System.out.println("正在添加用户...");
} @Override
public void deleteUser() {
System.out.println("正在删除用户...");
}
}

(2)切面

新建包com.chy.aspect,包下新建类UserDaoAspect:

public class UserDaoAspect {
//前置通知要调用的方法
public void before(){
System.out.println("正在执行前置通知...");
} //后置通知要调用的方法
public void after(){
System.out.println("正在执行后置通知...");
} //返回通知要调用的方法
public void afterReturning(Object obj){
System.out.println("正在执行返回通知...");
System.out.println("目标方法的返回值是:"+obj);
} // 异常通知要调用的方法
public void afterThrowing(JoinPoint point,Exception e){
System.out.println("异常信息:"+e.getMessage());
}
}

(3)xml配置

<?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 https://www.springframework.org/schema/aop/spring-aop.xsd"> <!--目标对象-->
<bean name="userDaoImpl" class="com.chy.dao.UserDaoImpl" /> <!--切面-->
<bean name="userDaoAspect" class="com.chy.aspect.UserDaoAspect" /> <!--AOP配置-->
<aop:config>
<!--全局切入点,所有切面都可以引用。配置切入点只能用id,不能用name -->
<!-- <aop:pointcut id="pointCut" expression="execution(* com.chy.dao.UserDaoImpl.*(..))" /> --> <!--一个<aop:aspect>配置一个切面-->
<aop:aspect ref="userDaoAspect">
<!--局部切入点,只能在此切面中引用-->
<aop:pointcut id="pointCut" expression="execution(* com.chy.dao.UserDao.*(..))" /> <!--前置通知-->
<aop:before method="before" pointcut-ref="pointCut" />
<!--可以引用切入点,也可以现配-->
<!-- <aop:before method="before" pointcut="execution(* com.chy.dao.UserDao.*(..))"/> --> <!--后置通知-->
<aop:after method="after" pointcut-ref="pointCut" /> <!--返回通知-->
<!--如果要使用目标方法的返回值,可以用returning要将目标方法的返回值传递给返回通知要调用的方法的哪个形参-->
<aop:after-returning method="afterReturning" pointcut-ref="pointCut" returning="obj"/> <!--异常通知-->
<!--如果要使用捕获的异常对象,可以用throwing指定要将异常对象传递给哪个形参-->
<aop:after-throwing method="afterThrowing" pointcut-ref="pointCut" throwing="e"/> </aop:aspect> </aop:config> </beans>

5种通知对应的方法都可以传递JoinPoint型的参数,不用传递实参,只有目标方法的返回值、捕获的异常需要传实参。

returning是返回通知的特有属性,throwing是异常通知的特有属性。

环绕通知

环绕通知与其它通知有重叠,通常不与其它通知一起使用。

    // 环绕通知
public Object around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
//前增强
System.out.println("正在执行前增强...");
//调用目标方法
Object object=proceedingJoinPoint.proceed();
//后增强
System.out.println("正在执行后增强...");
return object;
}
            <!--环绕通知-->
<!--ProceedingJoinPoint是JoinPoint的子类,不必手动传参-->
<aop:around method="around" pointcut-ref="pointCut" />

注解配置方式

(1)目标接口、目标类

public interface UserDao {
public void addUser();
public void deleteUser();
}
@Repository
public class UserDaoImpl implements UserDao{
@Override
public void addUser() {
System.out.println("正在添加用户...");
} @Override
public void deleteUser() {
System.out.println("正在删除用户...");
}
}

(2)切面

@Component
@Aspect
public class UserDaoAspect {
//配置切入点
@Pointcut("execution(* com.chy.dao.UserDao.*(..))")
private void pointCut(){} /*
前置通知
@Before(value="pointCut()"),只有一个属性时可以只写属性值
@Before("execution(* com.chy.dao.UserDao.*(..))"),属性值可以引用切入点,也可以现配
*/
@Before("pointCut()")
public void before(){
System.out.println("正在执行前置通知...");
} //后置通知
@After("pointCut()")
public void after(){
System.out.println("正在执行后置通知...");
} //返回通知。可传递目标方法的返回值。
@AfterReturning(value = "pointCut()",returning = "obj" )
public void afterReturning(Object obj){
System.out.println("正在执行返回通知...");
System.out.println("目标方法的返回值是:"+obj);
} // 异常通知。可传递异常对象。
@AfterThrowing(value = "pointCut()",throwing = "e")
public void afterThrowing(JoinPoint point,Exception e){
System.out.println("异常信息:"+e.getMessage());
}
}

环绕通知:

     // 环绕通知
@Around("pointCut()")
public Object around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
//前增强
System.out.println("正在执行前增强...");
//调用目标方法
Object object=proceedingJoinPoint.proceed();
//后增强
System.out.println("正在执行后增强...");
return object;
}

(3)xml配置

<?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 https://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd"> <!--使用包扫描,要扫描多个包时用逗号分隔-->
<context:component-scan base-package="com.chy.dao,com.chy.aspect" /> <!--启用AspectJ的注解-->
<aop:aspectj-autoproxy />
</beans>

使用注解十分方便,xml文件也更加简洁,推荐。


使用

不管是xml方式,还是注解方式,使用时都是一样的:

(1)如果目标类实现了接口,不管切入点配置为接口、还是实现类:

execution(* com.chy.dao.UserDao.*(..))
execution(* com.chy.dao.UserDaoImpl.*(..))

使用时都只能使用接口(代理的是接口,不是具体的实现类):

    UserDao userDao=applicationContext.getBean("userDaoImpl", UserDao.class);
userDao.addUser();

红色标出的两处都只能使用接口。

(2)如果目标类没有实现接口,那切入点只能配置为目标类:

execution(* com.chy.dao.UserDaoImpl.*(..))

使用时自然只能使用目标类:

    UserDaoImpl userDao=applicationContext.getBean("userDaoImpl", UserDaoImpl.class);
userDao.addUser();

调用方法时会自动增强。


AOP常见术语

  • Joinpoint (连接点):目标类中的所有方法
  • Pointcut(切入点):目标类中被增强的方法。有时候我们只增强目标类的部分方法。
  • Weaving(织入):把增强应用到目标对象创建代理对象的过程。spring aop采用动态代理织入,aspectj采用在编译期、类装载期织入。

在Spring中使用AspectJ实现AOP的更多相关文章

  1. Spring中基于xml的AOP

    1.Aop 全程是Aspect Oriented Programming 即面向切面编程,通过预编译方式和运行期动态代理实现程序功能的同一维护的一种技术.Aop是oop的延续,是软件开发中的 一个热点 ...

  2. 详谈 Spring 中的 IOC 和 AOP

    这篇文章主要讲 Spring 中的几个点,Spring 中的 IOC,AOP,下一篇说说 Spring 中的事务操作,注解和 XML 配置. Spring 简介 Spring 是一个开源的轻量级的企业 ...

  3. Spring框架(6)---AspectJ实现AOP

    AspectJ实现AOP 上一篇文章Spring框架(4)---AOP讲解铺垫,讲了一些基础AOP理解性的东西,那么这篇文章真正开始讲解AOP 通过AspectJ实现AOP要比普通的实现Aop要方便的 ...

  4. Spring实战(十二) Spring中注入AspectJ切面

    1.Spring AOP与AspectJ Spring AOP与AspectJ相比,是一个功能比较弱的AOP解决方案. AspectJ提供了许多它不能支持的类型切点,如在创建对象时应用通知,构造器切点 ...

  5. 如何快速理解Spring中的DI和AOP

    前言 Spring框架通过POJO最小侵入性编程.DI.AOP.模板代码手段来简化了Java 开发,简化了企业应用的开发.POJO和模板代码相对来说好理解,本篇重点解读下DI和AOP. 一 DI DI ...

  6. 理解Spring中的IOC和AOP

    我们是在使用Spring框架的过程中,其实就是为了使用IOC,依赖注入和AOP,面向切面编程,这两个是Spring的灵魂. 主要用到的设计模式有工厂模式和代理模式 IOC就是典型的工厂模式,通过ses ...

  7. spring中基于注解使用AOP

    本文内容:spring中如何使用注解实现面向切面编程,以及如何使用自定义注解. 一个场景 比如用户登录,每个请求发起之前都会判断用户是否登录,如果每个请求都去判断一次,那就重复地做了很多事情,只要是有 ...

  8. Spring中的IOC\DI\AOP等概念的简单学习

    IoC(Inversion of Control,控制反转).这是spring的核心,贯穿始终, 所谓IoC,对于spring框架来说,就是由spring来负责控制对象的生命周期和对象间的关系.Spr ...

  9. Spring AOP报错处理 Can not set field to $Proxy 在spring中使用事物或AOP遇到的错误

    [转] 解决方法: http://forum.springsource.org/showthread.php?85016-IllegalArgumentException-with-Applicati ...

随机推荐

  1. Logstash动态模板映射收集Nginx的Json格式日志

    Logstash传输给ES的数据会自动映射为5索引,5备份,字段都为text的的索引.这样基本上无法进行数据分析.所以必须将Logstash的数据按照既定的格式存储在ES中,这时候就要使用到ES模板技 ...

  2. zp本地包

    https://pan.baidu.com/s/13670pdPNvG_o1coYFnovXA 密码: 3pk3

  3. GenTree:基因进化和功能分析

    欢迎来到"bio生物信息"的世界 GenTree是一个集合多种数据的在线数据库. 总共涉及的基因有63152个,蛋白质编码基因有20300个. 评估基因年龄用的是UCSC数据库的1 ...

  4. python |elasticsearchs操作es的例子

    from elasticsearch import Elasticsearch import json import time es = Elasticsearch(['es地址:9200'],ign ...

  5. Centos7基础之查看NETMASK,GATWAY,DNS小技巧

    引语: 查看IP这种很基础的操作,想必大家都快倒背如流了.就是不知道大家知不知道怎么查看NETMASK,GATWAY,DNS.当然nmtui图形化界面以及查看网络配置文件这种骚操作就直接略过了.之前一 ...

  6. 新手學python之新體驗

    1. 使用縮進方式做為程式塊開始結束的標示,程式換行在行末尾加 "\" 2. 元祖(Tuple)數據類型,和List的不同是Tuple不能修改,優點是執行速度比List快,因為不能 ...

  7. CentOS7.5 使用二进制程序部署Kubernetes1.12.2(三)

    一.安装方式介绍 1.yum 安装 目前CentOS官方已经把Kubernetes源放入到自己的默认 extras 仓库里面,使用 yum 安装,好处是简单,坏处也很明显,需要官方更新 yum 源才能 ...

  8. ThinkPHP3(添加,修改,删除)

    实现商品的添加 1.在add.html页面中更改表单元素的名称 Goods控制器的add()方法中获取商品分类 在add.html中循环获取 2.设置提交的位置 3.添加商品代码参见GoodsCont ...

  9. npm与yarn命令

    npm 1. 查看npm版本 node -v npm -v 2. 更新npm至最新版 npm install npm@latest -g 3. npm install:安装依赖 # 在本地node_m ...

  10. 重置 Macbook 登录密码

    1.按 开机键 的同时 按 Command + R,等进度条走完,会出现如下图 2.在菜单栏,选取“实用工具”>“终端”. 3.在终端窗口,键入下面的命令:resetpassword 按下回车键 ...