Java 原生注解

Java 原生注解

注解(Annotation),元数据(Meta data)的一种形式,提供了程序本身之外的数据。是从jdk1.5才引入的特性,注解与类、接口、枚举在同一个层次,并可以应用于包、类型、构造方法、方法、成员变量、参数、本地变量的声明中。

@PostConstruct 注解

该注解被用来修饰一个非静态的 void()方法。被@PostConstruct修饰的方法会在服务器加载Servlet的时候运行,并且只会被服务器执行一次,是在构造函数之后执行,init()方法之前执行。

通常我们会是在Spring框架中使用到@PostConstruct注解 该注解的方法在整个Bean初始化中的执行顺序:

Constructor(构造方法) -> @Autowired或@Resource(依赖注入) -> @PostConstruct(注释的方法)

@Slf4j
@Component
public class ConfigConst {
    @Resource
    SysConfigRepository sysConfigDao;
    
    @Resource
    private RedisTemplate<String, String> redisTemplate;

    //@Config 是自定义的一个配置缓存注记
    @Config(key="huawei.obs")
    public static String HUAWEI ;
 
    //此组件Constructor构造函数执行完毕,所有其他组件加载完毕后执行此标注的init()方法
    @PostConstruct
    public void init(){
        Iterable<SysConfig> iterator =sysConfigDao.findAll();
        iterator.forEach(
                sysConfig -> {
                    redisTemplate.opsForValue().set(sysConfig.getKey(), sysConfig.getValue());
                }
        );
        Field[] fields = ConfigConst.class.getDeclaredFields();
        List<Field> configFields =
                Arrays.stream(fields).filter(field -> ObjectUtil.isNotNull(field.getAnnotation(Config.class)))
                        .collect(Collectors.toList());
        for(Field field:configFields){
            Config config = field.getAnnotation(Config.class);
            if(ObjectUtil.isNotNull(redisTemplate.opsForValue().get(config.key()))){
                log.warn(config.key()+"未配置");
            }
            ReflectUtil.setFieldValue(ConfigConst.class,field.getName()
                                      ,redisTemplate.opsForValue().get(config.key()));
        }
    }
}

Lombok 插件常用注解

@Data 注解

经常用 @Data 注解标记在实体类上面快速实现getters 和 setters, 而它好用地注解应该不至于这一个,下面是常用地注解汇总:
一般用在类上,提供类所有属性的 get 和 set 方法,此外还提供了equals、canEqual、hashCode、toString等方法;

@Setter 注解

一般用在属性上,为属性提供 set 方法, 用在再类上则表示当前类中所有属性都生成set方法;

@Getter 注解

用在属性上,为属性提供 get 方法, 用在再类上表示当前类中所有属性都生成get方法;

@NoArgsConstructor注解

用在类上,为类提供一个无参的构造方法;

@AllArgsConstructor注解

用在类上,为类提供一个全参的构造方法;

@RequiredArgsConstructor注解

用在类上,生成一个包含 “特定参数” 的构造器,特定参数指的是那些有加上 final 修饰词的变量们;

@Builder注解

用在类上,自动生成流式 set 值写法,从此之后再也不用写一堆 setter 了;
虽然只要加上@Builder注解,我们就能够用流式写法快速设定对象的值,但是 setter 还是必须要写不能省略的,因为 Spring 或是其他框架有很多地方都会用到对象的 getter/setter 对他们取值/赋值所以通常是 @Data 和 @Builder 会一起用在同个类上,既方便我们流式写代码,也方便框架做事;

@Cleanup注解

可以用在 IO 流上,用于关闭并释放资源;
例如下面例子,每次IO六操作后要在finally中关闭流,释放资源:

public class CleanupExample {
  public static void main(String[] args) throws IOException {
    InputStream in = new FileInputStream(args[0]);
    try {
      OutputStream out = new FileOutputStream(args[1]);
      try {
        byte[] b = new byte[10000];
        while (true) {
          int r = in.read(b);
          if (r == -1) break;
          out.write(b, 0, r);
        }
      } finally {
        if (out != null) {
          out.close();
        }
      }
    } finally {
      if (in != null) {
        in.close();
      }
    }
  }
}

类似以上地一个IO留操作的方法使用lombok 的 @Cleanup 注解后可以简化成这样:

public class CleanupExample {
    public static void main(String[] args) throws IOException {
        @Cleanup InputStream in = new FileInputStream(args[0]);
        @Cleanup OutputStream out = new FileOutputStream(args[1]);
        byte[] b = new byte[10000];
        while (true) {
            int r = in.read(b);
            if (r == -1) break;
            out.write(b, 0, r);
        }
    }
}
@SneakyThrows 注解

