美文网首页
了解下Spring依赖注入几个常用注解

了解下Spring依赖注入几个常用注解

作者: 艺术类架构师 | 来源:发表于2019-07-07 14:50 被阅读0次

开发中经常用到的注解有以下几个:
①:@Autowired:是(JSR-330)javax.inject.inject的替代形式,实现Spring依赖注入的一种形式,可以装配对象,设置对象依赖,注入Setter方法,找到多个Bean对象时需要用@Qualifier限定使用哪个Bean。
使用示例:

方式1:

    @Autowired(required=true)
    IDemoService autowiredService;

备注:required=true代表依赖是必须的,false代表依赖不是必然的。

方式2:

    @Autowired
    @Qualifier("autowiredDemoService")
    IDemoService autowiredService;

备注:当存在多个Bean实例时@Qualifier起到指定候选Bean的作用。

如何注入对象的同时再设置被注入对象的属性值。
可以有三种形式,作用都一样,只不过其代理实现机制不一样而已。

    @Autowired
    void setResponseByAutowired(AutowiredDemoService autowiredService) {
        autowiredService.setOk("autowired response");
    }

   @Resource
    void setResponseWithResouceAnnotation(AutowiredDemoService autowiredService) {
        autowiredService.setOk("resource response");
    }


    @Inject
    void setResponseByAutowiredAgain(AutowiredDemoService autowiredService) {
        autowiredService.setOk("autowiredAgain response");
    }

源码分析:
@Autowired由AutowiredAnnotationBeanPostProcessor实现,它里面有两个重要的内部类,AutowiredFieldElement和AutowiredMethodElement,这两个类都继承自InjectionMetadata.InjectedElement,并重写了inject(注入方法),这两个类的作用一个是注解在属性字段的注入,另一个是注解在方法上的注入。

简单说一下这个类里面的其他方法是做什么用的。

Method:findAutowiringMetadata->找到所有装配的元数据
Method:registerDependentBeans ->将指定的Bean注册它的依赖Bean(比方说;xxService注册到xxController中去)

②:@Resource:资源标记注解,由J2EE提供的注解(javax.annotation.Resource)。当组件初始化时,容器将向应用程序组件注入请求资源的实例。重点就是:标记应用程序所需的资源,资源在Spring中可能以Component,Service,以@Bean注入形式等。@Resource默认是ByName方式注入资源。

特性:支持byName,byType多种形式。

@Resource注解核心实现实在类CommonAnnotationBeanPostProcessor中实现的,我们就简单说一下这个类针对Resource做了什么用。
通过查看源码得出,里面有一个内部类:ResourceElement,还有一个重要方法:buildResourceMetadata->构建ResourceMetaData(Resource元素据)

//构造ResourceElement函数
   public ResourceElement(Member member, AnnotatedElement ae, @Nullable PropertyDescriptor pd) {
    Resource resource = ae.getAnnotation(Resource.class);
            String resourceName = resource.name();
            Class<?> resourceType = resource.type();
            this.isDefaultName = !StringUtils.hasLength(resourceName);
            if (this.isDefaultName) {
                resourceName = this.member.getName();
                if (this.member instanceof Method && resourceName.startsWith("set") && resourceName.length() > 3) {
                    resourceName = Introspector.decapitalize(resourceName.substring(3));
                }
            }
            else if (embeddedValueResolver != null) {
                resourceName = embeddedValueResolver.resolveStringValue(resourceName);
            }
            if (Object.class != resourceType) {
                checkResourceType(resourceType);
            }
            else {
                // No resource type specified... check field/method.
                resourceType = getResourceType();
            }
            this.name = (resourceName != null ? resourceName : "");
            this.lookupType = resourceType;
            String lookupValue = resource.lookup();
            this.mappedName = (StringUtils.hasLength(lookupValue) ? lookupValue : resource.mappedName());
            Lazy lazy = ae.getAnnotation(Lazy.class);
            this.lazyLookup = (lazy != null && lazy.value());
        }

@Resource和@Autowired的相同点:

①:都是注解形式,都可以用来依赖注入,都可以以配置在属性上的形式依赖一个Bean,也可以以Setter形式注入一个Bean.两者的注入形式都可以被javax.inject.Inject注解取代。

②:两者都依赖于Spring上下文,都需要先获取BeanFacotry之后,再由BeanFactory去解析Bean,装配Bean等动作。

③:他们俩都可以配置延时加载(以@Lazy配置使用,这样做时用到时才会装配,才会报错,与懒加载是一层意思。

@Resource和@Autowired的不同点:
①:来源不同,@Resource是J2EE里面的注解,不依赖于Spring.
@Autowired是来自于Spring-Beans里面的注解,必须在Spring容器中才能使用,并依赖于Spring上下文。

②:使用的范围@Resource比@Autowired更广泛,@Resource除了ByType之外还可以ByName。@Resource指定name时相当于@Autowired与@Qualifer组合使用.

③:@Resource可以设置一定的容错性,可以配置lookUp,可以指定Type来装配。

相关文章

网友评论

      本文标题:了解下Spring依赖注入几个常用注解

      本文链接:https://www.haomeiwen.com/subject/xzqphctx.html