我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Java Spring中各依赖注入注解的区别是什么

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Java Spring中各依赖注入注解的区别是什么

本篇文章给大家分享的是有关Java Spring中各依赖注入注解的区别是什么,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。

Spring对于Bean的依赖注入,支持多种注解方式:

@Resource javax.annotation JSR250 (Common Annotations for Java)  @Inject javax.inject JSR330 (Dependency Injection for Java)  @Autowired org.springframework.bean.factory Spring

直观上看起来,@Autowired是Spring提供的注解,其他几个都是JDK本身内建的注解,Spring对这些注解也进行了支持。但是使用起来这三者到底有什么区别呢?笔者经过方法的测试,发现一些有意思的特性。

区别总结如下:

一、@Autowired有个required属性,可以配置为false,这种情况下如果没有找到对应的bean是不会抛异常的。@Inject和@Resource没有提供对应的配置,所以必须找到否则会抛异常。

二、  @Autowired和@Inject基本是一样的,因为两者都是使用AutowiredAnnotationBeanPostProcessor来处理 依赖注入。但是@Resource是个例外,它使用的是CommonAnnotationBeanPostProcessor来处理依赖注入。当然,两者 都是BeanPostProcessor。

@Autowired和@Inject - 默认 autowired by type - 可以 通过@Qualifier 显式指定 autowired by qualifier name。 - 如果 autowired by type 失败(找不到或者找到多个实现),则退化为autowired by field name  @Resource - 默认 autowired by field name - 如果 autowired by field name失败,会退化为 autowired by type - 可以 通过@Qualifier 显式指定 autowired by qualifier name - 如果 autowired by qualifier name失败,会退化为 autowired by field name。但是这时候如果 autowired by field name失败,就不会再退化为autowired by type了。

TIPS Qualified name VS Bean name

在Spring设计中,Qualified name并不等同于Bean  name,后者必须是***的,但是前者类似于tag或者group的作用,对特定的bean进行分类。可以达到getByTag(group)的效果。对 于XML配置的bean,可以通过id属性指定bean name(如果没有指定,默认使用类名首字母小写),通过标签指定qualifier  name:

<bean id="lamborghini" class="me.arganzheng.study.spring.autowired.Lamborghini">     <qualifier value="luxury"/>     <!-- inject any dependencies required by this bean --> </bean>

如果是通过注解方式,那么可以通过@Qualifier注解指定qualifier name,通过@Named或者@Component(@Service,@Repository等)的value值指定bean name:

@Component("lamborghini") @Qualifier("luxury") public class Lamborghini implements Car { }

或者

@Component @Named("lamborghini") @Qualifier("luxury") public class Lamborghini implements Car { }

同样,如果没有指定bean name,那么Spring会默认是用类名首字母小写(Lamborghini=>lamborghini)。

三、 通过Anotation注入依赖的方式在XML注入方式之前进行。如果对同一个bean的依赖同时使用了两种注入方式,那么XML的优先。但是不同担心通过Anotation注入的依赖没法注入XML中配置的bean,依赖注入是在bean的注册之后进行的。

四、目前的autowired by  type方式(笔者用的是3.2.3.RELEASE版本),Spring的AutowiredAnnotationBeanPostProcessor 实现都是有”bug”的,也就是说@Autowired和@Inject都是有坑的(称之为坑,不称之为bug是因为貌似是故意的。。)。这是来源于线上 的一个bug,也是这边文章的写作原因。现场如下:

application-context.xml中有如下定义:

<xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans"     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"     xmlns:context="http://www.springframework.org/schema/context"     xmlns:util="http://www.springframework.org/schema/util"     xsi:schemaLocation="         http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd         http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd         http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd         http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.5.xsd">      <context:annotation-config />      <context:component-scan base-package="me.arganzheng.study" />      <util:constant id="en"         static-field="me.arganzheng.study.spring.autowired.Constants.Language.EN" />     <util:constant id="ja"         static-field="me.arganzheng.study.spring.autowired.Constants.Language.JP" />     <util:constant id="ind"         static-field="me.arganzheng.study.spring.autowired.Constants.Language.IND" />     <util:constant id="pt"         static-field="me.arganzheng.study.spring.autowired.Constants.Language.PT" />     <util:constant id="th"         static-field="me.arganzheng.study.spring.autowired.Constants.Language.TH" />     <util:constant id="ar"         static-field="me.arganzheng.study.spring.autowired.Constants.Language.AR" />     <util:constant id="en-rIn"         static-field="me.arganzheng.study.spring.autowired.Constants.Language.EN_RIN" />      <util:map id="languageChangesMap" key-type="java.lang.String"         value-type="java.lang.String">         <entry key="pt" value="pt" />         <entry key="br" value="pt" />         <entry key="jp" value="ja" />         <entry key="ja" value="ja" />         <entry key="ind" value="ind" />         <entry key="id" value="ind" />         <entry key="en-rin" value="en-rIn" />         <entry key="in" value="en-rIn" />         <entry key="en" value="en" />         <entry key="gb" value="en" />         <entry key="th" value="th" />         <entry key="ar" value="ar" />         <entry key="eg" value="ar" />     </util:map>  </beans>

其中static-field应用的常量定义在如下类中:

package me.arganzheng.study.spring.autowired;  public interface Constants {      public interface Language {         public static final String EN = "CommonConstants.LANG_ENGLISH";         public static final String JP = "CommonConstants.LANG_JAPANESE";         public static final String IND = "CommonConstants.LANG_INDONESIAN";         public static final String PT = "CommonConstants.LANG_PORTUGUESE";         public static final String TH = "CommonConstants.LANG_THAI";         public static final String EN_RIN = "CommonConstants.LANG_ENGLISH_INDIA";         public static final String AR = "CommonConstants.LANG_Arabic";     } }

然后如果我们在代码中如下声明依赖:

public class AutowiredTest extends BaseSpringTestCase {      @Autowired     private Map<String, String> languageChangesMap;      @Test     public void testAutowired() {         notNull(languageChangesMap);         System.out.println(languageChangesMap.getClass().getSimpleName());         System.out.println(languageChangesMap);     } }

Guess what,诡异的事情发生了!

运行结果如下:

LinkedHashMap {en=CommonConstants.LANG_ENGLISH, ja=CommonConstants.LANG_JAPANESE, ind=CommonConstants.LANG_INDONESIAN, pt=CommonConstants.LANG_PORTUGUESE, th=CommonConstants.LANG_THAI, ar=CommonConstants.LANG_Arabic, en-rIn=CommonConstants.LANG_ENGLISH_INDIA}

也就是说Map

严重: Caught exception while allowing TestExecutionListener [org.springframework.test.context.support.DependencyInjectionTestExecutionListener@5c51ee0a] to prepare test instance [me.arganzheng.study.spring.autowired.AutowiredTest@6e301e0] org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'me.arganzheng.study.spring.autowired.AutowiredTest': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private java.util.Map me.arganzheng.study.spring.autowired.AutowiredTest.languageChangesMap; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [java.lang.String] found for dependency [map with value type java.lang.String]: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
... ed by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [java.lang.String] found for dependency [map with value type java.lang.String]: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)} at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:986) at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:843) at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:768) at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:486) ... 28 more

debug了一下,发现确实是Spring的一个bug。在DefaultListableBeanFactory的这个方法出问题了:

protected Object doResolveDependency(DependencyDescriptor descriptor, Class<?> type, String beanName,             Set<String> autowiredBeanNames, TypeConverter typeConverter) throws BeansException {         ...              else if (Map.class.isAssignableFrom(type) && type.isInterface()) {             Class<?> keyType = descriptor.getMapKeyType();             if (keyType == null || !String.class.isAssignableFrom(keyType)) {                 if (descriptor.isRequired()) {                     throw new FatalBeanException("Key type [" + keyType + "] of map [" + type.getName() +                             "] must be assignable to [java.lang.String]");                 }                 return null;             }             Class<?> valueType = descriptor.getMapValueType();             if (valueType == null) {                 if (descriptor.isRequired()) {                     throw new FatalBeanException("No value type declared for map [" + type.getName() + "]");                 }                 return null;             }             Map<String, Object> matchingBeans = findAutowireCandidates(beanName, valueType, descriptor);             if (matchingBeans.isEmpty()) {                 if (descriptor.isRequired()) {                     raiseNoSuchBeanDefinitionException(valueType, "map with value type " + valueType.getName(), descriptor);                 }                 return null;             }             if (autowiredBeanNames != null) {                 autowiredBeanNames.addAll(matchingBeans.keySet());             }             return matchingBeans;         }         ...     }