利用了这一机制,将当前方法抛出的异常,包装成RuntimeException,骗过编译器,使得调用点可以不用显示处理异常信息,使用注解后不需要担心Exception的处理。例如:

import lombok.SneakyThrows;

public class SneakyThrowsExample implements Runnable {
  @SneakyThrows(UnsupportedEncodingException.class)
  public String utf8ToString(byte[] bytes) {
    return new String(bytes, "UTF-8");
  }
  
  @SneakyThrows
  public void run() {
    throw new Throwable();
  }
}

真正生成的代码

import lombok.Lombok;

public class SneakyThrowsExample implements Runnable {
  public String utf8ToString(byte[] bytes) {
    try {
      return new String(bytes, "UTF-8");
    } catch (UnsupportedEncodingException e) {
      throw Lombok.sneakyThrow(e);
    }
  }
  
  public void run() {
    try {
      throw new Throwable();
    } catch (Throwable t) {
      throw Lombok.sneakyThrow(t);
    }
  }
}

SpringBoot常用注解

@Bean 注解

用于告诉方法,产生一个Bean对象,然后这个Bean对象交给Spring管理。产生这个Bean对象的方法Spring只会调用一次,随后这个Spring将会将这个Bean对象放在自己的IOC容器中。
SpringIOC 容器管理一个或者多个bean,这些bean都需要在@Configuration注解下进行创建,在一个方法上使用@Bean注解就表明这个方法需要交给Spring进行管理。详细了解参考: @Bean 注解全解析 。

@ConditionalOnMissingBean注解

是修饰bean的一个注解,主要实现的是,当你的bean被注册之后,如果而注册相同类型的bean,就不会成功,它会保证你的bean只有一个,即你的实例只有一个,当你注册多个相同的bean时,会出现异常,以此来告诉开发人员。

@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(ObjectMapper.class)
@AutoConfigureBefore(JacksonAutoConfiguration.class)
public class JacksonConfiguration {
    /**
    * Bean:定义一个customizer的方法并生成bean对象交给IOC
    * ConditionalOnMissingBean: 保证此对象只注册一次,从夫注册同名同类的对象时抛出异常
    **/
	@Bean
	@ConditionalOnMissingBean
	public Jackson2ObjectMapperBuilderCustomizer customizer() {
		return builder -> {
			builder.locale(Locale.CHINA);
			builder.timeZone(TimeZone.getTimeZone(ZoneId.systemDefault()));
			builder.simpleDateFormat(DatePattern.NORM_DATETIME_PATTERN);
			builder.serializerByType(Long.class, ToStringSerializer.instance);
			builder.modules(new PigJavaTimeModule());
		};
	}
}
@AutoConfigureBefore@AutoConfigureAfter 和@Order 注解

用来控制@Configuration标记的配置文件加载顺序,具体参考: 链接

@Condition类注解
@ConditionalOnBean(仅仅在当前上下文中存在某个对象时,才会实例化一个Bean)
@ConditionalOnClass(某个class位于类路径上,才会实例化一个Bean)
@ConditionalOnExpression(当表达式为true的时候,才会实例化一个Bean)
@ConditionalOnMissingBean(仅仅在当前上下文中不存在某个对象时,才会实例化一个Bean)
@ConditionalOnMissingClass(某个class类路径上不存在的时候,才会实例化一个Bean)
@ConditionalOnNotWebApplication(不是web应用,才会实例化一个Bean)
@ConditionalOnBean:当容器中有指定Bean的条件下进行实例化。
@ConditionalOnMissingBean:当容器里没有指定Bean的条件下进行实例化。
@ConditionalOnClass:当classpath类路径下有指定类的条件下进行实例化。
@ConditionalOnMissingClass:当类路径下没有指定类的条件下进行实例化。
@ConditionalOnWebApplication:当项目是一个Web项目时进行实例化。
@ConditionalOnNotWebApplication:当项目不是一个Web项目时进行实例化。
@ConditionalOnProperty:当指定的属性有指定的值时进行实例化。
@ConditionalOnExpression:基于SpEL表达式的条件判断。
@ConditionalOnJava:当JVM版本为指定的版本范围时触发实例化。
@ConditionalOnResource:当类路径下有指定的资源时触发实例化。
@ConditionalOnJndi:在JNDI存在的条件下触发实例化。
@ConditionalOnSingleCandidate:当指定的Bean在容器中只有一个,或者有多个但是指定了首选的Bean时触发实例化。
  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值