前言ioc和aop是spring中的两个核心的概念,简单介绍一下我的理解:
ioc:控制反转,就是将以前由我们自己手动创建对象的过程交给了spring,spring帮助我们生产对象、管理对象、管理对象和对象之间的依赖关系。降低了代码的耦合度,方便我们后期对项目做维护。举个通俗一点的例子:
正常情况下,我们在家,饿了,自己做饭。
使用ioc情况下,我们在家,饿了,打电话给商家,饭送过来。
ioc就相当于商家,做饭就相当于创建对象。
也就是说正常情况下,当一个类需要调用其他类的方法时,我们手动通过new、工厂或者其他方式创建对象。
使用ioc情况下,我们只需要注入对象即可。
aop:面向切面(方便)编程,可以对某一类对象进行监督和控制,在调用这类对象方法的前后去调用指定的代码,从而对一个方法进行扩展,从而达到增强模块功能的效果。举个通俗一点的例子:
正常情况下,直接吃饭。
使用aop情况下,有个保姆关注着,吃饭前帮忙洗手,吃饭后帮忙收拾碗筷。
aop就相当于保姆,吃饭就相当于带调用具体的方法。
也就是说,当我们想对方法进行补充时,并不去直接修改方法,而是通过aop去补充。当我们不想补充或者需要更换补充的时候,直接操作aop即可。
1、pointcut: 切点,用于定义哪个方法会被拦截,例如 execution(* cn.springcamp.springaop.service..(…))
2、advice: 拦截到方法后要执行的动作
3、aspect: 切面,把pointcut和advice组合在一起形成一个切面
4、join point: 在执行时pointcut的一个实例
4、weaver: 实现aop的框架,例如 aspectj 或 spring aop
一、springboot项目引入aop依赖<!--aop--> <dependency> <groupid>org.springframework.boot</groupid> <artifactid>spring-boot-starter-aop</artifactid> </dependency>
启动类加上@enableaspectjautoproxy注解,可以省略。因为在aop的默认配置属性中,spring.aop.auto属性默认是开启的。
也不需要再引入aspectj依赖了。
二、普通方式切面类代码:
package com.example.myblog.test;import org.aspectj.lang.joinpoint;import org.aspectj.lang.proceedingjoinpoint;import org.aspectj.lang.annotation.*;import org.springframework.stereotype.component;@component@aspectpublic class aoptest { //定义切入点 @pointcut("execution(public * com.example.myblog.test.aoptestclient.*(..))") public void aspecttest(){} //前置通知,切入点执行之前执行 @before("aspecttest()") public void dobefore(joinpoint joinpoint){ system.out.println("前置通知"); } //后置通知,切入点执行之后执行 @after("aspecttest()") public void doafter(joinpoint joinpoint){ system.out.println("后置通知"); } //最终通知,,切入点执行之后执行 @afterreturning("aspecttest()") public void doafterreturning(joinpoint joinpoint){ system.out.println("最终通知"); } //异常通知,切入点抛出异常执行 @afterthrowing("aspecttest()") public void deafterthrowing(joinpoint joinpoint){ system.out.println("异常通知"); } //环绕通知,切入点执行前、后执行 @around("aspecttest()") public object dearound(proceedingjoinpoint joinpoint) throws throwable{ system.out.println("未执行"); object result = joinpoint.proceed(); system.out.println("已执行"); //返回结果 return result; }}
切点类代码:
package com.example.myblog.test;import org.springframework.stereotype.component;@componentpublic class aoptestclient { public void test(){ system.out.println("正在测试aop"); }}
测试类代码:
package com.example.myblog;import com.example.myblog.test.*;import org.junit.test;import org.junit.runner.runwith;import org.springframework.beans.factory.annotation.autowired;import org.springframework.boot.test.context.springboottest;import org.springframework.test.context.junit4.springjunit4classrunner;@springboottest@runwith(springjunit4classrunner.class)public class myblogapplicationtests { @autowired private aoptestclient aoptestclient; @test public void testaop(){ aoptestclient.test(); }}
测试结果:
三、注解方式自定义注解代码:
package com.example.myblog.test;import java.lang.annotation.elementtype;import java.lang.annotation.retention;import java.lang.annotation.retentionpolicy;import java.lang.annotation.target;//表示次注解可以标注在类和方法上@target({elementtype.method, elementtype.type})//运行时生效@retention(retentionpolicy.runtime)public @interface myannotation { //定义一个变量,可以接受参数 string desc() default " ";}
切面类代码:
package com.example.myblog.test;import org.aspectj.lang.joinpoint;import org.aspectj.lang.proceedingjoinpoint;import org.aspectj.lang.annotation.*;import org.springframework.stereotype.component;@component@aspectpublic class aopannotationtest { //定义切入点 @pointcut("@annotation(com.example.myblog.test.myannotation)") public void aspecttest(){} //前置通知,切入点执行之前执行 @before("aspecttest()") public void dobefore(joinpoint joinpoint){ system.out.println("前置通知"); } //后置通知,切入点执行之后执行 @after("aspecttest()") public void doafter(joinpoint joinpoint){ system.out.println("后置通知"); } //最终通知,,切入点执行之后执行 @afterreturning("aspecttest()") public void doafterreturning(joinpoint joinpoint){ system.out.println("最终通知"); } //异常通知,切入点抛出异常执行 @afterthrowing("aspecttest()") public void deafterthrowing(joinpoint joinpoint){ system.out.println("异常通知"); } //环绕通知,切入点执行前、后执行 @around("aspecttest()") public object dearound(proceedingjoinpoint joinpoint) throws throwable{ system.out.println("未执行"); object result = joinpoint.proceed(); system.out.println("已执行"); //返回结果 return result; }}
切点类代码:
package com.example.myblog.test;import org.springframework.stereotype.component;@componentpublic class aopannotationtestclient { @myannotation public void test(){ system.out.println("正在测试aop"); }}
测试类代码:
@test public void testaopannotation(){ aopannotationtestclient.test(); }
测试结果:
以上就是springboot项目怎么使用aop的详细内容。
