1.AOP概述
1.1什么是 AOP
1.2AOP的作用及优势
1.3AOP的实现方式
2.spring中AOP的细节
2.1AOP的相关术语
2.2学习spring要明确的事情
3.基于xml的AOP配置
需求:对业务方法进行日志增强
3.1导入jar包
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.itheima</groupId> <artifactId>day03_eesy_03springAOP</artifactId> <version>1.0-SNAPSHOT</version> <packaging>jar</packaging> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.0.2.RELEASE</version> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.8.7</version> </dependency> </dependencies> </project>
3.2业务层接口
package com.itheima.service; /** * 账户的业务层接口 */ public interface IAccountService { //idea中新建一个类的快捷键:alt+insert,up键和down键可以选择接口 /** * 模拟保存账户 */ void saveAccount(); /** * 模拟更新账户 * @param */ void updateAccount(int i); /** * 删除账户 * @return */ int deleteAccount(); }
3.3业务类
package com.itheima.service.impl; import com.itheima.service.IAccountService; public class AccountServiceImpl implements IAccountService { @Override public void saveAccount() { System.out.println("执行了保存"); } @Override public void updateAccount(int i) { System.out.println("执行了更新"+i); } @Override public int deleteAccount() { System.out.println("执行了删除"); return 0; } }
3.4日志类
package com.itheima.utils; /** * 用于记录日志的工具类,它里面提供了公共的代码 */ public class Logger { /** * 用于打印日志:计划让其在切入点方法执行之前执行(切入点方法就是业务层方法) */ public void printLog(){ System.out.println("Logger类中的pringLog方法开始记录日志了。。。"); } }
3.5配置bean.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 http://www.springframework.org/schema/aop/spring-aop.xsd"> <!-- 1.配置srping的Ioc,把service对象配置进来--> <bean id="accountService" class="com.itheima.service.impl.AccountServiceImpl"></bean> <!--spring中基于XML的AOP配置步骤 1、把通知Bean也交给spring来管理 2、使用aop:config标签表明开始AOP的配置 3、使用aop:aspect标签表明配置切面 id属性:是给切面提供一个唯一标识 ref属性:是指定通知类bean的Id。 4、在aop:aspect标签的内部使用对应标签来配置通知的类型 我们现在示例是让printLog方法在切入点方法执行之前之前:所以是前置通知 aop:before:表示配置前置通知 method属性:用于指定Logger类中哪个方法是前置通知 pointcut属性:用于指定切入点表达式,该表达式的含义指的是对业务层中哪些方法增强 切入点表达式的写法: 关键字:execution(表达式) 表达式: 访问修饰符 返回值 包名.包名.包名...类名.方法名(参数列表) 标准的表达式写法: public void com.itheima.service.impl.AccountServiceImpl.saveAccount() 访问修饰符可以省略 void com.itheima.service.impl.AccountServiceImpl.saveAccount() 返回值可以使用通配符,表示任意返回值 * com.itheima.service.impl.AccountServiceImpl.saveAccount() 包名可以使用通配符,表示任意包。但是有几级包,就需要写几个*. * *.*.*.*.AccountServiceImpl.saveAccount()) 包名可以使用..表示当前包及其子包 * *..AccountServiceImpl.saveAccount() 类名和方法名都可以使用*来实现通配 * *..*.*() 参数列表: 可以直接写数据类型: 基本类型直接写名称 int 引用类型写包名.类名的方式 java.lang.String 可以使用通配符表示任意类型,但是必须有参数 可以使用..表示有无参数均可,有参数可以是任意类型 全通配写法: * *..*.*(..) 实际开发中切入点表达式的通常写法: 切到业务层实现类下的所有方法 * com.itheima.service.impl.*.*(..) --> <!-- 2.配置Logger类 --> <bean id="logger" class="com.itheima.utils.Logger"></bean> <!--3.配置AOP--> <aop:config> <!--配置切面 --> <aop:aspect id="logAdvice" ref="logger"> <!-- 配置通知的类型,并且建立通知方法和切入点方法的关联--> <aop:before method="printLog" pointcut="execution(* com.itheima.service.impl.*.*(..))"></aop:before> <!--用于配置前置通知。指定增强的方法在切入点方法之前执行 method:用于指定通知类中的增强方法名称 ponitcut-ref:用于指定切入点的表达式的引用 poinitcut:用于指定切入点表达式 --> </aop:aspect> <!--id:给切面提供一个唯一标志 ref:引用配置好的通知类bean的id--> </aop:config> </beans>
3.6测试
package com.itheima.test; import com.itheima.service.IAccountService; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class AOPTest { public static void main(String[] args){ //1.获取容器 ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml"); //2.获取对象 IAccountService as = (IAccountService) ac.getBean("accountService"); //3.执行方法 as.saveAccount(); as.updateAccount(1); as.deleteAccount(); } }