javascript
SpringBoot 使用AOP功能
RPC,AOP都會用到代理,代理的技術有jdk的Proxy代理(必須實現接口),cglib(可以不實現接口,直接實現類),Javassist(jboss )而Spring boot本身也在方方面面使用了代理技術,在Spring中有兩種動態代理方式,分別為jdk動態代理和CGLIB動態代理。
下面主要講述,springboot如何使用AOP功能
1.POM文件中添加依賴
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId> </dependency>2.在application.properties中加入配置
spring.aop.auto=truePS:其實springboot此配置是默認開啟的,所以根本可以不用管了,在Springboot中使用過注解配置方式的人會問是否需要在程序主類中增加@EnableAspectJAutoProxy來啟用,實際并不需要。看下面關于AOP的默認配置屬性,其中spring.aop.auto屬性默認是開啟的,也就是說只要引入了AOP依賴后,其實默認已經增加了@EnableAspectJAutoProxy。
# AOP spring.aop.auto=true # Add @EnableAspectJAutoProxy. spring.aop.proxy-target-class=false # Whether subclass-based (CGLIB) proxies are to be created (true) 此處是設置是否開啟CGLIB代理,默認不開啟,相當于spring xml中 <aop:aspectj-autoproxy proxy-target-class="true"/>, 不過后面會有點奇怪的問題,springboot中,不管這個項是否設置為true或者false,都不會跟以前spring項目中, 如果沒有設置為true,當代理類沒有繼承接口,啟動項目的時候會報錯。而springboot項目中,會自動轉換成使用 CGLIB進行動態代理,其中原理是怎么實現,就沒有去看底層代碼了,估計底層進行了改造吧!3.利用注解方式,實現AOP實現類。
import java.util.Arrays;import javax.servlet.http.HttpServletRequest;import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.AfterReturning; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.aspectj.lang.annotation.Pointcut; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes;@Aspect @Component public class WebLogAspect {private Logger logger = LoggerFactory.getLogger(WebLogAspect.class);@Pointcut("execution(public * com.springboot.test.controller.*.*(..))")public void webLog(){System.out.println("begin");}@Before("webLog()")public void doBefore(JoinPoint joinPoint) throws Throwable {// 接收到請求,記錄請求內容ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();HttpServletRequest request = attributes.getRequest();// 記錄下請求內容logger.info("URL : " + request.getRequestURL().toString());logger.info("HTTP_METHOD : " + request.getMethod());logger.info("IP : " + request.getRemoteAddr());logger.info("CLASS_METHOD : " + joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName());logger.info("ARGS : " + Arrays.toString(joinPoint.getArgs()));}@AfterReturning(returning = "ret", pointcut = "webLog()")public void doAfterReturning(Object ret) throws Throwable {// 處理完請求,返回內容logger.info("RESPONSE : " + ret);}}測試:
情況1:spring.aop.proxy-target-class=false,實現類沒有繼承接口。
上圖可以說明使用了CGLIB動態代理。這里就可以看出,spring.aop.proxy-target-class好像并沒有其效果,這個我都沒有去深究了。有誰知道的,請留言一下咯!
情況2:spring.aop.proxy-target-class=false,實現類繼承了接口。
上圖可以看出使用了jdk動態代理!
情況3:spring.aop.proxy-target-class=true,實現類繼承了接口。
上圖可以看出使用了CGLIB動態代理。這里就可以看出,spring.aop.proxy-target-class起效果了。
結論:就是不太清楚情況一,為什么不會報錯,知道的牛人,可以留言喔!
總結
以上是生活随笔為你收集整理的SpringBoot 使用AOP功能的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python精要(65)-类(2)-构造
- 下一篇: 程序员法律考试(7)-民法(4)