Java Spring各种依赖注入注解的区别

合集下载

Spring常用的三种注入方式

Spring常用的三种注入方式

Spring常⽤的三种注⼊⽅式Spring通过DI(依赖注⼊)实现IOC(控制反转),常⽤的注⼊⽅式主要有三种:构造⽅法注⼊,setter注⼊,基于注解的注⼊。

构造⽅法注⼊先简单看⼀下测试项⽬的结构,⽤maven构建的,四个包:entity:存储实体,⾥⾯只有⼀个User类dao:数据访问,⼀个接⼝,两个实现类service:服务层,⼀个接⼝,⼀个实现类,实现类依赖于IUserDaotest:测试包在spring的配置⽂件中注册UserService,将UserDaoJdbc通过constructor-arg标签注⼊到UserService的某个有参数的构造⽅法<!-- 注册userService --><bean id="userService" class="erService"><constructor-arg ref="userDaoJdbc"></constructor-arg></bean><!-- 注册jdbc实现的dao --><bean id="userDaoJdbc" class="erDaoJdbc"></bean>如果只有⼀个有参数的构造⽅法并且参数类型与注⼊的bean的类型匹配,那就会注⼊到该构造⽅法中。

public class UserService implements IUserService {private IUserDao userDao;public UserService(IUserDao userDao) {erDao = userDao;}public void loginUser() {userDao.loginUser();}}@Testpublic void testDI() {ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");// 获取bean对象UserService userService = ac.getBean(UserService.class, "userService");// 模拟⽤户登录userService.loginUser();}测试打印结果:jdbc-登录成功注:模拟⽤户登录的loginUser⽅法其实只是打印了⼀条输出语句,jdbc实现的类输出的是:jdbc-登录成功,mybatis实现的类输出的是:mybatis-登录成功。

spring构造器注入多个构造函数_使用构造器注入的好处

spring构造器注入多个构造函数_使用构造器注入的好处

spring构造器注入多个构造函数_使用构造器注入的好处构造器注入是一种常用的依赖注入方式,用于将依赖对象通过构造函数的参数传入到目标对象中。

相比于其他依赖注入方式,构造器注入具有以下几个好处:1.显式依赖:通过构造器注入,我们可以清晰地看到目标对象所依赖的所有对象,以及它们之间的关系。

这样做可以帮助我们更好地理解和维护代码。

2.解耦:通过构造器注入,目标对象与其依赖对象解耦,它们之间的关系仅通过参数传递。

这样做可以提高代码的可测试性和可维护性,因为我们可以轻松地替换依赖对象,而不必修改目标对象的代码。

3.配置灵活:构造器注入可以让我们灵活地配置依赖对象。

通过不同的构造函数参数,我们可以传入不同的依赖对象实例,从而满足不同的需求。

这种灵活性可以帮助我们实现更复杂的业务逻辑。

4.可扩展性:构造器注入可以很容易地扩展目标对象的功能。

当需要添加新的依赖对象时,我们只需要新增一个构造函数,并在其中传入新的依赖对象即可。

这样做不会影响到原有的代码,同时也不会破坏目标对象与依赖对象之间的关系。

5.单元测试:构造器注入可以很方便地进行单元测试。

通过传入模拟的依赖对象,我们可以更好地控制测试环境,从而更容易发现和修复潜在的问题。

需要注意的是,构造器注入也有一些限制和潜在的问题。

首先,构造器注入需要在创建目标对象实例时传递所有的依赖对象,这可能会导致构造函数参数过多的问题。

此外,如果目标对象与其依赖对象之间存在循环依赖关系,构造器注入可能会遇到困难。

为了解决这些问题,我们可以通过使用工厂模式或者依赖注入容器来简化构造器注入的使用,并且更好地管理对象之间的依赖关系。

在Spring框架中,构造器注入是一种常用的依赖注入方式。

通过使用构造函数的参数,我们可以将依赖对象传递给目标对象。

Spring框架提供了多种方式来配置构造器注入,例如使用XML配置文件,使用注解或者使用Java配置类。

无论使用哪种方式,构造器注入都可以帮助我们实现松耦合、可测试和可扩展的代码。

spring四种依赖注入方式

spring四种依赖注入方式

s p r i n g四种依赖注入方式The document was finally revised on 2021博客分类:•??平常的java开发中,程序员在某个类中需要依赖其它类的方法,则通常是new 一个依赖类再调用类实例的方法,这种开发存在的问题是new的类实例不好统一管理,spring提出了依赖注入的思想,即依赖类不由程序员实例化,而是通过spring容器帮我们new指定实例并且将实例注入到需要该对象的类中。

依赖注入的另一种说法是“控制反转”,通俗的理解是:平常我们new一个实例,这个实例的控制权是我们程序员,而控制反转是指new实例工作不由我们程序员来做而是交给spring容器来做。

spring有多种依赖注入的形式,下面仅介绍spring通过xml进行IOC配置的方式:•Set注入这是最简单的注入方式,假设有一个SpringAction,类中需要实例化一个SpringDao对象,那么就可以定义一个private的SpringDao成员变量,然后创建SpringDao的set方法(这是ioc的注入入口):Java代码1.package?2.publicclassSpringAction{.>,这样其实是spring将SpringDaoImpl对象实例化并且调用SpringAction 的setSpringDao方法将SpringDao注入:Java代码1.<!--配置bean,配置后该类由spring管理-->?2.<beanname="springAction"class="">?3.4.<!--(1)依赖注入,配置当前类中相应的属性-->5.<propertyname="springDao"6.ref="springDao"></property>?7.8.</bean>9.<beanname="springDao"class=""></bean>?10.11.•构造器注入这种方式的注入是指带有参数的构造函数注入,看下面的例子,我创建了两个成员变量SpringDao和User,但是并未设置对象的set方法,所以就不能支持第一种注入方式,这里的注入方式是在SpringAction 的构造函数中注入,也就是说在创建SpringAction对象时要将SpringDao和User两个参数值传进来:Java代码1.publicclassSpringAction{态方法()"来获取对象,而是依然通过spring注入的形式获取:Java代码1.package?2.3.import?4.import?5.import?6.7.publicclassDaoFactory{1.."class="..."scope="prototype">。

Spring框架详细解析

Spring框架详细解析

Spring框架详细解析Spring框架是Java开发中最受欢迎的开源框架之一。

它提供了一个轻量级的容器,用于管理Java应用程序中的对象和依赖关系。

本文将详细解析Spring框架的核心特性及其在实际开发中的应用。

一、IoC容器Spring框架的核心是控制反转(Inversion of Control,简称IoC)容器。

IoC容器负责创建和管理Java对象的生命周期,使得开发者可以将对象的创建与对象之间的依赖关系交由框架来处理。

在Spring框架中,开发者通过配置文件或注解的方式,将需要由容器管理的类定义为Bean。

当应用程序启动时,IoC容器会根据配置文件或注解来实例化这些Bean,并自动解决它们之间的依赖。

通过使用IoC容器,开发者不再需要手动管理对象的创建和销毁,也可以轻松地解决对象之间的依赖关系,提高了代码的可维护性和可测试性。

二、依赖注入依赖注入(Dependency Injection,简称DI)是Spring框架的另一个重要特性。

通过依赖注入,开发者可以将一个对象的依赖关系传递给另一个对象,从而实现对象之间的松耦合。

Spring框架提供了三种注入方式:构造方法注入、属性注入和接口注入。

开发者可以根据实际需求选择最适合的注入方式。

在构造方法注入中,开发者通过构造方法的参数来传递依赖对象。

在属性注入中,开发者使用注解或配置文件来设置对象的属性值。

在接口注入中,开发者通过实现特定接口来完成依赖的注入。

通过使用依赖注入,开发者可以减少代码的耦合度,提高代码的可复用性和扩展性。

同时,依赖注入也使得开发者能够更加灵活地替换对象的依赖,从而实现代码的动态配置。

三、AOP编程面向切面编程(Aspect Oriented Programming,简称AOP)是Spring框架的另一个重要特性。

AOP通过将跨越多个类和模块的功能封装成切面,实现了横切关注点的代码复用。

在Spring框架中,开发者可以通过编写切面(Aspect)来定义切点(Pointcut),并在切点处织入增强(Advice)逻辑。

【转】Spring学习笔记1—依赖注入(构造器注入、set注入和注解注入)

【转】Spring学习笔记1—依赖注入(构造器注入、set注入和注解注入)

【转】Spring学习笔记1—依赖注⼊(构造器注⼊、set注⼊和注解注⼊)什么是依赖注⼊在以前的java开发中,某个类中需要依赖其它类的⽅法时,通常是new⼀个依赖类再调⽤类实例的⽅法,这种⽅法耦合度太⾼并且不容易测试,spring提出了依赖注⼊的思想,即依赖类不由程序员实例化,⽽是通过spring容器帮我们new指定实例并且将实例注⼊到需要该对象的类中。

依赖注⼊的⽅式依赖注⼊有3种⽅式:构造器注⼊、set注⼊和注解注⼊。

1.构造器注⼊构造器注⼊保证⼀些必要的属性在Bean实例化时就得到设置,并且确保了Bean实例在实例化后就可以使⽤。

使⽤⽅式:1. 在类中,不⽤为属性设置setter⽅法,但是需要⽣成该类带参的构造⽅法。

2. 在配置⽂件中配置该类的bean,并配置构造器,在配置构造器中⽤到了<constructor-arg>节点,该节点有四个属性index:指定注⼊属性的顺序索引,从0开始;type:指该属性所对应的类型;ref:引⽤的依赖对象;value:当注⼊的不是依赖对象,⽽是基本数据类型时,就⽤value;例⼦1:public class SpringAction {//注⼊对象springDaoprivate SpringDao springDao;private User user;public SpringAction(SpringDao springDao,User user){this.springDao = springDao;er = user;System.out.println("构造⽅法调⽤springDao和user");}public void save(){user.setName("卡卡");springDao.save(user);}}<bean name="springAction" class="com.bless.springdemo.action.SpringAction"><!--(2)创建构造器注⼊,如果主类有带参的构造⽅法则需添加此配置--><constructor-arg index="0" ref="springDao"></constructor-arg><constructor-arg index="1" ref="user"></constructor-arg></bean><bean name="springDao" class="com.bless.springdemo.dao.impl.SpringDaoImpl"></bean><bean name="user" class="er"></bean>其中index属性表⽰注⼊的bean在构造⽅法中的参数顺序。

论述spring依赖注入中注解分类、作用及应用方式

论述spring依赖注入中注解分类、作用及应用方式

论述spring依赖注入中注解分类、作用及应用方式spring依赖注入(DI)是把实例对象放在spring容器中运用注解注入进行实例依赖关系的维护,通常可分为以下几类:一、 Spring注解:1、 @Resource:该注解直接用欧文名字,如 applicationContext.xml 里定义的 bean 的名字作为注解的 value 属性,通过名字装配bean。

2、 @Autowired:该注解根据类型装配bean,如果项目中有多个实现类型的bean 那么需要标注 @Qualifier("beanName") 来指定注入bean为哪一个。

3、 @Value:该注解通过表达式来设置属性值,可以是一个字符串、某个bean 的属性值、某个配置文件的值等,例如@Value("#{systemProperties['']}"),表示从systemProperties取出为属性值4、 @PostConstruct:该注解标注的方法会在bean初始化的时候执行,也可以在配置文件中配置 init-method="methodName",当容器装配完成 bean 的时候会调用methodName 对应的方法5、 @PreDestroy:该注解标注的方法会在bean销毁的时候执行,也可以在配置文件中配置 destroy-method="methodName",当容器销毁 bean 的时候会调用methodName 对应的方法二、 JavaEE注解:1、 @javax.annotation.Resource :该注解可以直接通过它的 property name 属性来指定注入bean 名字2、 @javax.inject.Inject:该注解是JavaEE6 中出现的,和 @Autowired 一样可以根据类型装配bean三、其他的注解:1、 @Repository:该注解用来标注 Dao 层的组件,表明该组件是一个数据访问层的实现2、 @Service:该注解用来标注 Service 层的组件,表明是业务类组件3、 @Controller:该注解用来标注 controller 层的组件,进行请求处理这些注解有一些作用是相同的,比如都可以被spring容器所扫描到,但他们各有特殊用途,且使用方式也各有不同,以上便是spring依赖注入中注解分类、作用及应用方式的详细介绍。

SpringBean常用依赖注入方式详解

SpringBean常用依赖注入方式详解

SpringBean常⽤依赖注⼊⽅式详解⼀般⽽⾔,Spring的依赖注⼊有三种:构造器注⼊、setter注⼊以及接⼝注⼊。

本⽂主要讲构造器注⼊与setter注⼊。

1、构造器注⼊为了让Spring完成构造器注⼊,我们需要去描述具体的类、构造⽅法并设置构造⽅法的对应参数。

代码如下:public class Role {private Long id;private String roleName;private String note;public Long getId() {return id;}public void setId(Long id) {this.id = id;}public String getRoleName() {return roleName;}public void setRoleName(String roleName) {this.roleName = roleName;}public String getNote() {return note;}public void setNote(String note) {this.note = note;}public Role(String roleName, String note) {this.roleName = roleName;this.note = note;}public Role() {}public void run() {System.out.println("roleName:" + roleName + ";" + "note:" + note);}}这个时候是没有办法利⽤⽆参的构造⽅法去创建对象的,为了使Spring能正确创建这个对象,需要在xml⽂件中加⼊如下bean:<bean id="role1" class="com.ssm.chapter.pojo.Role"><constructor-arg index="0" value="总经理" /><constructor-arg index="1" value="公司管理者" /></bean>其中,constructor-arg元素⽤于定义类构造⽅法的参数,index⽤于定义参数的位置,⽽value是设置值,通过这样定义spring 便知道使⽤Role(String, String)这样的构造⽅法去创建对象了。

Java依赖注入的三种方式

Java依赖注入的三种方式

Java依赖注⼊的三种⽅式Spring通过DI(依赖注⼊)实现IOC(控制反转),常⽤的注⼊⽅式主要有三种:构造⽅法注⼊,setter注⼊,基于注解的注⼊。

构造⽅法注⼊构造器注⼊:保证了⼀些必要的属性在Bean实例化时就设置,并且确保了bean实例在实例化后就可以使⽤.1.在类中,不⽤为属性设置setter⽅法,只需提供构造⽅法即可2.在构造⽂件中配置该类bean,并配置构造器,在配置构造器中⽤//ApplicationContext.xml<bean id="action" class="erAction"><constructor-arg index ="0" name="name" value="Murphy"></constructor-arg></bean>提供构造⽅法public class UserAction {private String name;public UserAction(String name) { = name;}}setter注⼊1.根据property标签的name属性的值去找对应的setter⽅法.例如: name= “aa” 对应的就是setAa⽅法.2.由于属性注⼊具有可选性和灵活性⾼的优点,是实际上最常⽤的注⼊⽅式.3.属性注⼊要求bean提供⼀个默认的构造函数,并为需要注⼊的属性提供对应的setter⽅法.spring先调⽤bean默认的构造函数实例化bean对象,然后通过反射机制的⽅法调⽤setter⽅法注⼊属性值.4.还有⼀点需要注意:如果通过set⽅法注⼊属性,那么spring会通过默认的空参构造⽅法来实例化对象,所以如果在类中写了⼀个带有参数的构造⽅法,⼀定要把空参数的构造⽅法写上,否则spring没有办法实例化对象,导致报错。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

Spring对于Bean的依赖注入,支持多种注解方式:
直观上看起来,@Autowired是Spring提供的注解,其他几个都是JDK本身内建的注解,Spring 对这些注解也进行了支持。

但是使用起来这三者到底有什么区别呢?笔者经过方法的测试,发现一些有意思的特性。

区别总结如下:
一、@Autowired有个required属性,可以配置为false,这种情况下如果没有找到对应的bean 是不会抛异常的。

@Inject和@Resource没有提供对应的配置,所以必须找到否则会抛异常。

二、@Autowired和@Inject基本是一样的,因为两者都是使用AutowiredAnnotationBeanPostProcessor来处理依赖注入。

但是@Resource是个例外,它使用的是CommonAnnotationBeanPostProcessor来处理依赖注入。

当然,两者都是BeanPostProcessor。

TIPS Qualified name VS Bean name
在Spring设计中,Qualified name并不等同于Bean name,后者必须是唯一的,但是前者类似于tag或者group的作用,对特定的bean进行分类。

可以达到getByTag(group)的效果。

对于XML配置的bean,可以通过id属性指定bean name(如果没有指定,默认使用类名首字母小写),通过标签指定qualifier name:
如果是通过注解方式,那么可以通过@Qualifier注解指定qualifier name,通过@Named或者@Component(@Service,@Repository等)的value值指定bean name:
或者
同样,如果没有指定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中有如下定义:
其中static-field应用的常量定义在如下类中:
然后如果我们在代码中如下声明依赖:
Guess what,诡异的事情发生了!运行结果如下:
也就是说Map
debug了一下,发现确实是Spring的一个bug。

在DefaultListableBeanFactory的这个方法出问题了:
关键在这一句:Map
debug了一下,发现跟没有指定qualifie name是一样的执行路径。

不是指定了bean name了吗?为什么还是autowired by type呢?仔细查看了一下才发现。

DefaultListableBeanFactory 的doResolveDependency方法对首先对类型做了区别:
如果是Array,Collection或者Map,则根据集合类中元素的类型来进行autowired by type(Map 使用value的类型)。

为什么这么特殊处理呢?原来,Spring是为了达到这样的目的:让你可以一次注入所有符合类型的实现,也就是说可以这样子注入:
如果你的car有多个实现,那么都会注入进来,不会再报
然而,上面的情况如果你用@Resource则不会有这个问题:
正常运行:
当然,你如果不指定@Qualifier(“languageChangesMap”),同时field name不是languageChangesMap,那么还是一样报错的。

而且,@Resource也可以实现上面的List接收所有实现:
运行的妥妥的:
这是因为@Resource注解使用的是CommonAnnotationBeanPostProcessor处理器,跟AutowiredAnnotationBeanPostProcessor不是同一个作者[/偷笑]。

这里就不分析了,感兴趣的同学可以自己看代码研究一下。

最终结论如下:
1、@Autowired和@Inject
2、@Resource
测试工程保存在GitHub上,是标准的maven工程,感兴趣的同学可以clone到本地运行测试一下。

补充
有同事指出Spring官方文档上有这么一句话跟我的结有点冲突:
也就是说@Autowired即使加了@Qualifier注解,其实也是autowired by type。

@Qualifier只是一个限定词,过滤条件而已。

重新跟进了一下代码,发现确实是这样子的。

Spring设计的这个@Qualifier name 并不等同于bean name。

他有点类似于一个tag。

不过如果这个tag 是唯一的化,那么其实效果上等同于bean name。

实现上,Spring是先getByType,得到list candicates,然后再根据qualifier name进行过滤。

再定义一个兰博基尼,这里使用@Qualifier指定:
再定义一个劳斯莱斯,这里故意用@Named指定:
测试一下注入定义的豪华车:
运行结果如下:
补充:Autowiring modes
Spring支持四种autowire模式,当使用XML配置方式时,你可以通过autowire属性指定。

如果使用@Autowired、@Inject或者@Resource注解的时候,则稍微复杂一些,会有一个失败退化过程,并且引入了Qualifier。

不过基本原理是一样。

相关文档
最新文档