面向切面编程,指导开发者如何组织程序结构
增强原始设计的功能
oop:面向对象编程
1.导入aop相关坐标,创建
<!--spring依赖-->
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.10.RELEASE</version>
</dependency>
<!--spring-text依赖-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.2.10.RELEASE</version>
</dependency>
<!-- 导入切入点表达式依赖-->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.4</version>
</dependency>
<!-- 导入junit依赖 测试单元-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
2.创建配置类进行Spring注解包扫描
package com.heima.config;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
//写入注解是spring的配置类
@Configuration
//扫描包
@ComponentScan("com.heima")
public class SpringConfig {
}
3.定义业务接口与实现类
jisaunqi
package com.heima.service;
public interface JiSuanQi {
// 加法
int add(int a, int b);
// 除法
int div(int a, int b);
}
jisuanqiimpl
package com.heima.service.impl;
import com.heima.service.JiSuanQi;
public class JiSuanQiImpl implements JiSuanQi {
@Override
public int add(int a, int b) {
int r = a + b;
return r;
}
@Override
public int div(int a, int b) {
int r = a / b;
return r;
}
}
生成
测试库
package com.heima.service.impl;
import com.heima.config.SpringConfig;
import com.heima.service.JiSuanQi;
import junit.framework.TestCase;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
//junit测试单元
//启动整合
@RunWith(SpringJUnit4ClassRunner.class)
//指定启动类
@ContextConfiguration(classes={SpringConfig.class})
public class JiSuanQiImplTest extends TestCase {
@Autowired
private JiSuanQi jiSuanQi;
@Test
public void testAdd() {
System.out.println(jiSuanQi.add(1, 2));
}
@Test
public void testDiv() {
System.out.println(jiSuanQi.div(4, 2));
}
}
运行测试
4.定义通知,制作通知方法
5.定义切入点表达式,配置切面
建立软件包
建立类
类中要写入注解被扫描,
通知方法有4种
1.前置通知
//1.前置通知
@Before("pt()")
public void before(JoinPoint joinPoint) {
System.out.println("参数为:"+ Arrays.toString(joinPoint.getArgs()));
System.out.println("我要开始计算了...");
}
2.后置通知
//2.后置通知
@After("pt()")
public void after() {
System.out.println("我结束计算了");
}
3.返回通知
//returning="返回结果对象"
@AfterReturning(value = "pt()",returning = "r")
public void afterReturning( Object r) {
System.out.println("结果为:"+r);
}
4.异常通知
//4.异常通知 捕获异常触发
@AfterThrowing(value = "pt()",throwing = "e")
public void afterThrowing(Throwable e) {
System.out.println("计算出现异常"+e.getMessage());
}
要在配置开启AOP功能
回到测试类里运行测试
MyAdivice
package com.heima.advice;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
import java.sql.Array;
import java.util.Arrays;
//通知类,写入注解
@Aspect
//被Spring容器扫描到,由于spring容器已写入扫描器
@Component
public class MyAdivice {
//切点表达式 你想在哪个方法上切入
//int是参数类型
//com.heima.service.impl.JiSuanQiImpl.add:找到add方法
//(int,int)两个参数 参数类型为int
@Pointcut("execution(int com.heima.service.impl.JiSuanQiImpl.add(int,int))")
public void pt() {}
//通知方法
//1.前置通知
@Before("pt()")
public void before(JoinPoint joinPoint) {
System.out.println("参数为:"+ Arrays.toString(joinPoint.getArgs()));
System.out.println("我要开始计算了...");
}
//2.后置通知
@After("pt()")
public void after() {
System.out.println("我结束计算了");
}
//3.返回通知 获取返回结果后触发
//returning="返回结果对象"
@AfterReturning(value = "pt()",returning = "r")
public void afterReturning( Object r) {
System.out.println("结果为:"+r);
}
//4.异常通知 捕获异常触发
@AfterThrowing(value = "pt()",throwing = "e")
public void afterThrowing(Throwable e) {
System.out.println("计算出现异常"+e.getMessage());
}
}
6.在配置类中开启aop功能
package com.heima.config;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
//写入注解是spring的配置类
@Configuration
//开启AOP功能
@EnableAspectJAutoProxy
//扫描包
@ComponentScan("com.heima")
public class SpringConfig {
}
简化
//@Pointcut("execution(int com.heima.service.impl.JiSuanQiImpl.add(int,int))")简化
//@Pointcut("execution(int com.heima.service.impl.JiSuanQiImpl.add(*,*))")返回类型可以是多个
//@Pointcut("execution(int com.heima.service.impl.JiSuanQiImpl.add(..))")返回类型可以是多个
//@Pointcut("execution(int com.heima.service.impl.JiSuanQiImpl.*(..))")这里*代表包里面所有方法都可以运行
//@Pointcut("execution(* com..impl.*.*(..))")代表意思为包的类型com包下面的所有包和方法
//@Pointcut("execution(* com..*.*(..))")简化结果