Spring高级注解-Day3

《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》点击传送门,即可获取!

}

}

EfficiencyUtils.java

  • 也可以在类上加@Order(数值) 自己配置执行顺序,数字越小越先执行

4.3 用于配置切入点表达式的

4.3.1 @Pointcut
4.3.1.1 作用
  • 此注解是用于指定切入点表达式的。
4.3.1.2 属性
  • value:用于指定切入点表达式。
4.3.1.3 基本使用

@Component

//表明当前类是一个切面类

@Aspect

public class LogUtil {

//用于定义通用的切入点表达式

@Pointcut(value = “execution(* com.example.service.impl..(…)) && args(user)”,argNames = “user”)

private void pointcut1(User user){

}

//用于配置当前方法是一个前置通知

@Before(value = “pointcut1(user)”,argNames = “user”)

public void printLog(User user){

System.out.println(“打印日志” + user);

}

}

LogUtil.java

4.4 用于配置通知的

4.4.1 @Before
4.4.1.1 作用
  • 被此注解修饰的方法为前置通知。前置通知的执行时间点是在切入点方法执行之前。
4.4.1.2 属性
  • value:用于指定切入点表达式。可以是表达式,也可以是表达式的引用。

  • argNames:用于指定切入点表达式参数的名称。它要求和切入点表达式中的参数名称一致。通常不指定也可以获取切入点方法的参数内容。

4.4.2 @AfterReturning
4.4.2.1 作用
  • 用于配置后置通知。后置通知的执行是在切入点方法正常执行之后执行。

需要注意的是,由于基于注解的配置时,spring创建通知方法的拦截器链时,后置

通知在最终通知之后,所以会先执行@After注解修饰的方法。

4.4.2.2 属性
  • value:用于指定切入点表达式,可以是表达式,也可以是表达式的引用。

  • pointcut:它的作用和value是一样的。

  • returning:指定切入点方法返回值的变量名称。它必须和切入点方法返回值名称一致。

  • argNames:用于指定切入点表达式参数的名称。它要求和切入点表达式中的参数名称一致。通常不指定也可以获取切入点方法的参数内容。

4.4.3 @AfterThrowing
4.4.3.1 作用
  • 用于配置异常通知。
4.4.3.2 属性
  • value:用于指定切入点表达式,可以是表达式,也可以是表达式的引用。

  • pointcut:它的作用和value是一样的。

  • throwing:指定切入点方法执行产生异常时的异常对象变量名称。它必须和异常变量名称一致。

  • argNames:用于指定切入点表达式参数的名称。它要求和切入点表达式中的参数名称一致。通常不指定也可以获取切入点方法的参数内容。

4.4.4 @After
4.4.4.1 作用
  • 用于指定最终通知。
4.4.4.2 属性
  • value:用于指定切入点表达式,可以是表达式,也可以是表达式的引用。

  • argNames:用于指定切入点表达式参数的名称。它要求和切入点表达式中的参数名称 一致。通常不指定也可以获取切入点方法的参数内容。

4.4.5 基本使用

@Component

//表明当前类是一个切面类

@Aspect

public class LogUtil {

//用于配置当前方法是一个前置通知

@Before(“execution(* com.example.service.impl..(…))”)

public void beforePrintLog(){

System.out.println(“前置通知打印日志”);

}

//用于配置当前方法是一个最终通知

@After(“execution(* com.example.service.impl..(…))”)

public void afterPrintLog(){

System.out.println(“最终通知打印日志”);

}

//用于配置当前方法是一个后置通知

@AfterReturning(“execution(* com.example.service.impl..(…))”)

public void afterReturningPrintLog(){

System.out.println(“后置通知日志”);

}

//用于配置当前方法是一个异常通知

@AfterThrowing(“execution(* com.example.service.impl..(…))”)

public void afterThrowingPrintLog(){

System.out.println(“异常通知打印日志”);

}

}

LogUtil.java

  • 执行顺序

前置通知打印日志

保存用户User{id=1, username=‘zs’, password=‘123’, birthday=Sat Jul 24 16:02:21 CST 2021}

后置通知日志

最终通知打印日志

4.4.6 一个切面内相同类型通知的执行顺序

