本文主要介紹spring aop中9種切入點表達式的寫法
成都創(chuàng)新互聯(lián)主要從事網(wǎng)站建設、網(wǎng)站制作、網(wǎng)頁設計、企業(yè)做網(wǎng)站、公司建網(wǎng)站等業(yè)務。立足成都服務安澤,十多年網(wǎng)站建設經(jīng)驗,價格優(yōu)惠、服務專業(yè),歡迎來電咨詢建站服務:028-86922220攔截任意公共方法
execution(public * *(..))
攔截以set開頭的任意方法
execution(* set*(..))
攔截類或者接口中的方法
execution(* com.xyz.service.AccountService.*(..))
攔截AccountService(類、接口)中定義的所有方法
攔截包中定義的方法,不包含子包中的方法
execution(* com.xyz.service.*.*(..))
攔截com.xyz.service包中所有類中任意方法,不包含子包中的類
攔截包或者子包中定義的方法
execution(* com.xyz.service..*.*(..))
攔截com.xyz.service包或者子包中定義的所有方法
表達式格式:包名. 或者 包名..
攔截包中任意方法,不包含子包中的方法
within(com.xyz.service.*)
攔截service包中任意類的任意方法
攔截包或者子包中定義的方法
within(com.xyz.service..*)
攔截service包及子包中任意類的任意方法
代理對象為指定的類型會被攔截
目標對象使用aop之后生成的代理對象必須是指定的類型才會被攔截,注意是目標對象被代理之后生成的代理對象和指定的類型匹配才會被攔截
this(com.xyz.service.AccountService)
示例
this表達式的使用,可能不是很好理解,用示例說明一下:<?xml version="1.0" encoding="UTF-8"?> <projectxmlns="http://maven.apache.org/POM/4.0." xmlns:xsi="http://www.w3.org/2001/XMLSchemainsance" 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> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.1.4.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.ms</groupId> <artifactId>spring-aop-demo </artifactId> <version>0.0.1-SNAPSHOT</version> <name>spring-aop-demo</name> <description>Demo project for Spring Boot</description>
package com.ms.aop.jthis.demo1;
public interface IService {
void m1();
}
package com.ms.aop.jthis.demo1;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
@Slf4j@Component
br/>@Component
br/>@Override
log.info("切入點this測試!");
}
}
package com.ms.aop.jthis.demo1;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;@Aspect
br/>@Aspect
br/>@Slf4j
@Pointcut("this(com.ms.aop.jthis.demo1.ServiceImpl)")
public void pointcut() {
}
@Around("pointcut()")
public Object invoke(ProceedingJoinPoint invocation) throws Throwable {
log.info("方法執(zhí)行之前");
Object result = invocation.proceed();
log.info("方法執(zhí)行完畢");
return result;
}
}
package com.ms.aop.jthis.demo1;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
@ComponentScan(basePackageClasses = {Client.class})@EnableAspectJAutoProxy
br/>@EnableAspectJAutoProxy
public class Client {
public static void main(String[] args) {
AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(Client.class);
IService service = annotationConfigApplicationContext.getBean(IService.class);
service.m1();
log.info("{}", service instanceof ServiceImpl);
}
}
**執(zhí)行結果**
10:27:12.277 [main] INFO com.ms.aop.jthis.demo1.ServiceImpl - 切入點this測試!
10:27:12.277 [main] INFO com.ms.aop.jthis.demo1.Client - false
1. **@EnableAspectJAutoProxy**:表示若spring創(chuàng)建的對象如果實現(xiàn)了接口,默認使用jdk動態(tài)代理,如果沒有實現(xiàn)接口,使用cglib創(chuàng)建代理對象
2. 所以 **service** 是使用jdk動態(tài)代理生成的對象,**service instanceof ServiceImpl** 為 **false**
3. **@Pointcut("this(com.ms.aop.jthis.demo1.ServiceImpl)")**表示被spring代理之后生成的對象必須為**com.ms.aop.jthis.demo1.ServiceImpl**才會被攔截,但是**service**不是**ServiceImpl**類型的對象了,所以不會被攔截
4. 修改代碼**@EnableAspectJAutoProxy(proxyTargetClass=true)**,使用cglib來生成代理對象
**執(zhí)行結果:**
10:34:50.736[main]INFO com.ms.aop.jthis.demo1.Interceptor1-方法執(zhí)行之前
10:34:50.755[main]INFO com.ms.aop.jthis.demo1.ServiceImpl-切入點this測試!
10:34:50.756[main]INFO com.ms.aop.jthis.demo1.Interceptor1-方法執(zhí)行完畢
10:34:50.756[main]INFO com.ms.aop.jthis.demo1.Client-true
> service 為 ServiceImpl類型的對象,所以會被攔截
### **4、target表達式**
目標對象為指定的類型被攔截
target(com.xyz.service.AccountService)
> 目標對象為AccountService類型的會被代理
**示例**
package com.ms.aop.target;
public interface IService {
void m1();}
package com.ms.aop.target;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
@Slf4j@Component
br/>@Component
br/>@Override
log.info("切入點target測試!");
}
}
package com.ms.aop.target;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
@Aspect@Component
br/>@Component
public class Interceptor1 {
@Pointcut("target(com.ms.aop.target.ServiceImpl)")
public void pointcut() {
}
@Around("pointcut()")
public Object invoke(ProceedingJoinPoint invocation) throws Throwable {
log.info("方法執(zhí)行之前");
Object result = invocation.proceed();
log.info("方法執(zhí)行完畢");
return result;
}
}
package com.ms.aop.target;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
@ComponentScan(basePackageClasses = {Client.class})@EnableAspectJAutoProxy
br/>@EnableAspectJAutoProxy
public static void main(String[] args) {
AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(Client.class);
IService service = annotationConfigApplicationContext.getBean(IService.class);
service.m1();
}
}
**執(zhí)行結果:**
10:49:01.674 [main] INFO com.ms.aop.targetInterceptor1 - 方法執(zhí)行之前
10:49:01.674 [main] INFO com.ms.aop.target.ServiceImpl - 切入點target測試!
10:49:01.674 [main] INFO com.ms.aop.target.Interceptor1 - 方法執(zhí)行完畢
**this 和 target 的不同點**
1. **this作用于代理對象,target作用于目標對象**
2. **this表示目標對象被代理之后生成的代理對象和指定的類型匹配會被攔截**,匹配的是代理對象
3. **target表示目標對象和指定的類型匹配會被攔截**,匹配的是目標對象
### **5、args 表達式**
匹配方法中的參數(shù)
@Pointcut("args(com.ms.aop.args.demo1.UserModel)")
> 匹配只有一個參數(shù),且類型為**com.ms.aop.args.demo1.UserModel**
匹配多個參數(shù)
args(type1,type2,typeN)
匹配任意多個參數(shù)
@Pointcut("args(com.ms.aop.args.demo1.UserModel,..)")
匹配第一個參數(shù)類型為**com.ms.aop.args.demo1.UserModel**的所有方法, .. 表示任意個參數(shù)
### **6、@target表達式**
匹配的目標對象的類有一個指定的注解
@target(com.ms.aop.jtarget.Annotation1)
> 目標對象中包含**com.ms.aop.jtarget.Annotation1**注解,調用該目標對象的任意方法都會被攔截
### **7、@within表達式**
指定匹配必須包含某個注解的
@within(com.ms.aop.jwithin.Annotation1)
> 聲明有**com.ms.aop.jwithin.Annotation1**注解的類中的所有方法都會被攔截
##### **@target 和 @within 的不同點**
1. **@target(注解A)**:判斷被**調用的目標對象**中是否聲明了注解A,如果有,會被攔截
2. **@within(注解A)**: 判斷被**調用的方法所屬的類**中是否聲明了注解A,如果有,會被攔截
@target關注的是被調用的對象,@within關注的是調用的方法所在的類
### **8、@annotation表達式**
匹配有指定注解的方法(注解作用在方法上面)
@annotation(com.ms.aop.jannotation.demo2.Annotation1)
> 被調用的方法包含指定的注解
### **9、@args表達式**
方法參數(shù)所屬的類型上有指定的注解,被匹配
> 注意:是**方法參數(shù)所屬的類型**上有指定的注解,不是方法參數(shù)中有注解
- 匹配1個參數(shù),且第1個參數(shù)所屬的類中有Anno1注解
@args(com.ms.aop.jargs.demo1.Anno1)
- 匹配多個參數(shù),且多個參數(shù)所屬的類型上都有指定的注解
@args(com.ms.aop.jargs.demo1.Anno1,com.ms.aop.jargs.demo1.Anno2)
- 匹配多個參數(shù),且第一個參數(shù)所屬的類中有Anno1注解
@args(com.ms.aop.jargs.demo2.Anno1,..)
另外有需要云服務器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內外云服務器15元起步,三天無理由+7*72小時售后在線,公司持有idc許可證,提供“云服務器、裸金屬服務器、高防服務器、香港服務器、美國服務器、虛擬主機、免備案服務器”等云主機租用服務以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡單易用、服務可用性高、性價比高”等特點與優(yōu)勢,專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應用場景需求。