关键在这一句:Map

严重: Caught exception while allowing TestExecutionListener [org.springframework.test.context.support.DependencyInjectionTestExecutionListener@9476189] to prepare test instance [me.arganzheng.study.spring.autowired.AutowiredTest@2d546e21] ... Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [java.lang.String] found for dependency [map with value type java.lang.String]: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true), @org.springframework.beans.factory.annotation.Qualifier(value=languageChangesMap)}     at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:986)     at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:843)     at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:768)     at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:486)     ... 28 more

debug了一下,发现跟没有指定qualifie name是一样的执行路径。不是指定了bean name了吗?为什么还是autowired  by  type呢?仔细查看了一下才发现。DefaultListableBeanFactory的doResolveDependency方法对首先对类型做 了区别:

protected Object doResolveDependency(DependencyDescriptor descriptor, Class<?> type, String beanName,             Set<String> autowiredBeanNames, TypeConverter typeConverter) throws BeansException {          Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor);         if (value != null) {             if (value instanceof String) {                 String strVal = resolveEmbeddedValue((String) value);                 BeanDefinition bd = (beanName != null && containsBean(beanName) ? getMergedBeanDefinition(beanName) : null);                 value = evaluateBeanDefinitionString(strVal, bd);             }             TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());             return (descriptor.getField() != null ?                     converter.convertIfNecessary(value, type, descriptor.getField()) :                     converter.convertIfNecessary(value, type, descriptor.getMethodParameter()));         }          if (type.isArray()) {             Class<?> componentType = type.getComponentType();             Map<String, Object> matchingBeans = findAutowireCandidates(beanName, componentType, descriptor);             if (matchingBeans.isEmpty()) {                 if (descriptor.isRequired()) {                     raiseNoSuchBeanDefinitionException(componentType, "array of " + componentType.getName(), descriptor);                 }                 return null;             }             if (autowiredBeanNames != null) {                 autowiredBeanNames.addAll(matchingBeans.keySet());             }             TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());             return converter.convertIfNecessary(matchingBeans.values(), type);         }         else if (Collection.class.isAssignableFrom(type) && type.isInterface()) {             Class<?> elementType = descriptor.getCollectionType();             if (elementType == null) {                 if (descriptor.isRequired()) {                     throw new FatalBeanException("No element type declared for collection [" + type.getName() + "]");                 }                 return null;             }             Map<String, Object> matchingBeans = findAutowireCandidates(beanName, elementType, descriptor);             if (matchingBeans.isEmpty()) {                 if (descriptor.isRequired()) {                     raiseNoSuchBeanDefinitionException(elementType, "collection of " + elementType.getName(), descriptor);                 }                 return null;             }             if (autowiredBeanNames != null) {                 autowiredBeanNames.addAll(matchingBeans.keySet());             }             TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());             return converter.convertIfNecessary(matchingBeans.values(), type);         }         else if (Map.class.isAssignableFrom(type) && type.isInterface()) {             Class<?> keyType = descriptor.getMapKeyType();             if (keyType == null || !String.class.isAssignableFrom(keyType)) {                 if (descriptor.isRequired()) {                     throw new FatalBeanException("Key type [" + keyType + "] of map [" + type.getName() +                             "] must be assignable to [java.lang.String]");                 }                 return null;             }             Class<?> valueType = descriptor.getMapValueType();             if (valueType == null) {                 if (descriptor.isRequired()) {                     throw new FatalBeanException("No value type declared for map [" + type.getName() + "]");                 }                 return null;             }             Map<String, Object> matchingBeans = findAutowireCandidates(beanName, valueType, descriptor);             if (matchingBeans.isEmpty()) {                 if (descriptor.isRequired()) {                     raiseNoSuchBeanDefinitionException(valueType, "map with value type " + valueType.getName(), descriptor);                 }                 return null;             }             if (autowiredBeanNames != null) {                 autowiredBeanNames.addAll(matchingBeans.keySet());             }             return matchingBeans;         }         else {             Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);             if (matchingBeans.isEmpty()) {                 if (descriptor.isRequired()) {                     raiseNoSuchBeanDefinitionException(type, "", descriptor);                 }                 return null;             }             if (matchingBeans.size() > 1) {                 String primaryBeanName = determinePrimaryCandidate(matchingBeans, descriptor);                 if (primaryBeanName == null) {                     throw new NoUniqueBeanDefinitionException(type, matchingBeans.keySet());                 }                 if (autowiredBeanNames != null) {                     autowiredBeanNames.add(primaryBeanName);                 }                 return matchingBeans.get(primaryBeanName);             }             // We have exactly one match.             Map.Entry<String, Object> entry = matchingBeans.entrySet().iterator().next();             if (autowiredBeanNames != null) {                 autowiredBeanNames.add(entry.getKey());             }             return entry.getValue();         }     }

