本站提供最佳jieba源码服务,欢迎转载和分享。

【深圳源码计算】【npm 源码】【paly源码】@resource源码

2024-11-25 05:29:32 来源:hgem2源码 分类:百科

1.为什么@Resource出错
2.注解@Autowired和@Resource的源码区别总结
3.如何理解@Resource和@Reference的区别

@resource源码

为什么@Resource出错

       看spring2.0源码中的 InputStreamResource类中的isOpen() 方法:

       /

**

        * This implementation always returns <code>true</code>.

        */

        public boolean isOpen() {

        return true;

        }

       这个方法永远返回true。

        再看这个方法:

       /

**

        * Detects which kind of validation to perform on the XML file identified

        * by the supplied { @link Resource}. If the

        * file has a <code>DOCTYPE</code> definition then DTD validation is 源码used

        * otherwise XSD validation is assumed.

        */

        protected int detectValidationMode(Resource resource) {

        if (resource.isOpen()) {

        throw new BeanDefinitionStoreException(

        "Passed-in Resource [" + resource + "] contains an open stream: " +

        "cannot determine validation mode automatically. Either pass in a Resource " +

        "that is able to create fresh streams, or explicitly specify the validationMode " +

        "on your XmlBeanDefinitionReader instance.");

        }

        ... ...

        }

        由于resource.isOpen()永远返回true,所以这里会抛出异常。源码我的源码理解是:InputStreamResource是直指向输入流InputStream的,在构造InputStreamResource时,源码我们要加载的源码深圳源码计算资源第一次被打开后, 即InputStreamResource的源码getInputStream()方法调用后, 不允许再次读取资源对应的源码InputStream。下面是源码getInputStream()方法,可以看到,源码InputStreamResource用私有的源码属性 read来标记输入流是否被读取过, 若读取过一次,源码 再次读取会抛异常的源码npm 源码

       /

**

        * This 源码implementation throws IllegalStateException if attempting to

        * read the underlying stream multiple times.

        */

        public InputStream getInputStream() throws IOException, IllegalStateException {

        if (this.read) {

        throw new IllegalStateException("InputStream has already been read - " +

        "do not use InputStreamResource if a stream needs to be read multiple times");

        }

        this.read = true;

        return this.inputStream;

        }

        然而从spring2.0开始,为了支持xml schema,源码需要再次读取资源以检查配置文件是否遵循了DTD 和 xml schema, 又由于当前被打开的资源不能被多次读取, 以致异常抛出。从下面spring源码中关于InputStreamResource类的paly源码说明中可以看到,作者强烈建议不要使用InputStreamResource, 而是尽量使用替代者ByteArrayResource、ClassPathResource、FileSystemResource、UrlResource等来加载xml等资源。

        InputStreamResource类是tbsdemo源码为给定的InputStream而准备的Resource接口的实现。它只有在没有其它合适的Resource接口实现类可用时才使用。而且,只要有可能就尽量使用ByteArrayResource或者其它基于文件的Resource实现。与其它Resource实现不同的是,这是个已经打开资源的描述符(因此isOpen()函数返回 true)。如果你需要在其它位置保持这个资源的lineagem 源码描述符或者多次读取一个流,请不要使用它。

       /

**

        * { @link Resource} implementation for a given InputStream. Should only

        * be used if no specific Resource implementation is applicable.

        * In particular, prefer { @link ByteArrayResource} or any of the

        * file-based Resource implementations where possible.

       

*

        * <p>In contrast to other Resource implementations, this is a descriptor

        * for an <i>already opened</i> resource - therefore returning "true" from

        * <code>isOpen()</code>. Do not use it if you need to keep the resource

        * descriptor somewhere, or if you need to read a stream multiple times.

       

*

        * @author Juergen Hoeller

        * @since ..

        * @see ByteArrayResource

        * @see ClassPathResource

        * @see FileSystemResource

        * @see UrlResource

        */

        public class InputStreamResource extends AbstractResource { ...}

       引一段springsource站网友的解释, 供参考:

        This is caused by Spring 2.0's new support for XML schema: We need to sneak into the file to find out whether it's based on our DTD or our schema now. Simply assuming the DTD as default in that case could cause strange exceptions in the XML parser that would only arise with such an InputStream specified.

        The recommended solution is the same as the general resource loading recommendation of the past two years:Do not use InputStreamResource unless explicitly necessary.

注解@Autowired和@Resource的区别总结

       @Autowired和@Resource是Spring框架中常见的依赖注入注解,但它们的注入机制和处理略有不同。接下来,我们将从源码角度深入剖析它们的注入过程。

       @Autowired总结:

       - 注入流程涉及AutowiredAnnotationBeanPostProcessor,首先检查属性或方法上的@Autowired,构建AutowiredFieldElement或AutowiredMethodElement。

       - 如果未启用懒加载,AutowiredFieldElement会通过DefaultListableBeanFactory的resolveDependency方法寻找并注入bean,包括候选bean的查找和确定。

       @Resource总结:

       - CommonAnnotationBeanPostProcessor的buildResourceMetadata方法是切入点,只对非静态、非忽略类型的字段创建ResourceElement对象。

       - ResourceElement对象的getResourceToInject方法负责获取bean,通过autowireResource方法调用。

       源码分析:

       1. @Autowired的注入过程涉及AutowiredAnnotationBeanPostProcessor的多个内部方法,如doResolveDependency和findAutowireCandidates,处理了候选bean的选择和懒加载机制。

       2. @Resource的流程在CommonAnnotationBeanPostProcessor中更为直接,主要通过ResourceElement类的getResourceToInject方法获取bean。

       学习更多关于Java和Spring的深入知识,如MyBatis、ZooKeeper等,持续关注博主的更新。