@Component

//表明当前类是一个切面类

@Aspect

public class LogUtil {

//用于配置当前方法是一个前置通知

@Before(“execution(* com.example.service.impl..(…))”)

public void before2PrintLog(){

System.out.println(“前置通知2打印日志”);

}

//用于配置当前方法是一个前置通知

@Before(“execution(* com.example.service.impl..(…))”)

public void before1PrintLog(){

System.out.println(“前置通知1打印日志”);

}

}

  • 最终执行顺序

前置通知1打印日志

前置通知2打印日志

保存用户User{id=1, username=‘zs’, password=‘123’, birthday=Sat Jul 24 16:20:17 CST 2021}

  • 一个切面内相同类型通知的执行顺序与声明顺序无关

  • 一个切面内相同类型通知的执行顺序由方法名中每个字符的ASCII码顺序决定

  • 个切面内相同类型通知的执行顺序不能用@Order进行控制

4.4.7 @Around
4.4.7.1 作用
  • 用于指定环绕通知。
4.4.7.2 属性
  • value:用于指定切入点表达式,可以是表达式,也可以是表达式的引用。

  • argNames:用于指定切入点表达式参数的名称。它要求和切入点表达式中的参数名称一致。通常不指定也可以获取切入点方法的参数内容。

4.4.7.3 基本使用

public interface UserService {

@Description(“保存”)

void saveUser(User user);

@Description(“查找”)

User findById(String id);

@Description(“更新”)

void update(User user);

@Description(“删除”)

void delete(String id);

}

UserService.java

/**

  • 系统日志的实体类

*/

public class SystemLog implements Serializable {

//主键

private String id;

//方法名称

private String method;

//方法说明

private String action;

//时间

private Date time;

//来访者名称

private String remoteIp;

@Override

public String toString() {

return “SystemLog{” +

“id='” + id + ‘’’ +

“, method='” + method + ‘’’ +

“, action='” + action + ‘’’ +

“, time=” + time +

“, remoteIp='” + remoteIp + ‘’’ +

‘}’;

}

public String getId() {

return id;

}

public void setId(String id) {

this.id = id;

}

public String getMethod() {

return method;

}

public void setMethod(String method) {

this.method = method;

}

public String getAction() {

return action;

}

public void setAction(String action) {

this.action = action;

}

public Date getTime() {

return time;

}

public void setTime(Date time) {

this.time = time;

}

public String getRemoteIp() {

return remoteIp;

}

public void setRemoteIp(String remoteIp) {

this.remoteIp = remoteIp;

}

}

SystemLog.java

@Component

//表明当前类是一个切面类

@Aspect

public class LogUtil {

/**

  • 用于增强业务层方法,在其执行时记录系统日志

  • @return

*/

@Around(“execution(* com.example.service.impl..(…))”)

public Object aroundPrintLog(ProceedingJoinPoint pjp){

Object rtValue = null;

//创建系统日志对象

SystemLog log = new SystemLog();

try {

log.setId(UUID.randomUUID().toString());

log.setRemoteIp(“127.0.0.1”);

log.setTime(new Date());

//使用ProceedingJoinPoint中的获取签名方法

Signature signature = pjp.getSignature();

//判断当前的签名是否是方法签名

if(signature instanceof MethodSignature){

//把签名转换成方法签名

MethodSignature methodSignature = (MethodSignature) signature;

//获取当前执行的方法

Method method = methodSignature.getMethod();

log.setMethod(method.getName());

//判断当前方法上是否有@Description注解

boolean isAnnotated = method.isAnnotationPresent(Description.class);

if(isAnnotated){

//得到当前方法上的@Description

Description description = method.getAnnotation(Description.class);

//得到注解的value属性

String value = description.value();

log.setAction(value);

}

}

System.out.println(“环绕通知” + log);

Object[] args = pjp.getArgs();

//切入点方法执行

rtValue = pjp.proceed(args);

} catch (Throwable throwable) {

throwable.printStackTrace();

}

return rtValue;

}

}

LogUtil.java

4.5 用于扩展目标类的

4.5.1 @DeclareParents
4.5.1.1 作用
  • 用于给被增强的类提供新的方法。(实现新的接口)
