}
//用于配置当前方法是一个最终通知
@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类型匹配的通配符:
_:匹配任何数量字符;
…:匹配任何数量字符的重复,如在类型模式中匹配任何数量子包;而在方法参数模式中匹配任何数量参数。
### 最后
即使是面试跳槽,那也是一个学习的过程。只有全面的复习,才能让我们更好的充实自己,武装自己,为自己的面试之路不再坎坷!**今天就给大家分享一个Github上全面的Java面试题大全,就是这份面试大全助我拿下大厂Offer,月薪提至30K!**
**[CodeChina开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频】](
)**
**我也是第一时间分享出来给大家,希望可以帮助大家都能去往自己心仪的大厂!为金三银四做准备!**
一共有20个知识点专题,分别是:
#### Dubbo面试专题
![](https://img-blog.csdnimg.cn/img_convert/70cb44711b14009988a9d50a45674943.png)
**JVM面试专题**
![这个GItHub上的Java项目开源了,2020最全的Java架构面试复习指南](https://img-blog.csdnimg.cn/img_convert/344599f679d02ba35493a5f471880590.png)
**Java并发面试专题**
![这个GItHub上的Java项目开源了,2020最全的Java架构面试复习指南](https://img-blog.csdnimg.cn/img_convert/3f894dad4c1f305504665403e99adc51.png)
**Kafka面试专题**
![这个GItHub上的Java项目开源了,2020最全的Java架构面试复习指南](https://img-blog.csdnimg.cn/img_convert/2e1cf9dcfcffd7cb23f8f027c9114633.png)
**MongDB面试专题**
![这个GItHub上的Java项目开源了,2020最全的Java架构面试复习指南](https://img-blog.csdnimg.cn/img_convert/e791ddf760d663e53146042a38303a99.png)
**MyBatis面试专题**
![这个GItHub上的Java项目开源了,2020最全的Java架构面试复习指南](https://img-blog.csdnimg.cn/img_convert/1ea3487520c7656d5a2004cace270140.png)
**MySQL面试专题**
![这个GItHub上的Java项目开源了,2020最全的Java架构面试复习指南](https://img-blog.csdnimg.cn/img_convert/1a5beff4f4a541ee5a6c4c9e1f52a181.png)
**Netty面试专题**
![这个GItHub上的Java项目开源了,2020最全的Java架构面试复习指南](https://img-blog.csdnimg.cn/img_convert/0510da3643f3d0a5bca91b42f079ae64.png)
**RabbitMQ面试专题**
![这个GItHub上的Java项目开源了,2020最全的Java架构面试复习指南](https://img-blog.csdnimg.cn/img_convert/e7b19f44b0c67d174ddc025e7ef85e6c.png)
**Redis面试专题**
![这个GItHub上的Java项目开源了,2020最全的Java架构面试复习指南](https://img-blog.csdnimg.cn/img_convert/0189ffba2627fd6b0cbf8e9420b8379c.png)
**Spring Cloud面试专题**
![这个GItHub上的Java项目开源了,2020最全的Java架构面试复习指南](https://img-blog.csdnimg.cn/img_convert/e116d7d1f74ddae4bcb3e88d30614034.png)
**SpringBoot面试专题**
![这个GItHub上的Java项目开源了,2020最全的Java架构面试复习指南](https://img-blog.csdnimg.cn/img_convert/12bf3f2d9ad097d6c6d5fef7f64b3ca2.png)
**zookeeper面试专题**
![这个GItHub上的Java项目开源了,2020最全的Java架构面试复习指南](https://img-blog.csdnimg.cn/img_convert/489683ed416491643f542874d2f0021a.png)
**常见面试算法题汇总专题**
![这个GItHub上的Java项目开源了,2020最全的Java架构面试复习指南](https://img-blog.csdnimg.cn/img_convert/59f0541f25423eddafd1e293156f5efa.png)
**计算机网络基础专题**
![这个GItHub上的Java项目开源了,2020最全的Java架构面试复习指南](https://img-blog.csdnimg.cn/img_convert/9553e36ffbebdb28330d9e8d93140843.png)
**设计模式专题**
![这个GItHub上的Java项目开源了,2020最全的Java架构面试复习指南](https://img-blog.csdnimg.cn/img_convert/5cb7cb9b5cc3c59e445f1375711d97e4.png)
**Kafka面试专题**
[外链图片转存中...(img-ROzRAGWM-1631186232887)]
**MongDB面试专题**
[外链图片转存中...(img-bfLuAl10-1631186232888)]
**MyBatis面试专题**
[外链图片转存中...(img-uTRMObKH-1631186232889)]
**MySQL面试专题**
[外链图片转存中...(img-bkn5pVdu-1631186232890)]
**Netty面试专题**
[外链图片转存中...(img-AQBN7xXA-1631186232891)]
**RabbitMQ面试专题**
[外链图片转存中...(img-2JfQ3u8e-1631186232891)]
**Redis面试专题**
[外链图片转存中...(img-bvQ2fJEO-1631186232892)]
**Spring Cloud面试专题**
[外链图片转存中...(img-BPQ41QpD-1631186232893)]
**SpringBoot面试专题**
[外链图片转存中...(img-ZQ1u2aZx-1631186232893)]
**zookeeper面试专题**
[外链图片转存中...(img-pDGXNMBW-1631186232894)]
**常见面试算法题汇总专题**
[外链图片转存中...(img-8IyBWmsJ-1631186232895)]
**计算机网络基础专题**
[外链图片转存中...(img-3EUgPgbA-1631186232895)]
**设计模式专题**
[外链图片转存中...(img-ewQ0VLzg-1631186232896)]