如何理解@Resource和@Reference的区别

       1,定义:

        @Resource:spring的注解,作用:spring中获取已经注入到spring中的Bean

        @Reference: dubbo的注解,作用:注入duboo服务的对象

        2,遇到问题:

        本地配置:

        报错:No provider available from registry **** for service ------------

        哇,经典报错,一看错误就以为是生产者没有启动喽,去zk上面看dubbo生产者情况,真的没有,问题好像已经找到了,,等等,忽然发现他为什么去的是 registry 1呢,不应该去1和2都找吗? 对了,@Reference 注册dubbo不管是什么方式,无非是registry 和 version等指定,由于我没有指定,那按照spring的理解肯定是走自动装配喽,那我这边配置了两个注册中心,是不是他会智能的都找找呢?(不是的,dubbo生产者如果指定多个registry,然后<dubbo:service/>声明的服务会注册到多个注册中心,<dubbo:reference/>消费端多注册中心时是需要指定去哪个注册中心的)我不想在@Reference后面写一大堆,就想走自动化装配,最后找到可以在registry声明时 default 的属性的,

        根据一系列的猜测、我把配置改为了:

        自此问题解决了,,,,,

        我发现新的问题:使用@Reference来注入dubbo服务,那如果我项目中多个地方想使用,我在多个类中使用@Reference ,岂不是注入多个bean了(这个理解是有问题的,这时未意识到)。这显然是有问题的,因此我想将dubbo服务以单例注入到spring中,换成 spring自己的@Resource标签来获取,因此我将配置改成了一下:

        测试一下:确实好使,,自此配置使用方面没什么问题了,符合一个人的正常逻辑了,

        但是还有一个问题,就是:

        “我发现新的问题:使用@Reference来注入dubbo服务,那如果我项目中多个地方想使用,我在多个类中使用@Reference ,岂不是注入多个bean了 ”  è¿™ä¸ªé—®é¢˜çœŸçš„存在吗?

        下面来解答这个问题:

        spring的配置 使用 xml 或者注解 只是 使用方式的不同,@Reference 和 <dubbo:reference/> 的效果应该是是一样的, spring默认注入Bean,scope应该是singleton ,  那我在多个类中使用@Reference 注入同一个dubbo服务应该是在spring中只存在一个了,,事实上的是的,

        多个@Reference 标签 注入配置信息完全相同的 服务 ,是会有服务Bean缓存的,保证只会有一个 服务Bean ,源码如下:  这个方法 generateReferenceBeanCacheKey  是缓存key的获取。。

       private ReferenceBean<?> buildReferenceBean(Reference reference, Class<?> referenceClass) throws Exception {         // 获取服务引用对象的缓存key        String referenceBeanCacheKey = generateReferenceBeanCacheKey(reference, referenceClass);        // 从缓存map中获取服务引用对象        ReferenceBean<?> referenceBean = referenceBeansCache.get(referenceBeanCacheKey);        if (referenceBean == null) {             // 如果引用对象为空,则需要当场创建一个            ReferenceBeanBuilder beanBuilder = ReferenceBeanBuilder                    .create(reference, classLoader, applicationContext)                    .interfaceClass(referenceClass);            referenceBean = beanBuilder.build();            //并且放入到缓存map中。            referenceBeansCache.putIfAbsent(referenceBeanCacheKey, referenceBean);        }        return referenceBean;    } private String generateReferenceBeanCacheKey(Reference reference, Class<?> beanClass) {         // 获取接口名称        String interfaceName = resolveInterfaceName(reference, beanClass);        // 通过引用的URl+接口名+接口版本号+接口分组,用来做缓存key        String key = reference.url() + "/" + interfaceName +                "/" + reference.version() +                "/" + reference.group();        Environment environment = applicationContext.getEnvironment();        key = environment.resolvePlaceholders(key);        return key;    }

        自此问题说明完毕。。

        问题整理:

        1,多注册中心时,spring 自动化装配时,需要自己指定 某一个注册中心 或者 将某个注册中心 default设置为true.

        2, @Resource 和 @Reference 都可 注入 dubbo服务但是 概念是不一样的。

        3,@Reference 注解可以在多个类中注入 相同服务Bean 不会造成服务Bean 存在多个。。

        注:源码参考 文章 /article/

【本文网址:http://5o.net.cn/news/91f251797391.html 欢迎转载】

copyright © 2016 powered by 皮皮网   sitemap