4.5.1.2 属性
  • value:指定目标类型的表达式。当在全限定类名后面跟上+时,表示当前类及其子类

  • defaultImpl:指定提供方法或者字段的默认实现类。

4.5.1.3 基本使用

@Component

//表明当前类是一个切面类

@Aspect

public class LogUtil {

//让目标类具备当前声明接口中的方法,动态代理

@DeclareParents(value = “com.example.service.UserService+”,defaultImpl = ValidateExtensionServiceImpl.class)

private ValidateExtensionService validateExtensionService;

//用于配置当前方法是一个前置通知

@Before(“execution(* com.example.service.impl..(…))”)

public void printLog(){

System.out.println(“打印日志”);

}

}

LogUtil.java

@Component

public class ValidateExtensionServiceImpl implements ValidateExtensionService {

@Override

public boolean checkUser(User user) {

//校验不通过

if(user.getUsername().contains(“zs”)){

return false;

}

return true;

}

}

ValidateExtensionServiceImpl.java

public class SpringDeclareParentsTest {

public static void main(String[] args) {

AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(“config”);

UserService userService = ac.getBean(“userService”, UserService.class);

User user = new User();

user.setId(1);

user.setUsername(“ls”);

user.setPassword(“123”);

user.setBirthday(new Date());

//验证用户昵称

//把UserService看作ValidateExtensionService

ValidateExtensionService validateExtensionService = (ValidateExtensionService) userService;

boolean checkUser = validateExtensionService.checkUser(user);

if(checkUser){

userService.saveUser(user);

}

}

}

SpringDeclareParentsTest.java

4.5.2 @EnableLoadTimeWeaving
4.5.2.1 作用
  • 用于切换不同场景下实现增强。
4.5.2.2 属性
  • aspectjWeaving:是否开启LTW的支持。

ENABLED 开启LTW

DISABLED 不开启LTW

AUTODETECT 如果类路径下能读取到META‐INF/aop.xml文件,则开启LTW,否则关闭

5 切入点表达式


5.1 切入点表达式概念及作用

  • 概念:指的是遵循特定的语法用于捕获每一个种类的可使用连接点的语法。

  • 作用: 用于对符合语法格式的连接点进行增强。

5.2 按照用途分类

  • 主要的种类:

方法执行:execution(MethodSignature)

方法调用:call(MethodSignature)

构造器执行:execution(ConstructorSignature)

构造器调用:call(ConstructorSignature)

类初始化:staticinitialization(TypeSignature)

属性读操作:get(FieldSignature)

属性写操作:set(FieldSignature)

例外处理执行:handler(TypeSignature)

对象初始化:initialization(ConstructorSignature)

对象预先初始化:preinitialization(ConstructorSignature)

5.3 切入点表达式的关键字

  • 支持的AspectJ切入点指示符如下:

execution:用于匹配方法执行的连接点;

within:用于匹配指定类型内的方法执行;

this:用于匹配当前AOP代理对象类型的执行方法;注意是AOP代理对象的类型匹配,这样就可能包括引入接口也类型匹配;

target:用于匹配当前目标对象类型的执行方法;注意是目标对象的类型匹配,这样就不包括引入接口也类型匹配;

args:用于匹配当前执行的方法传入的参数为指定类型的执行方法;

@within:用于匹配所以持有指定注解类型内的方法;

@target:用于匹配当前目标对象类型的执行方法,其中目标对象持有指定的注解;

@args:用于匹配当前执行的方法传入的参数持有指定注解的执行;

@annotation:用于匹配当前执行方法持有指定注解的方法;

bean:Spring AOP扩展的,AspectJ没有对于指示符,用于匹配特定名称的Bean对象的执行方法;

reference pointcut:表示引用其他命名切入点,只有@ApectJ风格支持,Schema风格不支持。

5.4 切入点表达式的通配符

  • AspectJ类型匹配的通配符:

_:匹配任何数量字符;

…:匹配任何数量字符的重复,如在类型模式中匹配任何数量子包;而在方法参数模式中匹配任何数量参数。

+:匹配指定类型的子类型;仅能作为后缀放在类型模式后边。

说明:

