目录
一、操作术语
1、连接点
类里面哪些方法可以被增强,这些方法称为连接点
2、切入点
实际被真正增强的方法,称为切入点
3、通知(增强)
(1)实际增强的逻辑部分称为通知(增强)
(2)通知有多钟类型
前置通知
后置通知
环绕通知
异常通知
最终通知
4.切面
将通知应用到切入点的过程。
二、AspectJ(准备工作)
Spring框架中一般基于 AspectJ 实现AOP相关操作
1.什么是 AspectJ
* AspectJ 并不是Spring组成部分,是独立的AOP框架,一般将 AspectJ 和 Spring 框架一起使用,进行AOP操作
2.基于AspectJ 实现AOP操作
(1)基于xml配置文件实现
(2)基于注解方式实现(实际使用)
3.在项目中引入AOP相关依赖
3.切入点表达式
(1)切入点表达式作用:知道对哪个类里面的哪个方法进行增强
(2)语法结构:
execution([权限修饰词] [返回类型] [类全路径] [方法名称] ([参数列表]))
举例1:对 com.xx.dao.BookDao类中的add()方法进行增强
execution(*com.xx.dao.BookDao.add()(..))
举例2:对com.xx.dao.BookDao类中的所有方法进行增强
execution(*com.xx.dao.BookDao.*(..))
举例3: 对com.xx.dao包中的所有类,类里的所有方法进行增强
execution(*com.xx.dao.*.*(..))
注: * :可以是public、private,为了为方便则用 * 代替(表示什么类型都可以)
..:表示参数列表
三、AOP操作(AspectJ注解)
1.创建类,在类中定义方法
package com.xx.AOP;
public class User {
public void add(){
System.out.println("add.....");
}
}
2.创建增强类(编写增强逻辑)
package com.xx.AOP;
//增强的类
public class UserProxy {
//前置通知(在User.add()方法执行前执行此方法)
public void before(){
System.out.println("before.......");
}
}
3.进行通知配置
(1)在Spring配置文件中,开启注解的扫描 (可以通过配置类—完全注解开发,也可以通过配置文件,此处使用配置文件)
<?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:context="http://www.springframework.org/schema/context"
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/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
<!--开启注解扫描-->
<context:component-scan base-package="com.xx.AOP"></context:component-scan>
</beans>
(2)使用注解,创建User和UserProxy
(3)在增强类上面添加@Aspect
(4)在Spring配置文件中开启代理对象
4. 配置不同类型的通知
(1)在增强类中,在作为通知的方法上添加通知类型的注解,并使用切入点表达式来配置内容
测试:
package com.xx.Test;
import com.xx.AOP.User;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestAop {
@Test
public void testAop(){
ApplicationContext context =
new ClassPathXmlApplicationContext("AOP.xml");
User user = context.getBean("user", User.class);
user.add();
}
}
/*
before.......
add.....
*/
注:其他类型通知注解
后置通知:@After
异常通知:@AfterThrowing(当增强方法的过程中有异常才执行)
最终通知:@AfterReturning
环绕通知:@Around
注:环绕通知中必须传入ProceedingJoinPoint对象,调用其proceed()方法来手动执行切入点,否则什么也不执行
5.公共切入点抽取
6. 有多个增强类对同一个方法进行增强,设置增强类的优先级
比如再创建一个类对User.add()方法进行增强
package com.xx.AOP;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
@Component
@Aspect
public class PersonProxy {
@Before(value = "execution(* com.xx.AOP.User.add())")
public void Before(){
System.out.println("PersonProxy.before.......");
}
}
(1)在增强类的上面添加注解 @Order(数字类型值),数字类型值越小,则优先级越高
则测试结果为:
四、AOP操作(AspectJ配置文件)
1.创建两个类,增强类和被增强类,创建方法
2.在Spring配置文件中创建两个类对象
3.在Spring配置文件中配置切入点
<?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">
<!--创建对象-->
<bean id="book" class="com.xx.AOPxml.Book"></bean>
<bean id="bookProxy" class="com.xx.AOPxml.BookProxy"></bean>
<!--配置AOP的增强-->
<aop:config>
<!--配置切入点-->
<!--id:切入点名称
expression:切入点表达式(需要被增强的方法的类型及路径)-->
<aop:pointcut id="point" expression="execution(* com.xx.AOPxml.Book.buy(..))"/>
<!--配置切面-->
<aop:aspect ref="bookProxy">
<!--配置作用在具体的方法上-->
<!--即 将增强类中的 method 以哪种通知类型 体现在哪个 切入点(pointcut-ref)上-->
<aop:before method="before" pointcut-ref="point"></aop:before>
</aop:aspect>
</aop:config>
</beans>
测试:
public void testAOPxml(){
ApplicationContext context = new ClassPathXmlApplicationContext("AopXml.xml");
Book book = context.getBean("book", Book.class);
book.buy();
}
结果:
注:也可以创建配置类使用完全注解方式来实现增强功能,不需要创建xml文件