- AOP的相关术语
- 连接点:可以被拦截的点。
- 切入点:真正被拦截的点。
- 通知:增强方法
- 引介:类的增强
- 目标:被增强的对象
- 织入:将增强应用到目标的过程。
- 代理:织入增强后产生的对象
- 切面:切入点和通知的组合
一、创建Web项目,引入jar包
- Spring 核心jar包
- com.springsource.org.apache.commons.logging-1.1.1.jar
- spring-beans-5.2.9.RELEASE.jar
- spring-context-5.2.9.RELEASE.jar
- spring-core-5.2.9.RELEASE.jar
- spring-expression-5.2.9.RELEASE.jar
- Spring IOC、AOP核心jar包
- spring-aop-5.2.9.RELEASE.jar
- JUnit5 核心jar包
- spring-test-5.2.9.RELEASE.jar Spring整合单元测试的jar包
- Spring AspectJ核心jar包
- spring-aspects-5.2.9.RELEASE.jar spring和aspectj整合的jar包
- com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar AspectJ的jar包
二、创建类
public interface ProductDao { public void save(); public void find(); public void update(); public void delete(); }
public class ProductDaoImpl implements ProductDao { @Override public void save() { System.out.println("保存商品..."); } @Override public void find() { System.out.println("查询商品..."); } @Override public void update() { System.out.println("修改商品..."); } @Override public void delete() { System.out.println("删除商品..."); } }
三、配置Spring (将类交给Spring管理)
①、设置XML约束
spring-framework-5.2.9.RELEASEdocsspring-framework-referencecore.html#xsd-schemas-aop
②、将类交给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 https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd"> <bean id="productDao" class="com.xxx.spring.dao.ProductDaoImpl"/> </beans>
③、编写测试类
引入了Spring整合JUnit的jar包,就不用我们手动创建ApplicationContext对象了
@SpringJUnitConfig(locations = "classpath:bean.xml")//JUnit5 public class SpringDemo { @Autowired private ProductDao productDao; @Test public void demo1() { productDao.save(); productDao.find(); productDao.update(); productDao.delete(); } }
保存商品...
查询商品...
修改商品...
删除商品...
④、编写切面类(增强方法所在的对象)
public class AspectXML { public void checkPri() { System.out.println("权限验证方法======"); } }
⑤、通过配置完成AOP
<!-- 将切面类交给Spring管理 --> <bean id="aspectXML" class="com.xxx.spring.dao.AspectXML"/> <!-- 通过AOP的配置完成对目标类产生代理 --> <aop:config> <!-- expression:指定要增强的方法 --> <aop:pointcut expression="execution(* com.xxx.spring.dao.ProductDaoImpl.save(..))" id="product_save" /> <!-- 配置切面 ref="aspectXML" 指定切面类--> <aop:aspect ref="aspectXML"> <!-- 切面类中的增强方法对应的切入点 --> <aop:before method="checkPri" pointcut-ref="product_save" /> </aop:aspect> </aop:config>
⑥、执行③中测试方法
权限验证方法======
保存商品...
查询商品...
修改商品...
删除商品...
四、解析<aop:config>
<!-- 将切面类交给Spring管理 --> <bean id="aspectXML" class="com.xxx.spring.dao.AspectXML"/> <!-- 通过AOP的配置完成对目标类产生代理 --> <aop:config> <!-- expression:指定要增强的方法 --> <aop:pointcut expression="execution(* com.xxx.spring.dao.ProductDaoImpl.save(..))" id="product_save" /> <!-- 配置切面 ref="aspectXML" 指定切面类--> <aop:aspect ref="aspectXML"> <!-- 前置通知 --> <aop:before method="checkPri" pointcut-ref="product_save" /> <!-- 后置通知 --> <aop:after-returning method=""/> <!-- 环绕通知 --> <aop:around method=""/> <!-- 异常通知 --> <aop:after-throwing method=""/> <!-- 最终通知 --> <aop:after method=""/> </aop:aspect> </aop:config>
①、配置切面类,为切入点提供增强方法
<bean id="aspectXML" class="com.xxx.spring.dao.AspectXML"/>
②、通过表达式设置切入点
<aop:pointcut expression="execution(* com.xxx.spring.dao.ProductDaoImpl.save(..))" id="product_save" />
- 基于execution函数的表达式语法:
- [访问修饰符] 方法返回值 包名.类名.方法名(参数)
- [public] void com.xxx.spring.dao.ProductDaoImpl.save(..)
-
* *.*.*.*DaoImpl.save(..) ----所有DaoImpl类中的save方法
-
* com.xxx.spring.dao.ProductDaoImpl+.save(..) ----当前ProductDaoImpl类和其子类中的save方法
-
* com.xxx.spring..*.*(..) -- 当前spring包和其子包下所有类中的所有方法
③、指定切面类,设置切入点需要增强方法和增强方法的执行规则
<aop:aspect ref="aspectXML"> <!-- 前置通知 --> <aop:before method="" pointcut-ref="" /> <!-- 后置通知 --> <aop:after-returning method=""/> <!-- 环绕通知 --> <aop:around method=""/> <!-- 异常通知 --> <aop:after-throwing method=""/> <!-- 最终通知 --> <aop:after method=""/> </aop:aspect>
Ⅰ、前置通知
<aop:pointcut expression="execution(* com.xxx.spring.dao.ProductDaoImpl.save(..))" id="product_save" />
<aop:before method="checkPri" pointcut-ref="product_save" />
/** * 前置通知 * 获取切入点信息 */ public void checkPri(JoinPoint joinPoint) { System.out.println("权限验证======"+joinPoint); }
Ⅱ、后置通知
@Override public String delete() { System.out.println("删除商品..."); return "delete"; }
<aop:pointcut expression="execution(* com.xxx.spring.dao.ProductDaoImpl.delete(..))" id="product_delete" />
<!-- 后置通知 --> <aop:after-returning method="writeLog" pointcut-ref="product_delete" returning="result"/>
/** * 后置通知 * 获取切入点返回值 */ public void writeLog(Object result) { //Object result和上面配置文件中的returning="result"要一致 System.out.println("日志记录======"+result); }
Ⅲ、环绕通知
<aop:pointcut expression="execution(* com.xxx.spring.dao.ProductDaoImpl.update(..))" id="product_update" />
<!-- 环绕通知 --> <aop:around method="checkPerformance" pointcut-ref="product_update"/>
/** * 环绕通知 * 获取切入点 * @throws Throwable * */ public Object checkPerformance(ProceedingJoinPoint joinPoint) throws Throwable { System.out.println("性能检测前======"); Object obj=joinPoint.proceed(); System.out.println("性能检测后======"); return obj; }
Ⅳ、异常通知
@Override public void find() { System.out.println("查询商品..."); int i=1/0; }
<aop:pointcut expression="execution(* com.xxx.spring.dao.ProductDaoImpl.find(..))" id="product_find" />
<!-- 异常通知 --> <aop:after-throwing method="afterThrowing" pointcut-ref="product_find" throwing="ex"/>
/** * 异常抛出通知 * 获取异常信息 */ public void afterThrowing(Throwable ex) {//Throwable ex与上面配置中的throwing="ex"值要一致 System.out.println("异常抛出通知======"+ex.getMessage()); }
Ⅴ、最终通知(无论切入点是否有异常都会执行)
<aop:pointcut expression="execution(* com.xxx.spring.dao.ProductDaoImpl.find(..))" id="product_find" />
<!-- 最终通知 --> <aop:after method="after" pointcut-ref="product_find"/>
/** * 最终通知 */ public void after() { System.out.println("最终通知======"); }
最终结果:
权限验证======execution(void com.xxx.spring.dao.ProductDao.save()) 保存商品... 性能检测前====== 修改商品... 性能检测后====== 删除商品... 日志记录======delete 查询商品... 最终通知====== 异常抛出通知======/ by zero
- AOP的入门开发
- 引入jar包
- 编写目标类并配置交给Spring管理
- 编写切面类并配置交给Spring管理
- 进行aop的配置
-
<aop:config> <aop:pointcut expression=”execution(表达式)” id=”pc1”/> <aop:aspect> <aop:before method=”” pointcut-ref=”pc1”/> </aop:aspect> </aop:config>