如果是Array,Collection或者Map,则根据集合类中元素的类型来进行autowired by  type(Map使用value的类型)。为什么这么特殊处理呢?原来,Spring是为了达到这样的目的:让你可以一次注入所有符合类型的实现,也就是 说可以这样子注入:

@Autowired private List<Car> cars;

如果你的car有多个实现,那么都会注入进来,不会再报

org.springframework.beans.factory.NoSuchBeanDefinitionException: No unique bean of type [me.arganzheng.study.spring.autowired.Car] is defined: expected single matching bean but found 2: [audi, toyota].  然而,上面的情况如果你用@Resource则不会有这个问题:  public class AutowiredTest extends BaseSpringTestCase {      @Resource     @Qualifier("languageChangesMap")     private Map<String, String> languageChangesMap;      @Test     public void testAutowired() {         assertNotNull(languageChangesMap);         System.out.println(languageChangesMap.getClass().getSimpleName());         System.out.println(languageChangesMap);     } }

正常运行:

LinkedHashMap {pt=pt, br=pt, jp=ja, ja=ja, ind=ind, id=ind, en-rin=en-rIn, in=en-rIn, en=en, gb=en, th=th, ar=ar, eg=ar}

当然,你如果不指定@Qualifier(“languageChangesMap”),同时field name不是languageChangesMap,那么还是一样报错的。

Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [java.lang.String] found for dependency [map with value type java.lang.String]: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@javax.annotation.Resource(shareable=true, mappedName=, description=, name=, type=class java.lang.Object, authenticationType=CONTAINER, lookup=)} at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:986) at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:843) at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:768) at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.autowireResource(CommonAnnotationBeanPostProcessor.java:438) at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.getResource(CommonAnnotationBeanPostProcessor.java:416) at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor$ResourceElement.getResourceToInject(CommonAnnotationBeanPostProcessor.java:550) at org.springframework.beans.factory.annotation.InjectionMetadata$InjectedElement.inject(InjectionMetadata.java:150) at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87) at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.postProcessPropertyValues(CommonAnnotationBeanPostProcessor.java:303) ... 26 more

而且,@Resource也可以实现上面的List接收所有实现:

public class AutowiredTest extends BaseSpringTestCase {      @Resource     @Qualifier("languageChangesMap")     private Map<String, String> languageChangesMap;      @Resource     private List<Car> cars;      @Test     public void testAutowired() {         assertNotNull(languageChangesMap);         System.out.println(languageChangesMap.getClass().getSimpleName());         System.out.println(languageChangesMap);          assertNotNull(cars);         System.out.println(cars.getClass().getSimpleName());         System.out.println(cars);     } }

运行的妥妥的:

LinkedHashMap {pt=pt, br=pt, jp=ja, ja=ja, ind=ind, id=ind, en-rin=en-rIn, in=en-rIn, en=en, gb=en, th=th, ar=ar, eg=ar} ArrayList [me.arganzheng.study.spring.autowired.Audi@579584da, me.arganzheng.study.spring.autowired.Toyota@19453122]

这是因为@Resource注解使用的是CommonAnnotationBeanPostProcessor处理器,跟 AutowiredAnnotationBeanPostProcessor不是同一个作者[/偷笑]。这里就不分析了,感兴趣的同学可以自己看代码研究 一下。

最终结论如下:

1、@Autowired和@Inject

autowired by type 可以 通过@Qualifier 显式指定 autowired by qualifier name(非集合类。注意:不是autowired by bean name!)
如果 autowired by type 失败(找不到或者找到多个实现),则退化为autowired by field name(非集合类)

2、@Resource

