前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Spring核心——JSR250与资源控制 原

Spring核心——JSR250与资源控制 原

作者头像
随风溜达的向日葵
发布2018-08-15 11:22:34
1.2K0
发布2018-08-15 11:22:34
举报
文章被收录于专栏:技术墨客技术墨客

JSR-175与元编程

要说明JSR-250先要解释清楚JSR-175,要解释清楚JSR就的先了解JCP是什么。网上资料很多,就不细说了,简单的说JCP(Java Community Process)是管理Java生态(包括J2SE、J2EE等等)发展的合作组织。JSR(Java Specification Request)就是组织内的成员针对Java的发展提出的一些需求,通过审核之后即会融入到新版本的Java功能中成为Java的一项特性或功能,不同的发行版本和虚拟机都会遵守这些约定。

JSR-175的全文标题是 A Metadata Facility for the Java Programming Language (为Java语言提供元数据设施)。它明确提出了在Java平台引入“元编程”(Meta Programming)的思想,要求提供对“元数据”(Meta Data)的支持。这就是我们现在大量使用的“@”注解(Annotation)功能的最早来源。JSR-175之后的JSR-181(Web服务支持)、JSR-250、JSR-330都是基于“元数据”功能提出的一些更细节的实现。

至于“元编程”、“元数据”是什么这里就不详细展开说明了,它的理论很早就提出了,据说最早是在Lisp这一类函数式编程语言上开始使用的。网上有很多相关的资料,简单的说它就是“对源码进行编码”,比如下面这样:

代码语言:javascript
复制
class MyClass {
	@Autowired
	private Interface support;
}

通过@Autowired这个注解来对support这个域进行编码就可以很轻松的扩展原先类的功能。

JSR-250的Spring实现

JSR-250主要是围绕着“资源”的使用预定义了一些注解(Annotation),这里的“资源”可以理解为一个Class类的实例、一个JavaBean、或者一个Spring中的Bean。

JSR-250相关的注解全部在 javax.annotationjavax.annotation.security 包中,分成2个部分——资源定义和权限控制。它并没有提供具体的实现方式,仅仅是提供了指导性的文档和几个注解,由具体的框架去实现。

javax.annotation 中包含一下几个注解:

  • @Generated:生成资源的注解,通过该项标记产生的实例是一个资源。类似于Spring中的@Bean注解,用于生成一向资源。
  • @PostConstruct 创造资源之后的回调处理,Spring已经实现了这个注解,见Bean的定义与控制 一文的介绍。
  • @PreDestroy 销毁资源之前的回调处理,Spring同样实现了这个注解,见Bean的定义与控制
  • @Resource 标记使用资源的位置,Spring同样实现了这个注解的功能(后文会详细介绍)。功能上有些类似于@Autowired、@Inject,但是两者有不少的差别。
  • @Resources 标记使用多项资源的位置,类似于使用@Autowired向一个列表装载数据。

仔细看JSR-250定义的这些注解就会发现,他们都是关于“资源”的构建、销毁、使用的。Spring实现了@PostConstruct、@PreDestroy和@Resource。

javax.annotation.security 包中有以下内容:

  • @DeclareRoles 声明角色
  • @DenyAll  拒绝所有角色
  • @PermitAll  授权所有惧色
  • @RolesAllowed  角色授权
  • @RunAs 运行模式

security中的内容是在资源创建之后对资源的使用进行管理。和常规的权限控制模型一样——定义角色(@DeclareRoles )、确定角色对资源的控制权限(@DenyAll、@PermitAll 、@RolesAllowed )。Spring并没有实现这里的任何一个注解,在这里就不深入介绍了。这一块内容在J2EE的构建中有不少的应用。

Spring中的@Resource

在没有仔细看Spring的官方文档和JSR-250之前,我一直以为@Resource这个注解和@Autowired是2个不同的功能,更早的时候还以为是管理什么Properties资源的,很多网上的内容也写得比较模糊。虽然@Resource的实现是在 CommonAnnotationBeanPostProcessor 而@Autowired 是在 AutowiredAnnotationBeanPostProcessor,但是实际上两者的功能是重叠的,或者说@Resource的提供的功能是@Autowired的子集。

在Spring中使用@Resource注解时,把Bean理解为一项资源就很好理解了。下面通过一些简单的例子来介绍@Resource的使用。

@Resource的功能是告诉IoC容器标记的位置需要什么样的“资源”,如下:

代码语言:javascript
复制
class Abc {}
class Xyz {}
class Implement {
	@Resource
	private Abc abc;
	
	private Xyz xyz;

    @Resource
    private ApplicationContext context;

	@Resource(name="b_instance")
	public void setInject(Xyz xyz) {
		this.xyz = xyz;
	}
}
代码语言:javascript
复制
<beans>
    <context:annotation-config/>
    <bean id="abc" class="x.y.Abc" />
    <bean id="xyz_instance" name="inject" class="x.y.Xyz" />
    <bean class="x.y.Implement" />
</beans>

运行后,IoC会向标记了@Resource的位置注入Bean——是不是感觉和@Autowired一模一样?但是需要注意的是虽然两者最后都是注入一个Bean,但是@Resource和@Autowired的处理过程是不一样的。@Autowired如果没有提供任何参数,那么他优先按照类型注入,如果要对细节进行控制可以配合Primary和Qualifiers功能,详见注解自动装载的介绍。@Resource是按照命名来注入资源的,以上面的代码为例子:

  1. 例如在setter方法上定义了name="xyz_instance"参数,那么会去IoC容器中寻找id、name等于"xyz_instance"的Bean来注入。
  2. 例如在abc这个域(成员变量)上没有定义name参数,那么会使用域的名称(这里是"abc")去IoC中按id、name寻找Bean来注入。
  3. 如果@Resource定义在方法上,并且没有指定name参数,那么他会使用setter的名称(例子中方法名为setInject,名称就是"inject")来寻找并注入数据。
  4. 最后,如果名称匹配不上,容器会根据标记位置的类型来注入数据,例如例如中的ApplicationContext。

所以@Resource的装载资源过程是:1)匹配name参数;2)没有name参数时会根据setter或域的名称来匹配Bean的名称;3)还是匹配不上就根据标记位置的类型来注入数据。

与@Autowired相比主要有以下几点区别:

  1. 控制粒度没有@Autowired细,某些参数Spring并没有实现功能。但是使用他更符合整个Java生态的规范。
  2. 如果是使用类型依赖注入数据,应优先使用@Autowired,效率会好一些。
  3. @Resource通过名称注入与@Autowired相比省去了@Qualifiers等内容。
  4. @Resource只能用在域和Setter方法上。

总的来说如果是按照类型注入依赖对象,那么最终得到的结果并没有任何差异,只是执行过程上有差别。如果按Bean的名称使用,@Resource比@Autowired便捷一些,但是功能少很多。

个人建议如果开发的是一个面向终端用户的应用,比如Web应用、网站什么的,直接用@Autowired就好了。如果制作的是一个给别的开发人员使用的工具,可以考虑@Resourec,他能得到更多框架的支持。

@PostConstruct 与@PreDestroy

@PostConstruct 与@PreDestroy也是JSR-250中定义的注解,Spring都实现了他们的功能,使用方法可以查看 Bean的定义与控制 相关的说明和介绍。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • JSR-175与元编程
  • JSR-250的Spring实现
  • Spring中的@Resource
  • @PostConstruct 与@PreDestroy
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档