Spring高级注解-Day3,你还没弄明白存储键值对

}



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

@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)]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值