默认 autowired by field name
如果 autowired by field name失败,会退化为 autowired by type
可以 通过@Qualifier 显式指定 autowired by qualifier name
如果 autowired by qualifier name失败,会退化为 autowired by field name。但是这时候如果 autowired by field name失败,就不会再退化为autowired by type了

测试工程保存在GitHub上,是标准的maven工程,感兴趣的同学可以clone到本地运行测试一下。

补充

有同事指出Spring官方文档上有这么一句话跟我的结有点冲突:

However, although you can use this convention to refer to specific beans by name, @Autowired is fundamentally about type-driven injection with optional semantic qualifiers. This means that qualifier values, even with the bean name fallback, always have narrowing semantics within the set of type matches; they do not semantically express a reference to a unique bean id.

也就是说@Autowired即使加了@Qualifier注解,其实也是autowired by  type。@Qualifier只是一个限定词,过滤条件而已。重新跟进了一下代码,发现确实是这样子的。Spring设计的这个 @Qualifier  name 并不等同于 bean name。他有点类似于一个tag。不过如果这个tag是***的化,那么其实效果上等同于bean  name。实现上,Spring是先getByType,得到list candicates,然后再根据qualifier name进行过滤。

再定义一个兰博基尼,这里使用@Qualifier指定:

package me.arganzheng.study.spring.autowired;  import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Component;  @Component @Qualifier("luxury") public class Lamborghini implements Car {  }

再定义一个劳斯莱斯,这里故意用@Named指定:

package me.arganzheng.study.spring.autowired;  import javax.inject.Named;  import org.springframework.stereotype.Component;  @Component @Named("luxury") public class RollsRoyce implements Car {  }

测试一下注入定义的豪华车:

package me.arganzheng.study.spring.autowired;  import static junit.framework.Assert.assertNotNull;  import java.util.List;  import me.arganzheng.study.BaseSpringTestCase;  import org.junit.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier;   public class AutowiredTest extends BaseSpringTestCase {      @Autowired     @Qualifier("luxury")     private List<Car> luxuryCars;      @Test     public void testAutowired() {          assertNotNull(luxuryCars);         System.out.println(luxuryCars.getClass().getSimpleName());         System.out.println(luxuryCars);     }  }

运行结果如下:

ArrayList [me.arganzheng.study.spring.autowired.Lamborghini@66b875e1, me.arganzheng.study.spring.autowired.RollsRoyce@58433b76]

补充:Autowiring modes

Spring支持四种autowire模式,当使用XML配置方式时,你可以通过autowire属性指定。

no. (Default) No autowiring. Bean references must be defined via a ref element. Changing the default setting is not recommended for larger deployments, because specifying collaborators explicitly gives greater control and clarity. To some extent, it documents the structure of a system. byName. Autowiring by property name. Spring looks for a bean with the same name as the property that needs to be autowired. For example, if a bean definition is set to autowire by name, and it contains a master property (that is, it has a setMaster(..) method), Spring looks for a bean definition named master, and uses it to set the property. byType. Allows a property to be autowired if exactly one bean of the property type exists in the container. If more than one exists, a fatal exception is thrown, which indicates that you may not use byType autowiring for that bean. If there are no matching beans, nothing happens; the property is not set. constructor. Analogous to byType, but applies to constructor arguments. If there is not exactly one bean of the constructor argument type in the container, a fatal error is raised.

以上就是Java Spring中各依赖注入注解的区别是什么,小编相信有部分知识点可能是我们日常工作会见到或用到的。希望你能通过这篇文章学到更多知识。更多详情敬请关注编程网行业资讯频道。

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

Java Spring中各依赖注入注解的区别是什么

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Spring的依赖注入机制是什么

Spring的依赖注入(Dependency Injection,DI)机制是一种设计模式,用于实现对象之间的解耦和组件的松耦合。它通过将对象的依赖关系从代码中移除,而是将它们定义在配置文件中,由Spring容器负责管理和注入所需的依赖对象
2023-09-17

spring依赖注入的原理是什么

Spring依赖注入的原理是通过IOC(Inversion of Control)容器来实现的。IOC容器是Spring框架的核心,它负责创建对象、管理对象的生命周期以及解决对象之间的依赖关系。在IOC容器中,对象的依赖关系不再由对象自身管
2023-09-29

Java中的Spring框架是如何进行依赖注入的?(在Spring框架中,依赖注入的实现原理是什么?)

