注解呢,是java本身自带的一个东西,它基于java的接口进行实现,是一种特殊的接口类型,通常对于注解来说,三种情况,一个是在编译前就会被丢弃的,一个是编译后留在class中的,另一种是会一直存在,运行的时候注解也会被保留,而框架的注解一般都是第三种。

Class对象,Method对象,Parameter对象,Constructor对象等java反射对象通常都具有getAnnotation方法可以直接获取保留到运行时的注解实例,就像这样:

@Component

class AnnoTest {

}

这样的一个类,有一个component注解,我们可以通过这样:

Component comp = AnnoTest.class.getAnnotation(Component.class);

Annotation[] annotations = AnnoTest.class.getAnnotations();

// 其实还有两个注解的get方法,你可以自己去看,这里不多说。

就直接得到了class上面的注解。

注解和普通接口不一样,他声明的语法比较特别,public @interface 注解名这个样子。为了标识注解的使用范围,你需要使用一些java提供的几个其他注解,这些用来描述注解的注解被称为元注解。

@Retention,保留范围(在源码中存在,还是在字节码里面,还是一直留到运行环境),一般是Runtime,

@Target 注解的作用对象,类型还是字段还是方法,这个注解是写在什么地方的。

@Inherited 是否可以继承此注解,这个注解仅仅在针对类的注解中起效,如果一个类继承了使用了含有他的注解的父类,那么这个类也会拥有父类的那个注解。

@Documented 注解再生成JavaDoc的时候是否会被写入Javadoc。

总之,这样就是有一个注解了,比如这样:

@Retention(RUNTIME)

@Target(ElementType.TYPE)

public @interface Component {

/*** 组件名称* @return*/

String name() default "";

/*** 组件创建类型* @return*/

Scope scope() default Scope.SINGLE;

}

这里要特别的说下注解接口的方法:这些方法由返回值,方法名称构成,具体的值是你写注解的时候填进去的,例如上述注解的name,实际上是你在使用注解的时候放在@component(name="xxxx")这里面的那个name,这些方法可以使用default指定一个默认返回值,即,你在使用注解的时候没有填写这个东西,会返回的内容。

接下来,你要用反射的手法拿到这些带有注解的class,method,field之类的,然后get到他们的注解,然后对注解进行处理,无论是aop还是注入,按照你的需要自己实现。

这里有一个例子,这个是仿照spring进行properties文件进行值注入的方法,他通过读取class的configProperties注解得到properties文件的位置,然后注入到bean的字段中。

public Object prcess(Object target, Definition definition, IFactory factory) {

Class> clazz = definition.getClazz();

ConfigProperties config = clazz.getAnnotation(ConfigProperties.class);

if (config == null) {

return target;

}

String location = config.value();

if (!location.startsWith(File.separator)) {

location = File.separator + location;

}

URL url = clazz.getResource(location);

Properties props = new Properties();

try {

props.load(url.openStream());

// 这个只是对properties的封装,就当他是普通properties好了PropertiesConfig propsConfig = new PropertiesConfig();

propsConfig.setProperties(props);

Set keys = props.stringPropertyNames();

for (String propName : keys) {

String fieldName = propName.replace(config.prefix() + ".", "");

try {

//按照properties的key,去掉前缀后读取类的字段FieldField field = clazz.getDeclaredField(fieldName);

// 开启操作权限field.setAccessible(true);

// 字段不是string型就需要转换一下if (field.getType() != String.class) {

// 获取类型转换器ICovertor covertor = Covertors

.getCovertor(String.class, field.getType());

if (covertor != null) {

// 转换类型并且注入field.set(target, covertor

.covert(propsConfig.get(propName)));

} else {

// 反向获取类型转换器(这里的转换器接口//是双向的,其实这样区分方向转换不是很好,//但是我现在没有来得及改他。covertor = Covertors

.getCovertorRev(field.getType(),

String.class);

// 转换并注入, 其实这里应该判空,// 但是当时应该是我忘记了field.set(target, covertor.

covertRev(propsConfig.get(propName)));

}

} else {

// 类型一致,直接注入field.set(target, propsConfig.get(propName));

}

} catch (Exception e) {

// 注入失败也无所谓,无视这个字段下一个注入}

}

} catch (IOException e) {

throw new RuntimeException(e);

}

return target;

}

注解接口:

@Retention(RUNTIME)

@Target(TYPE)

@Component

public @interface ConfigProperties {

String value();

String prefix();

}

附一个近期手写的ioc容器,仿springboot,用注解驱动的那种,虽然水平比较菜,但是注解还是用了不少的,哦,对了,这个代码需要Java11才行。仿制IOC的GitHub​github.com

