注解就是提供一些额外的信息
- 作用对象:类、属性、方法、参数
- 作用时机:源文件、编译时、运行时
注解本质上跟XML配置文件一样,都是提供了一些有用信息,不过二者间的区别也很大:
区别 | 注解 | XML配置文件 |
---|---|---|
耦合度 | 高 | 低 |
易用性 | 高 | 低 |
示例1
自定义注解,使用注解,并获取注解的内容
- 自定义注解:
@Retention(RetentionPolicy.RUNTIME) // 运行时可以访问该注解
@Target(ElementType.TYPE) // 该注解使用在类上
public @interface MyAnnotation {
String value() default "默认值";
String[] locations() default {};
}
使用注解,并获取注解内容:
// 使用自定义的注解,并设置value和locations属性
@MyAnnotation(value = "test", locations = {"a.xml", "b.properties"})
public class AnnotationTest {
public static void main(String[] args) {
// 获取注解
MyAnnotation annotation = AnnotationTest.class.getAnnotation(MyAnnotation.class);
// 访问并打印注解的value和locations属性
System.out.println("value: " + annotation.value());
System.out.println("locations:");
Arrays.asList(annotation.locations()).forEach(System.out::println);
}
}
运行结果:
value: test
locations:
a.xml
b.properties
示例2
使用注解自动设置数据库连接属性值
- 定义数据库配置文件:jdbc.properties
jdbcUrl=jdbc:mysql://localhost:3306/test?serverTimezone=Asia/Shanghai
username=root
password=123456
driverClass=com.mysql.cj.jdbc.Driver
- 自定义注解
@Retention(RetentionPolicy.RUNTIME) // 运行时使用
@Target(ElementType.FIELD) // 该注解使用在属性字段上
public @interface Value {
String value() default "";
}
- 定义数据源工厂,返回Druid数据源
public class DataSourceFactory {
private static DruidDataSource dataSource = null;
@Value("jdbcUrl")
private static String jdbcUrl;
@Value("username")
private static String username;
@Value("password")
private static String password;
@Value("driverClass")
private static String driverClass;
public static DruidDataSource getDataSource() {
if (dataSource == null) {
setFields();
dataSource = new DruidDataSource();
dataSource.setUrl(jdbcUrl);
dataSource.setUsername(username);
dataSource.setPassword(password);
dataSource.setDriverClassName(driverClass);
}
return dataSource;
}
}
解析并设置@Value注解的字段
到这一步为止,jdbcUrl、username等连接属性并没有值,需要从@Value中解析出配置。
在DataSourceFactory中添加如下函数:
private static void setFields() {
Properties properties = new Properties();
try {
properties.load(Objects.requireNonNull(DataSourceFactory.class.getClassLoader().getResourceAsStream(
"com/bailiban/day3/annotation/datasource/jdbc.properties")));
Field[] fields = DataSourceFactory.class.getDeclaredFields();
for (Field field : fields) {
Value annotation = field.getAnnotation(Value.class);
if (annotation == null) {
continue;
}
field.setAccessible(true);
field.set(null, properties.getProperty(annotation.value()));
}
} catch (IOException | IllegalAccessException e) {
e.printStackTrace();
}
}
- 测试是否连接成功:
public static void main(String[] args) throws Exception {
DataSource dataSource = DataSourceFactory.getDataSource();
Connection conn = dataSource.getConnection();
System.out.println(conn);
conn.close();
}
运行结果:
信息: {dataSource-1} inited
com.mysql.cj.jdbc.ConnectionImpl@7b9a4292