Spring框架中的依赖注入(DI)通过反射和注解,以及IoC容器实现。DI允许组件从外部接收依赖关系,提高了模块化和可维护性,降低了错误风险,并支持松散耦合。具体步骤包括配置bean、创建IoC容器、解析依赖关系、实例化bean和注入依赖关系。DI好处包括解耦组件、提高可测试性、减少错误、支持松散耦合和提高灵活性。
Java中的Spring框架是如何进行依赖注入的?(在Spring框架中,依赖注入的实现原理是什么?)
2024-04-02

Java依赖注入的方式是什么

这篇“Java依赖注入的方式是什么”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“Java依赖注入的方式是什么”文章吧。Spr
2023-07-02

mybatis TypeHandler注入spring依赖的方法是什么

这篇文章主要讲解了“mybatis TypeHandler注入spring依赖的方法是什么”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“mybatis TypeHandler注入spring
2023-06-29

Spring依赖注入的两种方式是什么

今天小编给大家分享一下Spring依赖注入的两种方式是什么的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。一、依赖注入方式思考
2023-07-02

laravel中依赖注入指的是什么

这篇文章给大家分享的是有关laravel中依赖注入指的是什么的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。laravel依赖注入一词是由Martin Fowler提出的术语,它是将组件注入到应用程序中的一种行为,
2023-06-22

Spring bean需要依赖注入的原因是什么

这篇文章主要介绍“Spring bean需要依赖注入的原因是什么”,在日常操作中,相信很多人在Spring bean需要依赖注入的原因是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Spring bean
2023-06-20

php依赖注入指的是什么

本篇内容介绍了“php依赖注入指的是什么”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!在PHP中,依赖注入是指对类的依赖通过构造器完成自动注
2023-06-29

Angular中依赖注入模式是什么

这篇文章主要介绍Angular中依赖注入模式是什么,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!Angular 依赖注入模式依赖注入: Dependency Injection 简称 DI依赖注入模式要解决的问题开发
2023-06-14

VSCode中依赖注入的原理是什么

这篇文章主要介绍“VSCode中依赖注入的原理是什么”,在日常操作中,相信很多人在VSCode中依赖注入的原理是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”VSCode中依赖注入的原理是什么”的疑惑有所
2023-07-05

Spring框架实现依赖注入的原理是什么

这篇文章主要介绍“Spring框架实现依赖注入的原理是什么”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Spring框架实现依赖注入的原理是什么”文章能帮助大家解决问题。Spring 框架作为 Ja
2023-07-06

php依赖注入的原理是什么

PHP依赖注入的原理是通过将一个对象的依赖关系通过构造函数、方法参数或者setter方法的方式进行传递。依赖注入的目的是解耦,使得代码更加灵活、可测试和可维护。具体来说,依赖注入原理包括以下几个步骤:1. 定义依赖关系:首先需要定义需要注入
2023-09-21

angular依赖注入的原理是什么

Angular的依赖注入(Dependency Injection)是一种设计模式,用于管理组件之间的依赖关系。它的原理是通过将组件所需的依赖项作为参数传递给组件的构造函数来实现。具体来说,Angular使用一个注入器(Injector)来
2023-09-21

laravel依赖注入的原理是什么

Laravel的依赖注入原理是基于反射的。依赖注入是一种设计模式,它的目的是通过将依赖对象的实例传递给需要它们的对象,来解耦和提高代码的可测试性和可维护性。在Laravel中,依赖注入是通过服务容器实现的。服务容器是一个用于管理类的实例的
2023-10-22

理解Spring中的依赖注入和控制反转

学习过Spring框架的人一定都会听过Spring的IoC(控制反转) 、DI(依赖注入)这两个概念,对于初学Spring的人来说,总觉得IoC 、DI这两个概念是模糊不清的,是很难理解的,今天和大家分享网上的一些技术大牛们对Spring框
2023-05-30

go语言依赖注入指的是什么

本篇内容介绍了“go语言依赖注入指的是什么”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!在go语言中,依赖注入(DI)是一种解耦组件之间依赖
2023-07-05

Web前端中依赖注入的方法是什么

本篇内容介绍了“Web前端中依赖注入的方法是什么”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!一、什么是IoCIoC 的全称叫做 Inver
2023-06-04

编程热搜

目录