先说说这篇文章看完你能学习到什么吧
1:你可以知道为什么我会用这个,2:你能从中学习到aop的使用。
1:为什么我会使用这个框架
a:安全和不想掰扯别人的代码,为什么我会这么说呢?首先有的项目其实已经完成了或者代码在别人的模块。你自己不好改动他的部分,但是需要你动手添加后续的需求或者完善他的代码。你怕出问题,这时候aop就可以上场,他会帮你解决这个问题。
2:那怎么快速入手属于自己的spring-aop呢(或者说怎么在自己项目调用spring-aop这个框架呢)
1:环境(自己去建一个maven项目)
【jdk8】,【maven3.5】,【intellj idea2018】
2:导入spring-aop框架包(pom.xml)
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
<version>3.2.2</version>
</dependency>
</dependencies>
3:编撰项目启动类(spring-boot)
@SpringBootApplication
public class MainRunApplication {
public static void main(String args[]){
new SpringApplication(MainRunApplication.class).run();
}
}
4:spring-aop主要的五个注解
@Before(方法前置处理),@After(方法后置处理),@Around(方法环绕处理),@AfterReturning(方法返回值处理),@AfterThrowing(异常后续处理)
5:spring-aop之@Before
a:编撰被切入的类,并添加匹配@Before规则的方法
@Component
public class MainTest {
public Map<Integer,Integer> before(String input){
System.out.println("这是匹配到aop@Before切面规则的方法");
return null;
}
}
b:编写切面类Aspect并添加@Before注解的方法
@Aspect
@Component
public class RoutingAspect {
@Before(value = "execution(* *..before(String))")
public void aopBefore(JoinPoint joinPoint){
System.out.println(joinPoint.getArgs()[0]);
}
}
c:编写启动测试
@SpringBootApplication
public class MainRunApplication {
public static void main(String args[]){
ConfigurableApplicationContext run = new SpringApplication(MainRunApplication.class).run();
MainTest mainTest = run.getBeanFactory().getBean("mainTest",MainTest.class);
mainTest.before("这是前置@Before监听方法的参数");
}
}
6:spring-aop之@After
a:编撰被切入的类,并添加匹配@After规则的方法
@Component
public class MainTest {
public Map<Integer,Integer> before(String input){
System.out.println("这是匹配到aop@Before切面规则的方法");
return null;
}
public Map<Integer,Integer> after(Map<Integer,Integer> output){
System.out.println("这是匹配到aop@After切面规则的方法");
return output;
}
}
b:编写切面类Aspect并添加@After注解的方法
@Aspect
@Component
public class RoutingAspect {
@Before(value = "execution(* *..before(String))")
public void aopBefore(JoinPoint joinPoint){
System.out.println(joinPoint.getArgs()[0]);
}
@After(value = "execution(* *..after(java.util.Map)) && args(output)",argNames = "output")
public void aopBefore(Map<Integer,Integer> output){
System.out.println("修改了传进来的参数,原始长度为"+output.size());
output.put(1,1);
}
}
c:编写启动测试
@SpringBootApplication
public class MainRunApplication {
public static void main(String args[]){
ConfigurableApplicationContext run = new SpringApplication(MainRunApplication.class).run();
MainTest mainTest = run.getBeanFactory().getBean("mainTest",MainTest.class);
mainTest.before("这是前置@Before监听方法的参数");
Map<Integer, Integer> after = mainTest.after(new HashMap<>());
System.out.println("@After修改了传进来的参数,后续长度为"+after.size());
}
}
7:spring-aop之@AfterReturning
a:编撰被切入的类,并添加匹配@AfterReturning规则的方法
@Component
public class MainTest {
public Map<Integer,Integer> before(String input){
System.out.println("这是匹配到aop@Before切面规则的方法");
return null;
}
public Map<Integer,Integer> after(Map<Integer,Integer> output){
System.out.println("这是匹配到aop@After切面规则的方法");
return output;
}
public Map<Integer,Integer> afterReturn(Map<Integer,Integer> output){
System.out.println("这是匹配到aop@AfterReturn切面规则的方法");
return output;
}
}
b:编写切面类Aspect并添加@AfterReturning注解的方法
@Aspect
@Component
public class RoutingAspect {
@AfterReturning(value = "execution(* *..afterReturn(java.util.Map))",returning = "output")
public void aopAfterReturning(JoinPoint joinPoint, Map<Integer,Integer> output){
output.put(1,3);
System.out.println("@AfterReturning修改了返回值" + output.size());
}
@Before(value = "execution(* *..before(String))")
public void aopBefore(JoinPoint joinPoint){
System.out.println(joinPoint.getArgs()[0]);
}
@After(value = "execution(* *..after(java.util.Map)) && args(output)",argNames = "output")
public void aopBefore(Map<Integer,Integer> output){
System.out.println("修改了传进来的参数,原始长度为"+output.size());
output.put(1,1);
}
}
c:编写启动测试
@SpringBootApplication
public class MainRunApplication {
public static void main(String args[]){
ConfigurableApplicationContext run = new SpringApplication(MainRunApplication.class).run();
MainTest mainTest = run.getBeanFactory().getBean("mainTest",MainTest.class);
mainTest.before("这是前置@Before监听方法的参数");
Map<Integer, Integer> after = mainTest.after(new HashMap<>());
System.out.println("@After修改了传进来的参数,后续长度为"+after.size());
Map<Integer, Integer> afterReturn = mainTest.afterReturn(new HashMap<>());
}
}
8:spring-aop之@Around
a:编撰被切入的类,并添加匹配@Around规则的方法
@Component
public class MainTest {
public Map<Integer,Integer> before(String input){
System.out.println("这是匹配到aop@Before切面规则的方法");
return null;
}
public Map<Integer,Integer> after(Map<Integer,Integer> output){
System.out.println("这是匹配到aop@After切面规则的方法");
return output;
}
public Map<Integer,Integer> afterReturn(Map<Integer,Integer> output){
System.out.println("这是匹配到aop@AfterReturn切面规则的方法");
return output;
}
@RoutingWith(value = "mama")
public void around(){
System.out.println("这是匹配到aop@Around切面规则的方法");
}
}
b:编写切面类Aspect并添加@AfterReturning注解的方法
@Aspect
@Component
public class RoutingAspect {
@Around("@annotation(routingWith)")
public Object routingWithDataSource(ProceedingJoinPoint proceedingJoinPoint, RoutingWith routingWith) throws Throwable{
String key = routingWith.value();
System.out.println(key);
return proceedingJoinPoint.proceed();
}
@AfterReturning(value = "execution(* *..afterReturn(java.util.Map))",returning = "output")
public void aopAfterReturning(JoinPoint joinPoint, Map<Integer,Integer> output){
output.put(1,3);
System.out.println("@AfterReturning修改了返回值" + output.size());
}
@Before(value = "execution(* *..before(String))")
public void aopBefore(JoinPoint joinPoint){
System.out.println(joinPoint.getArgs()[0]);
}
@After(value = "execution(* *..after(java.util.Map)) && args(output)",argNames = "output")
public void aopBefore(Map<Integer,Integer> output){
System.out.println("修改了传进来的参数,原始长度为"+output.size());
output.put(1,1);
}
}
c:编写启动测试
@SpringBootApplication
public class MainRunApplication {
public static void main(String args[]){
ConfigurableApplicationContext run = new SpringApplication(MainRunApplication.class).run();
MainTest mainTest = run.getBeanFactory().getBean("mainTest",MainTest.class);
mainTest.before("这是前置@Before监听方法的参数");
Map<Integer, Integer> after = mainTest.after(new HashMap<>());
System.out.println("@After修改了传进来的参数,后续长度为"+after.size());
Map<Integer, Integer> afterReturn = mainTest.afterReturn(new HashMap<>());
mainTest.around();
}
}
3:敲黑板
1:为什么第一步为什么要再pom.xmlj加入那个包?
答:因为想要使用spring-aop,必须先导入他的框架包,才能使用
2:为什么导入的是spring-boot-starter-aop
答:因为导入这个可以直接使用spring-boot,而不需要重复再导入spring-boot的包,这里说下spring-boot-starter这个合集开头是啥意思--------spring boot本来就是可以开箱即用的全家桶框架集合,他们通过约定俗成的方式介入到spring boot,并把自己命名成spring-boot-starter这样子开头的名,开发者只要导入相关的spring-boot-starter的就可以用他们的框架,例如spring-boot-starter-aop,这里有aspectj的包,也有spring-aop,也有spring-boot-starter,这样我们只要导入一个这样的包就可以使用spring boot的模块
3:spring-boot项目启动类的@SpringBootApplication是有啥用
答:这个标明了这个类是spring-boot 的入口启动类,并且里面有集成EnableAutoConfiguration,ComponentScan,Configuration等注解,方便好用,而且想要使用spring-boot启动,只要再加个
public static void main(String args[]){
new SpringApplication(MainRunApplication.class).run();
}
就可以用了
4:以下代码是获取一个bean为mainTest的方法吗,那我用@Autowired也可以注入吧
ConfigurableApplicationContext run = new SpringApplication(MainRunApplication.class).run();
MainTest mainTest = run.getBeanFactory().getBean("mainTest",MainTest.class);
答:没错的,这个方法相当于@Autowired注入,只是这个是手动获取bean的IOC容器,也就是我们说的控制反转容器,这个容器管理了一大堆扫描到的bean,并在需要的时候(使用@Bean或者@Component等自动注入)
5:@Before(方法前置处理),@After(方法后置处理),@Around(方法环绕处理),@AfterReturning(方法返回值处理),@AfterThrowing(异常后续处理)这四个方法啥意思
答:简单来说就说在对象调用被切面的方法之前,之后,以及方法前后(环绕)进行相应的切面处理,环绕比较简单,就是可以自由处理方法,决定方法要不要调用,以及传参的处理,返回值的处理,AfterReturning是对返回值的处理,Around这个还可以对有相应注解的方法进行切片处理。这种一般用在ORM和日志等需要开启事务等开关上有用到。
6:spring-aop是aop,相对于oop?
答:没错,我们熟悉的oop是面向对象编程,aop就是面向切面编程,也就是Aspect