java spring注解_spring注解是如何实现的?相关推荐

  1. @configuration注解_Spring注解@Configuration

    前言 @Configuation是spring最常见的注解之一,很多人都很熟悉.说起这个注解的作用,大家一定会说,当类上有@Configuration的时候,可以在这个类中使用@Bean注解向spri ...

  2. java spring异常处理_Spring项目中优雅的异常处理

    前言 如今的Java Web项目多是以 MVC 模式构建的,通常我们都是将 Service 层的异常统一的抛出,包括自定义异常和一些意外出现的异常,以便进行事务回滚,而 Service 的调用者 Co ...

  3. @import注解_Spring 注解之@Import 注入的各种花活

    今天来分享一下 pig4cloud 中涉及的 @Import 的注入形式.通过不同形式的注入方式,最大程度使得架构简洁. @Import导入一个组件 来看 EnablePigxDynamicRoute ...

  4. java spring 过滤器_spring中过滤器与拦截器的区别

    具体代码 /** * 通过过滤器实现跨域处理 */ @Order(1) @Component @WebFilter(urlPatterns = { "/api/*"}, filte ...

  5. java中spring的注解_spring中的各种注解解析

    Spring中的注解大概可以分为两大类: 1)spring的bean容器相关的注解,或者说bean工厂相关的注解: 2)springmvc相关的注解. spring的bean容器相关的注解,先后有:@ ...

  6. java spring框架 注解_spring框架之注解的使用

    原标题:spring框架之注解的使用 今天是刘小爱自学Java的第122天. 感谢你的观看,谢谢你. 学习内容安排如下: Spring注解的使用. JavaWeb项目的搭建. Spring的Web集成 ...

  7. spring多参java注解_spring参数注解校验

    在写一些controller协议的时候,有些时候从前端传过来的参数较多,好的办法是定义一个实体类来封装请求参数,但是用实体类封装参数后,无法对参数值进行校验,可以使用spring的@Validated ...

  8. java获取方法上的注解_Spring:使用Spring AOP时,如何获取目标方法上的注解

    当使用spring AOP时,判断目标方法上的注解进行相关操作,如缓存,认证权限等 自定义注解 packagecom.agent.annotation;importjava.lang.annotati ...

  9. java spring框架 注解_史上最全的java spring注解

    史上最全的java spring注解,没有之一 注解是个好东西,但好东西我们也是看见过,整理过,理解过,用过才知道好.不求我们每个都记住,但求保有印象,在需要的时候能提取出来再查找相关资料,平时工作就 ...

最新文章

  1. 技术一般,却被破格提拔!肯定有黑幕......
  2. __getattr__ 与动态属性
  3. 图形上下文的栈操作(保存和恢复)
  4. spark sql 查看分区_Spark 3.0 中七个必须知道的 SQL 性能优化
  5. java web简单三层结构
  6. C#的特性Attribute
  7. 2018麦考林杂志计算机科学,最新出炉|2018年麦考林杂志加拿大大学排名!
  8. 时间序列数据的特征提取
  9. Node.js--下载、安装、配置
  10. QQ坦白说_6.09前
  11. python三大神器之一装饰器
  12. 少儿编程c语言 难度,c语言很难学吗
  13. input的button类型,点击页面跳转
  14. 中值定理证明题解题思路
  15. 小小英雄怎么修改服务器,英雄联盟自走棋小小英雄怎么换 LOL英雄战棋小小英雄皮肤更改方法...
  16. 瑞幸咖啡贵不贵?咖啡不贵,商业却很贵
  17. AcWing 3725. 卖罐头 有意思的数学推导 思维
  18. 联发科有没有高端处理器_联发科官宣,全球第六款7nm处理器来袭,专为游戏而生...
  19. 高通语音专题---电话会议流程和日志分析
  20. 色氨酸代谢与肠内外健康稳态

热门文章

  1. Lync Server 2010的部署系列_第六章 安装配置拓扑生成器、前端Server、前端池
  2. 教你如何防止电脑插入u盘后自动运行
  3. jQuery1.3.2 源码学习 -2 两个重要的正则表达式
  4. 网络爬虫--14.【糗事百科实战】
  5. 平板电脑硬件如何测试软件,先锋(Pioneer)G71平板电脑软件测试评测-ZOL中关村在线...
  6. matlab ones函数_Matlab中相见恨晚的命令(持续更新)
  7. 访问linux服务主机,如何把Linux配置为日志服务主机。
  8. 注意:匿名函数调用直接加载函数名setInterval(move,30)
  9. Freeswitch之ASR(语音识别)总结大全
  10. java 对象加密_java.security包实现对象加密