这是第一次在公众号中写技术文章,本人也一直从事于java近10年,所以公众号中主要是分享一些java相关的技术,目前先列一下后期的主要内容,如果喜欢,请关注一下:
1、手把手教你写java爬虫,使用爬虫爬取几个比较热门的电影网站、极客时间中的资源
2、使用springboot手写可靠的异步消息服务,对业务系统进行解耦
3、手写tcc分布式事务处理框架,并讲解其原理
4、使用springboot手写分布式调度服务
5、业务系统中分库分表的使用
https://gitee.com/likun_557/spring-aop-demo
execution(public * *(..))
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"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
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>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
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
public class ServiceImpl implements IService {
@Override
public void m1() {
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
@Component
@Slf4j
public class Interceptor1 {
@Pointcut("this(com.ms.aop.jthis.demo1.ServiceImpl)")
public void pointcut() {
}
@Around("pointcut()")
public Object invoke(ProceedingJoinPoint invocation) throws Throwable {
log.info("方法执行之前");
Object result = invocation.proceed();
log.info("方法执行完毕");
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
@Slf4j
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);
}
}
执行结果
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
执行结果:
10:34:50.736[main]INFO com.ms.aop.jthis.demo1.Interceptor1-方法执行之前
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-方法执行完毕
10:34:50.756[main]INFO com.ms.aop.jthis.demo1.Client-true
service 为 ServiceImpl类型的对象,所以会被拦截
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
public class ServiceImpl implements IService {
@Override
public void m1() {
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
@Slf4j
public class Interceptor1 {
@Pointcut("target(com.ms.aop.target.ServiceImpl)")
public void pointcut() {
}
@Around("pointcut()")
public Object invoke(ProceedingJoinPoint invocation) throws Throwable {
log.info("方法执行之前");
Object result = invocation.proceed();
log.info("方法执行完毕");
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
public class Client {
public static void main(String[] args) {
AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(Client.class);
IService service = annotationConfigApplicationContext.getBean(IService.class);
service.m1();
}
}
执行结果:
10:49:01.674 [main] INFO com.ms.aop.target.Interceptor1 - 方法执行之前
10:49:01.674 [main] INFO com.ms.aop.target.ServiceImpl - 切入点target测试!
10:49:01.674 [main] INFO com.ms.aop.target.Interceptor1 - 方法执行完毕
@Pointcut("args(com.ms.aop.args.demo1.UserModel)")
匹配只有一个参数,且类型为com.ms.aop.args.demo1.UserModel
args(type1,type2,typeN)
@Pointcut("args(com.ms.aop.args.demo1.UserModel,..)")
匹配第一个参数类型为com.ms.aop.args.demo1.UserModel的所有方法,
..
表示任意个参数
@target(com.ms.aop.jtarget.Annotation1)
目标对象中包含com.ms.aop.jtarget.Annotation1注解,调用该目标对象的任意方法都会被拦截
@within(com.ms.aop.jwithin.Annotation1)
声明有com.ms.aop.jwithin.Annotation1注解的类中的所有方法都会被拦截
@annotation(com.ms.aop.jannotation.demo2.Annotation1)
被调用的方法包含指定的注解
注意:是方法参数所属的类型上有指定的注解,不是方法参数中有注解
@args(com.ms.aop.jargs.demo1.Anno1)
@args(com.ms.aop.jargs.demo1.Anno1,com.ms.aop.jargs.demo1.Anno2)
@args(com.ms.aop.jargs.demo2.Anno1,..)