首页 > 编程语言 > 详细

JavaSE:注解&反射

时间:2020-12-09 21:07:15      阅读:56      评论:0      收藏:0      [点我收藏+]

 

@Annotation注解

注解,也叫元数据。包、类、方法、局部变量(package, class, method, field)... 前面声明

注解可以被其他程序(比如:编译器)读取;是一种额外的辅助信息;

注解通过反射机制 来读取注解

 


 Bean相关:

@RestController // 写在Controller类之前,用于前后端分离JSON/XML形式数据 // 相当于下面5个:

  @Target (ElementType.TYPE)
  @Retention (RetentionPolicy.RUNTIME)
  @Documented 公共API会被工具文档化
  @Controller
  @ResponseBody

@AutoWired // 写在service实例化之前,让容器帮我们自动装配bean

 

@Component 泛指组件,一般用在公共的方法

@Resource 

@Repository   对应持久层即Dao层,主要用于数据库相关操作

@Service 对应服务层,主要涉及一些复杂的逻辑,需要用到Dao层

@Controller(前后端分离一般不单独用这个,而用RestController)    对应控制层,主要用户接受用户请求并调用Service层返回数据给前端页面

 

@Conditional 根据代码中设置的条件,装载不同的 bean

@Bean

@Score    声明 Bean的作用域(4种):singleton /prototype /request /session

@Configuration    配置类前,申明用

 


 处理HTTP请求:

@RequestMapping("/...")    //总的url

  @PostMapping("/...")     //针对具体接口,写在每一个方法前 //根据具体情况,如save就没有url

  @GetMapping("/...")

  @PutMapping("/...")  //追加

  @DeleteMapping("/...")

 

//下面2个都是在方法的参数括号中:

@RequestParam

@RequestBody

技术分享图片

技术分享图片

 

@PathVariable 路径变量 

  技术分享图片

技术分享图片

 

ps:一个请求方法只可以有一个@RequestBody(JSON);但可以有多个@RequestParam和@PathVariable


 

@SpringBootApplication   这个注解是SpringBoot 项目的基石,创建SpringBoot项目后会默认在主类加上。

  等价于@Configuration , @EnableAutoConfiguration 和 @ComponentScan 注解他们的 main 类:

  @Configuration

  @EnableAutoConfiguration  自动配置;类级别

  @ComponentScan

     @Controller , @Service , @Repository

 


 读取配置:

@Value("${app.filePath}")   //读取比较简单的配置信息

@ConfigurationProperties  //读取配置信息并与bean绑定

 


参数校验

常用的字段验证:

   @NotEmpty   @NotNull  @NotBlank  

   @AssertFalse  @AssertTrue  必须为正/负

   @Pattern(regex=,flag=) 正则表达式

   @Min  @Max  @Digits(integer, fraction)

   

验证请求体(RequestBody):

  @Valid  技术分享图片

  如果验证失败,将抛出MethodArgumentNotValidException

 

验证 PathVariable、RequestParam :

  要在类前加上@Validated注解;然后再在需要验证的数据前加上@Valid

 


 全局处理Controller异常:

@ControllerAdvice

  技术分享图片

@ExceptionHandler

  注解声明异常处理方法

 


JPA相关(java持久层API)

   技术分享图片

   @Entity:class对应数据库实体

   @Table:设置表名

   @Id:表明字段为主键

   @GeneratedValue (strategy=GenerationType....) 主键生成策略

      TABLE表来保存主键  SEQUENCE序列机制生成主键  IDENTITY自增长  AUTO引擎帮助三选一

  

   @Column 声明字段

   技术分享图片

   @Transient 指定不持久化特定字段

   @Lob 声明大字段(最多4GB)

 


 事务@Transactional  

   技术分享图片

 

 

@Transactional一般用于class和method;当method单独说明时,会覆盖class的

 


JSON数据处理

过滤JSON数据:

   技术分享图片

 

 @JsonFormat用于格式化json数据:

  技术分享图片

 

 @JsonUnwrapped 扁平化对象:

  技术分享图片 扁平化后: 技术分享图片

 


 测试相关

   @Test 测试method    @Transactional回滚避免污染测试数据     @WithMockUser模拟真实用户

  技术分享图片

 

 


 3个内置注解:

  @Override  // 重写父类的方法

  @Deprecated  // 不推荐使用,但可以使用

  @SuppressWarnings  // 镇压警告

    技术分享图片

 

 

4个元注解(为其他注解作说明):

  @Target //被描述的注解可以用在什么地方; FIELD 字段、METHOD 方法

  @Retention (SOURCE < CLASS < RUNTIME) 一般都用RUNTIME表示在运行时可以看到

  @Documented 

  @Inherited

  技术分享图片

   @interface 是自定义注解的声明

 


 【实例】

1)自定义注解:

技术分享图片

 

 技术分享图片

 

 2)使用注解:

 技术分享图片

 


反射 reflect

  Java通过反射来获得“动态性(程序运行期间改变程序结构)”,在执行期间,才动态获得类的内部信息、并直接操作内部属性和方法。

  不需要事先(写代码/编译期)知道运行对象是谁。我的感觉是可以根据外部的输入,来动态获取不同对象的类的信息。

技术分享图片

 技术分享图片


反射实例:

技术分享图片


 创建实体类Entity(pojo):

写完变量后:

  1)创建构造函数

  右击,选择Generate(或者Alt+INS)

  技术分享图片

  技术分享图片

 

   2) get & set 获取私有属性;toString方便调试

  技术分享图片

 


 写main方法:

  psvm然后Tab:技术分享图片

  sout:技术分享图片

 


 Class加载内存分析  https://www.bilibili.com/video/BV1p4411P7V3?p=9 (建议多看几遍)

  字节码加载到内存=》链接合并到jvm环境,设置static默认初始值 =》类构造器clinit初始化

 

  技术分享图片

 

 

技术分享图片技术分享图片技术分享图片

 


技术分享图片

 

技术分享图片

 常量和static变量在链接时就已经赋值了,初始化之前就已经存在了,引用这些量不会导致初始化。


 

ClassLoader  类加载器

技术分享图片

 

类加载器细分:

  1.根 类加载器(Java平台核心库 rt.jar)

  2.扩展(ext)加载器 

  3.系统类(app)类加载器,最常用

 


技术分享图片

  Class c1 = user.getClass()

  c1.getFields()    getDeclaredFields()    getField("Fieldname",String.class)按要求获取

  c1.getMethods()   getDeclaredMethods()   getMethod("Methodname",String.class)

  c1.getConstructors()   getDeclearedConstructors()

 

 1)由知道的c1这个Object,获取c1的Class的信息(属性

  技术分享图片

  技术分享图片

 

2)由知道的c1这个Object,获取c1的Class的信息(方法

  技术分享图片

   技术分享图片

 

  技术分享图片

    技术分享图片

 

3)由知道的c1这个Object,获取c1的Class的信息(构造器

  技术分享图片

 


反射实例

技术分享图片

 

 技术分享图片

  本例反射方式中,将getName方法剥离出来,再使用invoke来调用user对象(getName也可用于调用其他对象)

技术分享图片

 

 最后看下耗时:

   技术分享图片反射很慢,但有时候还是需要的


 通过反射获取泛型  https://www.bilibili.com/video/BV1p4411P7V3?p=15  

method.getGenericParameterTypes()       method.getGenericReturnType()       


 

JavaSE:注解&反射

原文:https://www.cnblogs.com/qyf2199/p/14063008.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!