切记:不骄不躁 不浮不沉 学会思考
本文主要介绍spring中 基于注解和基于xml配置文件的两种aop操作 废话不多说 下面就开始吧!!
一、aop操作术语
以上介绍也许太过官方,接下来将举个栗子说明一下,你就会恍然大明白!
eg:如下图。
二、aop操作 话不多说
在spring里面进行aop操作时,使用aspectJ来实现。需要注意的是:
(1)aspectj不是spring的一部分,而是和spring一起使用来进行aop操作
(2)spring2.0以后才新增了对aspectj的支持
使用aspectj实现aop有两种方式:(1)基于aspectj的xml配置 (2)基于aspectj的注解方式 下面将演示这两种方式
基于aspectj的xml配置
1.项目准备:
(1)除了导入spring的基本jar包之外,还需要导入aop的相关jar
(2)创建spring核心配置文件,导入aop约束
工程图如下:
知识准备:使用表达式来配置切入点
修饰符:public private
(1) *表示 所有修饰符 后面表示要增强的方法的全路径 里面的..表示参数
(2) 表示增强Book类里面的所有方法
(3) 表示所有类下面的所有方法
(4) 表示所有以sava开头的方法
2.类准备
创建Book、MyBook类 Book类作为被增强的类 MyBook作为增强类 代码
package per.spring.aop;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* 被增强的类
*/
public class Book {
public void add() {
System.out.println("book...........");
}
//add方法在xml中已经被配置前置增强 该测试方法调用add的时候 应该先执行了mybook里面的before方法 再执行add方法
@Test
public void testAop() {
//根据配置文件 创建对象
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext_aop.xml");
//获取对象
Book book = (Book) context.getBean("book");
book.add();
}
}
package per.spring.aop;
import org.aspectj.lang.ProceedingJoinPoint;
public class MyBook {
//此方法作为前置增强
public void before() {
System.out.println("before...........");
}
//此方法 作为后置增强
public void after() {
System.out.println("after...........");
}
//此方法作为环绕增强
public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
System.out.println("方法之前...........");
//执行被增强的方法
proceedingJoinPoint.proceed();
System.out.println("方法之后...........");
}
}
<?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:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:util="http://www.springframework.org/schema/util"
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/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<!-- bean配置 -->
<bean id="book" class="per.spring.aop.Book"></bean>
<bean id="myBook" class="per.spring.aop.MyBook"></bean>
<!-- aop配置 -->
<aop:config>
<!-- 配置切入点 即被增强的方法 此例子中 add是被增强的方法 -->
<aop:pointcut expression="execution(* per.spring.aop.Book.add(..))" id="pointCut1"/>
<!-- 配置切面 即将增强用到方法上面 -->
<aop:aspect ref="myBook">
<!-- 配置增强类型 是前置 后置 还是环绕 最终 method属性的值 是增强方法的名称 -->
<!-- pointcut-ref的值 是增强到哪个切入点上面 -->
<!-- 前置增强 -->
<aop:before method="before" pointcut-ref="pointCut1"/>
<!-- 后置增强 -->
<aop:after method="after" pointcut-ref="pointCut1"/>
<!-- 环绕增强 -->
<aop:around method="around" pointcut-ref="pointCut1"/>
</aop:aspect>
</aop:config>
</beans>
运行结果:
基于aspectj的注解方式:
类准备
package per.spring.aop;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* 被增强的类
*/
public class Book {
public void add() {
System.out.println("book...........");
}
//add方法被增强
@Test
public void testAop() {
//根据配置文件 创建对象
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext_aop.xml");
//获取对象
Book book = (Book) context.getBean("book");
book.add();
}
}
package per.spring.aop;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
@Aspect//该注解 表示切面
public class MyBook {
//此方法作为前置增强
@Before(value="execution(* per.spring.aop.Book.*(..))")//前置增强的注解 增强Book里面的所有方法
public void before() {
System.out.println("before...........");
}
//此方法 作为后置增强
@After(value="execution(* per.spring.aop.Book.*(..))")
public void after() {
System.out.println("after...........");
}
//此方法作为环绕增强
@Around(value="execution(* per.spring.aop.Book.*(..))")
public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
System.out.println("方法之前...........");
//执行被增强的方法
proceedingJoinPoint.proceed();
System.out.println("方法之后...........");
}
}
<?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:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:util="http://www.springframework.org/schema/util"
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/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<!-- 开启aop操作 -->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
<!-- bean配置 -->
<bean id="book" class="per.spring.aop.Book"></bean>
<bean id="myBook" class="per.spring.aop.MyBook"></bean>
</beans>
运行结果:
根据结果可以看出
环绕增强在方法之前和之后各执行一次
且紧挨着被增强的方法 before
增强 在方法之前执行 但不一定紧挨着被增强的方法
after
同理
以上则是spring中的aop的基于注解和基于配置文件的两种实现方式