1.Java 注解的注注解工作原理以及如何创建自定义注解
2.@Value竟然能玩出这么多花样,涨知识了
3.《Java面向对象编程》导读-在Java类中使用自定义注解
4.Spring 中 @Value 配置注入
5.java中@RequestMapping注解指定的解源路径value后面的大括号里面的字符串是什么意思啊!
Java 注解的注注解工作原理以及如何创建自定义注解
Java 注解是自 Java 5 起即成为语言基石的重要特性,它们通过元数据增强代码可读性、解源维护性和减少样板代码。注注解本文将深入探讨注解的解源大富翁指标源码工作原理,以及如何一步步创建自定义注解,注注解提升开发技能。解源什么是注注解 Java 注解?
Java 注解是一种特殊接口,通过@interface关键字定义,解源用于向代码元素添加元数据,注注解影响编译器行为、解源代码生成、注注解运行时功能和简化配置。解源注解剖析
注解是注注解编译器或处理工具的接口,附加在代码中,不会直接改变代码逻辑。它们在代码中的作用分为编译器指令、代码分析和运行时行为。注解应用
编译器指令:如@Override确保方法重写正确。
代码分析:工具使用注解检测问题或执行编码标准检查。
运行时行为:如@Deprecated标记弃用元素。
简化配置:注解替代部分 XML 配置,如Spring的@Autowired和Hibernate的@Entity。
创建自定义注解
步骤包括:定义注解类型,应用到代码,以及处理(编译时或运行时)以实现特定功能。关键内置注解
-
@Override
-
@Deprecated
-
@SuppressWarnings
-
@FunctionalInterface
-
元注解如@Retention和@Target
内置注解的道法源码影响
内置注解不仅是元数据,它们影响代码行为,如编译验证和运行时反射。 理解并有效使用这些注解是现代 Java 开发的基石。注解工作原理
注解通过元数据形式附着于代码元素,涉及声明、处理和应用阶段,如动态代理和接口实现。结论
Java 注解是提升代码质量的重要工具,通过自定义注解,开发者可以创建更灵活、更易于维护的代码。掌握注解的使用,是每个 Java 开发者提升技能的关键。@Value竟然能玩出这么多花样,涨知识了
前言 在进行Java开发时,Spring框架提供了丰富的API来满足日常需求。通过`@Controller`、`@Service`、`@Repository`、`@Component`等注解可以创建bean实例。依赖注入对象通常使用`@Autowired`和`@Resource`注解。事务开启可以借助`@Transactional`注解。而`@Value`注解,虽然功能强大且应用广泛,但往往容易被开发者忽视。 最近,一位BAT大厂的anyreport 源码高手分享了LeetCode刷题笔记,让我的面试技巧显著提升。 在《@Autowired的这些骚操作,你都知道吗?》、《聊聊spring事务失效的种场景,太坑了》、《惊呆了,spring中竟然有种定义bean的方法》等文章中,已经详细介绍了`@Autowired`、事务处理和bean定义等常用注解,这里不再赘述。 今天,让我们聚焦于`@Value`注解。这个注解在自动注入系统属性时极其有用,但很多人只用到了它的一部分功能,这确实是一种遗憾。本文将带你重新认识`@Value`,深入挖掘它的强大之处。由一个例子开始
假设在`UserService`类中,需要将系统属性注入到`userName`变量中。通常的代码实现如下: 通过`@Value`注解指定系统属性名称`susan.test.userName`,确保使用`{ }`包裹名称,Spring会自动将对应的系统属性值注入到`userName`变量中。 不过,这个功能的关键在于,在`applicationContext.properties`配置文件中,需要配置与系统属性名完全相同的配置项。关于属性名
这时,tengine源码有朋友可能会问,在`@ConfigurationProperties`配置类中,参数名可以与配置文件中的系统属性名不同。例如,在`MyConfig`类中,参数名为`userName`: 而配置文件中的系统属性名则为: 尽管参数名和系统属性名不同,测试结果表明功能正常运行。系统属性名使用驼峰标识或小写字母加中划线组合,Spring均能找到对应的配置类属性名`userName`进行赋值。 因此,配置文件中的系统属性名与配置类属性名可以不完全相同,前提条件是前缀`susan.test`保持一致。乱码问题
细心的小伙伴们可能注意到,我配置的属性值“张三”是转义过的。为何要做转义处理? 如果在配置文件中直接配置中文“张三”,获取数据时,`userName`变量会显示乱码:`å¼ ä¸`。为什么会出现乱码? 答案在于`springboot`的`CharacterReader`类,默认编码格式为`ISO--1`,用于读取`.properties`文件中的系统属性。如果属性包含中文字符,就会产生乱码。 解决乱码问题,主要有三种方案,但均不适用于`@Value`注解。推荐采用将属性值转换为`unicode`编码的方法,既解决了乱码问题,localcache源码又避免了重复代码的生成。使用在线转换工具,如`jsons.cn/unicode/`,转换中文内容至`unicode`格式。默认值设置
在工作中,我们经常遇到默认值设置的问题。使用Java的默认值通常无法满足实际需求。例如,配置了系统属性,则使用配置值;未配置时,使用默认值`susan`。 有些朋友可能尝试直接在定义参数时设置默认值,但这种方法行不通。因为默认值的设定时机在`@Value`注解依赖注入属性值之前,导致默认值被覆盖。正确做法是使用`:`符号设置默认值。 此外,为避免`business`层中引用`UserService`时可能引发的异常,建议在使用`@Value`注解时为参数设置默认值。这样可以确保在未配置系统属性时,服务依然能够启动。静态变量注入
虽然我们已经了解了如何使用`@Value`注解给成员变量注入系统属性值,但静态变量能否注入呢?答案是否定的。静态变量通过`@Value`注入时会失败。 要给静态变量注入系统属性值,需要通过一些“骚代码”实现,具体做法是在静态参数的setter方法上使用`@Value`注解,并在方法中完成静态变量的赋值。变量类型
`@Value`注解不仅支持字符串类型的变量,还支持其他多种类型的系统属性值注入,包括基本类型和集合类。基本类型
Java的基本数据类型及其对应的包装类在`@Value`注解中得到了良好支持。例如,可以注入`int`、`String`等类型的值。数组
数组在日常开发中使用频繁。定义数组时,通常使用逗号分隔参数值。若使用空格分隔,则会自动去掉空格,注意不要误解。 数组的定义及其注入属性值的方式与基本类型类似,但需要确保属性值的类型与数组类型一致。List、Set和Map
除了基本类型和数组,`@Value`注解还支持List、Set和Map等集合类的注入。配置文件的编写与数组类似,但需要针对集合的特性进行适当的调整。EL表达式
借助`EL`(Expression Language)表达式,`@Value`注解实现了更高级的功能,如注入bean、实现逻辑运算等。${ }与#{ }的区别
`@Value`注解的关键在于${ }和#{ }的用法。${ }主要用于获取配置文件中的系统属性值,而#{ }则用于获取bean的属性或调用bean的方法。${ }用法
通过${ }获取系统属性值时,可以设置默认值。如果未找到配置项,则使用默认值;若未设置默认值,将引发异常。#{ }用法
使用#{ }获取bean的属性或调用bean的方法时,可以实现逻辑运算、拼接字符串等功能,灵活度更高。总结
通过深入挖掘`@Value`注解的用法,我们不仅能够灵活地注入系统属性,还能够实现更高级的功能,如注入bean、实现逻辑运算等。在日常开发中,合理利用`@Value`注解,可以提升代码的效率和可维护性。 最后,我创建了一个高质量的技术交流群,欢迎小伙伴们加入,共同交流学习。如果你对技术感兴趣,希望提升自己的技能,欢迎加入。点击下方链接加入技术群,与更多技术大牛交流学习。《Java面向对象编程》导读-在Java类中使用自定义注解
在这篇文章中,将介绍如何在Java类中使用自定义注解。将定义三个注解:@Programmer、@ConstructorNote和@Common。接下来,这些注解可以在其他类中使用,示例代码如下:
例程1:Person类
在Person类的源代码中,使用注解进行标记。在类前添加@Programmer注解,在构造方法前添加@ConstructorNote注解,在成员变量、成员方法和参数前添加@Common注解。
注解成员的赋值有几种方式:默认值、以"成员名=成员值"形式赋值,或当注解仅有一个成员且名为"value"时,以成员值直接赋值。
编译Person类时,由于自定义注解的有效范围为RetentionPolicy.RUNTIME,编译器会将注解编译至类文件中。
在定义@Programmer注解时引用了JDK类库的内置@Documented注解,因此在使用JDK的javadoc命令生成JavaDoc文档时,包含@Programmer注解信息。
以上内容参考了孙卫琴的经典Java书籍《Java面向对象编程》。希望这篇介绍能帮助你更好地理解和使用自定义注解。
Spring 中 @Value 配置注入
通过 @Value 我们可以将配置文件中的数据注入到属性或入参中,Spring 是怎样解析注入的呢?
—配置项注入用法示例
value.from.file 为配置文件的 key,如果没有的时候用字符串 "defaultValue" 代替。
流程分析
首先在 Bean 创建后,BeanFactory 会填充 Bean 中的属性值,包含 Autowired、Value 等。
以 AnnotationConfigApplicationContext 创建为示例来说明。
创建 Context 的构造函数中创建了两个对象:
ClassPathBeanDefinitionScanner:通过 Java 字节码来扫描包中 class 文件,来生成 BeanDefinition。具体扫描过程可以参考上一篇文章 Spring 中注解扫描。
AnnotatedBeanDefinitionReader:这个构造函数中会创建 Environment,代码如下:
getOrCreateEnvironment 会创建 StandardEnvironment,这个时候会初始化两个 PropertySource。
至此 Environment 创建好了,我们为什么要讲 Environment 创建呢?
Spring 中解析配置是通过 Environment.resolvePlaceholders 来进行解析的,创建完 Environment 后,接下来就是解析配置的文件,将 Property 放入到 Environment 中。
PropertyResolver:接口中定义了 resolvePlaceholders,ConfigurablePropertyResolver:可以自定义表达式格式,前缀格式( "${ " ),后缀格式( "}" ),默认值分隔符( ":" ),AbstractEnvironment:实现了 resolvePlaceholders 逻辑。
AbstractEnvironment.resolvePlaceholders 代码如下。
propertyResolver 创建的时候,将 propertySources 放了进去。MutablePropertySources 通过名称我们就可以看出这个类可以包含多个配置文件。propertyResolver 解析配置的时候会按顺序查找,命中后就直接返回。
如下图所示,MutablePropertySources 中 0 和 1 是 Environment 创建的时候默认初始化的配,第二个是我们自己加的配置,这里我们也可以将我们自己加的配置放在最前面。MutablePropertySources 中有 addFirst 和 addLast 来控制添加的位置。
—SpEL 表达式用法示例
从系统配置中取值
取某个 Bean 的属性
将配置转成 List
其他用法
流程分析
DefaultListableBeanFactory.doResolveDependency 这个方法主要是对需要注入属性值进行解析,比如带 @Autowire、@Value 的属性。其中有如下一段代码:
①:是对配置进行解析,就是我们上面第一部分讲的,如果这里没有获取到会将 value 值原样返回。
②:这部分是将 strVal 当做 SpEL 表达式进行解析。
从这里可以看出我们不仅可以直接将表达式配置在 @Value 注解中,还可以配置在配置文件中。
SpEL 的更多用法可以参考官方文档 docs.spring.io/spring-framework/docs/current/spring-framework-reference/html/expressions.html。
微信搜索“CoderMeng”关注获取更多干货文章。
大家觉得写的不错欢迎分享支持。
java中@RequestMapping注解指定的路径value后面的大括号里面的字符串是什么意思啊!
这个是restful的请求方式,就是附加了请求参数,请求就可以是/manageweb/schbase-XXX,在你这个方法上对应的就是schid,通过@PathVariable映射