java.lang.String 匹配String类型;

java._.String 匹配java包下的任何“一级子包”下的String类型;

如匹配java.lang.String,但不匹配java.lang.ss.String

java…* 匹配java包及任何子包下的任何类型;

如匹配java.lang.String、java.lang.annotation.Annotation

java.lang.*ing 匹配任何java.lang包下的以ing结尾的类型;

java.lang.Number+ 匹配java.lang包下的任何Number的自类型;

如匹配java.lang.Integer,也匹配java.math.BigInteger

5.5 切入点表达式的逻辑条件

  • && and
  • || or

最后

即使是面试跳槽,那也是一个学习的过程。只有全面的复习,才能让我们更好的充实自己,武装自己,为自己的面试之路不再坎坷!今天就给大家分享一个Github上全面的Java面试题大全,就是这份面试大全助我拿下大厂Offer,月薪提至30K!

我也是第一时间分享出来给大家,希望可以帮助大家都能去往自己心仪的大厂!为金三银四做准备!
一共有20个知识点专题,分别是:

Dubbo面试专题

JVM面试专题

这个GItHub上的Java项目开源了,2020最全的Java架构面试复习指南

Java并发面试专题

这个GItHub上的Java项目开源了,2020最全的Java架构面试复习指南

Kafka面试专题

这个GItHub上的Java项目开源了,2020最全的Java架构面试复习指南

MongDB面试专题

这个GItHub上的Java项目开源了,2020最全的Java架构面试复习指南

MyBatis面试专题

这个GItHub上的Java项目开源了,2020最全的Java架构面试复习指南

MySQL面试专题

这个GItHub上的Java项目开源了,2020最全的Java架构面试复习指南

Netty面试专题

这个GItHub上的Java项目开源了,2020最全的Java架构面试复习指南

RabbitMQ面试专题

这个GItHub上的Java项目开源了,2020最全的Java架构面试复习指南

Redis面试专题

这个GItHub上的Java项目开源了,2020最全的Java架构面试复习指南

Spring Cloud面试专题

这个GItHub上的Java项目开源了,2020最全的Java架构面试复习指南

SpringBoot面试专题

这个GItHub上的Java项目开源了,2020最全的Java架构面试复习指南

zookeeper面试专题

这个GItHub上的Java项目开源了,2020最全的Java架构面试复习指南

常见面试算法题汇总专题

这个GItHub上的Java项目开源了,2020最全的Java架构面试复习指南

计算机网络基础专题

这个GItHub上的Java项目开源了,2020最全的Java架构面试复习指南

设计模式专题

这个GItHub上的Java项目开源了,2020最全的Java架构面试复习指南
《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》点击传送门,即可获取!

[外链图片转存中…(img-o9BBaxvm-1714767350188)]

Java并发面试专题

[外链图片转存中…(img-JDjhcnbX-1714767350188)]

Kafka面试专题

[外链图片转存中…(img-RrkV1aKk-1714767350189)]

MongDB面试专题

[外链图片转存中…(img-PfqG2vW4-1714767350189)]

MyBatis面试专题

[外链图片转存中…(img-drHSDpCO-1714767350189)]

MySQL面试专题

[外链图片转存中…(img-m60zU9aE-1714767350190)]

Netty面试专题

[外链图片转存中…(img-XBnSAm2f-1714767350190)]

RabbitMQ面试专题

[外链图片转存中…(img-YKLwi3L4-1714767350191)]

Redis面试专题

[外链图片转存中…(img-YBrtyvhs-1714767350191)]

Spring Cloud面试专题

[外链图片转存中…(img-nPB7BZ2h-1714767350191)]

SpringBoot面试专题

[外链图片转存中…(img-Mg1NSIZW-1714767350191)]

zookeeper面试专题

[外链图片转存中…(img-IpbIBkn8-1714767350191)]

常见面试算法题汇总专题

[外链图片转存中…(img-EpeAbEgj-1714767350192)]

计算机网络基础专题

[外链图片转存中…(img-3scbmLPL-1714767350192)]

设计模式专题

[外链图片转存中…(img-kNeboX6g-1714767350192)]
《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》点击传送门,即可获取!

  • 24
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值