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没有办法实例化对象,导致报错。

Java必须掌握的20+种Spring常用注解

Java必须掌握的20+种Spring常用注解

Java必须掌握的20+种Spring常⽤注解Spring部分1、声明bean的注解@Component 组件,没有明确的⾓⾊@Service 在业务逻辑层使⽤(service层)@Repository 在数据访问层使⽤(dao层)@Controller 在展现层使⽤,控制器的声明(C)2、注⼊bean的注解@Autowired:由Spring提供@Inject:由JSR-330提供@Resource:由JSR-250提供都可以注解在set⽅法和属性上,推荐注解在属性上(⼀⽬了然,少写代码)。

3、java配置类相关注解@Configuration 声明当前类为配置类,相当于xml形式的Spring配置(类上)@Bean 注解在⽅法上,声明当前⽅法的返回值为⼀个bean,替代xml中的⽅式(⽅法上)@Configuration 声明当前类为配置类,其中内部组合了@Component注解,表明这个类是⼀个bean(类上)@ComponentScan ⽤于对Component进⾏扫描,相当于xml中的(类上)@WishlyConfiguration 为@Configuration与@ComponentScan的组合注解,可以替代这两个注解4、切⾯(AOP)相关注解Spring⽀持AspectJ的注解式切⾯编程。

@Aspect 声明⼀个切⾯(类上)使⽤@After、@Before、@Around定义建⾔(advice),可直接将拦截规则(切点)作为参数。

@After 在⽅法执⾏之后执⾏(⽅法上)@Before 在⽅法执⾏之前执⾏(⽅法上)@Around 在⽅法执⾏之前与之后执⾏(⽅法上)@PointCut 声明切点在java配置类中使⽤@EnableAspectJAutoProxy注解开启Spring对AspectJ代理的⽀持(类上)5、@Bean的属性⽀持@Scope 设置Spring容器如何新建Bean实例(⽅法上,得有@Bean)其设置类型包括:Singleton (单例,⼀个Spring容器中只有⼀个bean实例,默认模式),Protetype (每次调⽤新建⼀个bean),Request (web项⽬中,给每个http request新建⼀个bean),Session (web项⽬中,给每个http session新建⼀个bean),GlobalSession(给每⼀个 global http session新建⼀个Bean实例)@StepScope 在Spring Batch中还有涉及@PostConstruct 由JSR-250提供,在构造函数执⾏完之后执⾏,等价于xml配置⽂件中bean的initMethod@PreDestory 由JSR-250提供,在Bean销毁之前执⾏,等价于xml配置⽂件中bean的destroyMethod6、@Value注解@Value 为属性注⼊值(属性上)⽀持如下⽅式的注⼊:》注⼊普通字符》注⼊操作系统属性》注⼊表达式结果》注⼊其它bean属性》注⼊⽂件资源》注⼊⽹站资源》注⼊配置⽂件注⼊配置使⽤⽅法:①编写配置⽂件(test.properties)=《三体》② @PropertySource 加载配置⽂件(类上)③还需配置⼀个PropertySourcesPlaceholderConfigurer的bean。

Spring依赖注入:注解注入

Spring依赖注入:注解注入

Spring依赖注⼊:注解注⼊注解注⼊顾名思义就是通过注解来实现注⼊,Spring和注⼊相关的常见注解有Autowired、Resource、Qualifier、Service、Controller、Repository、Component。

1.@Autowired是⾃动注⼊,⾃动从spring的上下⽂找到合适的bean来注⼊@Autowired(required=true)表⽰必须找到匹配的Bean,否则将报异常。

@Autowired默认按类型匹配注⼊Bean在Spring中,@Autowired注⼊的类型可以是接⼝⽐如,在Service层中注⼊Dao,如下⽰:@Autowiredprivate UserDao userDao;2.@Resource要求提供⼀个Bean名称的属性,如果属性为空,⾃动采⽤标注处的变量名和⽅法名作为Bean的名称。

@Resource默认按名称匹配注⼊Bean⽐如,在Controller层中注⼊Service,名称为Service的实现类,如下⽰@Resource(name = "userServiceImpl")private UserService userService;另外要注意,@Resource是java⾃带的注解,不是Spring中的注解。

@Resource注解完整的包路径为import javax.annotation.Resource;3.@Qualifier 指定注⼊bean的名称⽐如,在Controller层中注⼊Service,名称为Service的实现类,如下⽰@Autowired@Qualifier("userServiceImp")private UserSerevice userService;4.@Service,@Controller,@Repository分别标记类是Service层,Controller层,Dao层的类,spring扫描注解配置时,会标记这些类要⽣成bean。

Spring框架核心原理解析

Spring框架核心原理解析

Spring框架核心原理解析Spring框架作为一个被广泛应用的开源框架,具备强大的功能和灵活性,为Java应用程序开发提供了便捷的解决方案。

它的成功之处在于其核心原理的设计和实现。

本文将对Spring框架的核心原理进行解析,以帮助读者更好地理解该框架的内部机制。

一、依赖注入(Dependency Injection)依赖注入是Spring框架的核心概念之一。

它的基本原理是通过将对象之间的依赖关系交由框架来管理,从而降低了类之间的耦合性。

在Spring框架中,通过配置文件或注解的方式描述对象之间的依赖关系,框架根据这些描述将所需的对象注入到相应的位置。

二、控制反转(Inversion of Control)控制反转是依赖注入的基础概念,也被称为IoC。

它的核心思想是将对象的创建和管理交给框架来完成,而不是由对象自身负责。

在Spring框架中,通过IoC容器来实现控制反转,容器负责创建、初始化和管理应用程序中的对象,开发者只需要关注对象的使用即可。

三、面向切面编程(Aspect-Oriented Programming)面向切面编程是Spring框架的另一个核心原理。

它的目的是实现横切关注点的模块化,提供更好的代码复用和解耦。

在Spring框架中,通过AOP技术可以将一系列与业务逻辑无关的功能和代码片段,比如事务管理、日志记录等,抽离出来,以切面的方式织入到应用程序中。

四、模块化设计(Modular Design)Spring框架采用模块化的设计思想,将各种功能和组件划分为不同的模块,以便更好地管理和维护。

每个模块都有清晰的职责和功能,可以根据实际需求进行选择和组合。

常用的Spring模块包括核心容器模块、数据访问模块、Web开发模块等,开发者可以灵活地按需引入。

五、灵活的扩展性和可插拔性Spring框架具备良好的扩展性和可插拔性,可以根据具体需求进行灵活的配置和定制。

开发者可以使用自定义的扩展点和接口来实现个性化的功能需求,比如自定义的数据访问层、认证授权模块等。

java 依赖注入详解

java 依赖注入详解

java 依赖注入详解Java的依赖注入(Dependency Injection,简称DI)是一种软件设计模式,用于管理对象之间的依赖关系。

它通过将依赖关系从代码中移除,实现对象之间的松耦合。

本文将详细解释Java的依赖注入,并介绍其原理、用法以及优缺点。

一、依赖注入的原理和概念依赖注入的原理就是通过外部容器来管理对象之间的依赖关系,而不是在代码中显式地创建和管理这些依赖关系。

典型的依赖注入的实现方式是通过构造函数、Setter方法或接口来注入依赖。

1.构造函数注入:在对象创建时,通过构造函数传递依赖关系。

2. Setter方法注入:通过Setter方法设置依赖关系。

3.接口注入:通过接口来定义依赖关系,在实现类中注入依赖。

二、依赖注入的优点1.降低代码的耦合性:依赖注入将对象之间的关系交给外部容器管理,代码只需要关注自身的功能,这样能够降低代码的耦合性,提高代码的可维护性和可测试性。

2.提高代码的可扩展性:依赖注入可以轻松地替换依赖关系,通过切换不同的实现类,可以实现对代码的灵活扩展。

3.简化对象的创建和管理:依赖注入由外部容器来负责对象的创建和管理,避免了重复的代码。

4.提高代码的可读性:依赖注入能够将对象之间的依赖关系从代码中解耦出来,使得代码更加清晰易读。

三、依赖注入的实现方式1.使用框架:许多Java框架(如Spring)提供了依赖注入的支持。

通过在配置文件中定义对象的依赖关系,框架会在运行时自动注入依赖。

2.使用注解:Java可以通过注解来实现依赖注入。

通过在字段或Setter方法上添加注解,容器会根据注解信息来自动注入依赖。

3.手动管理:在没有使用框架或注解的情况下,可以手动管理对象之间的依赖关系。

可以通过构造函数、Setter方法或接口来进行依赖注入。

四、依赖注入的示例下面通过一个简单的示例来说明依赖注入的用法。

假设我们有一个UserService接口和一个UserServiceImpl实现类,代码如下:```public interface UserService {void saveUser();}public class UserServiceImpl implements UserService {public void saveUser() {System.out.println("保存用户信息");}}```我们可以通过构造函数注入依赖关系,代码如下:```public class UserController {private UserService userService;public UserController(UserService userService) { erService = userService;}public void save() {userService.saveUser();}}```在上面的例子中,UserController类通过构造函数接收一个UserService对象,并将其保存在成员变量userService中。

依赖注入的三种方式以及优缺点。

依赖注入的三种方式以及优缺点。

依赖注⼊的三种⽅式以及优缺点。

依赖注⼊是指在创建⼀个对象时,⾃动地创建它依赖的对象,并注⼊。

⼤家都知道有三种途径来实现依赖注⼊,我这⾥总结⼀下这三种⽅式的优缺点:1.构造⽅法注⼊:优点:在构造⽅法中体现出对其他类的依赖,⼀眼就能看出这个类需要其他那些类才能⼯作。

脱离了IOC框架,这个类仍然可以⼯作,POJO的概念。

⼀旦对象初始化成功了,这个对象的状态肯定是正确的。

缺点:构造函数会有很多参数(Bad smell)。

有些类是需要默认构造函数的,⽐如MVC框架的Controller类,⼀旦使⽤构造函数注⼊,就⽆法使⽤默认构造函数。

这个类⾥⾯的有些⽅法并不需要⽤到这些依赖(Bad smell)。

2. Set⽅法注⼊:优点:在对象的整个⽣命周期内,可以随时动态的改变依赖。

⾮常灵活。

缺点:对象在创建后,被设置依赖对象之前这段时间状态是不对的。

不直观,⽆法清晰地表⽰哪些属性是必须的。

3. ⽅法参数注⼊:⽅法参数注⼊的意思是在创建对象后,通过⾃动调⽤某个⽅法来注⼊依赖。

类似如下代码。

public class MovieRecommender {private MovieCatalog movieCatalog;private CustomerPreferenceDao customerPreferenceDao;@Autowiredpublic void prepare(MovieCatalog movieCatalog,CustomerPreferenceDao customerPreferenceDao) {this.movieCatalog = movieCatalog;this.customerPreferenceDao = customerPreferenceDao;}// ...}这种⽅式介于Set⽅法注⼊和构造⽅法注⼊之间。

⽐如说我们通常会⽤⼀个Init⽅法来接受依赖的参数。

这种⽅法可能不太常⽤,⼀般是只有⼀个⽅法依赖到注⼊的对象时⽤到,如果有多个⽅法依赖到注⼊的对象,还是⽐较倾向于使⽤构造⽅法注⼊。

Java Spring中常见注解

Java Spring中常见注解

Spring 中常见注解@ContollerSpringMVC 中,控制器 Controller 负责处理 DispatcherServlet 分发的请求,它把用户请求的数据经过业务处理层处理之后封装成一个 Model,然后再把该 Model 返回给对应的 View 进行展示。

SpringMVC 提供了一个非常简便的定义 Controller 的方法,你无需继承特定的类或者接口,只需使用 @Controller 标记一个类是 Contoller。

@RequestMapping使用 @RequestMapping 来映射 URL 到控制器,或者到 Controller 控制器的处理方法上。

method 的值一旦指定,则处理方法只对指定的 HTTP method 类型请求处理。

可以为多个方法映射相同的 URI,不同的 HTTP method 类型,Spring MVC 根据请求的 method 类型是可以区分开这些方法的。

@RequestParam 和 @PathVariable在 SpringMVC 中,两者的作用都是将 request 里的参数的值绑定到 Controller 里的方法参数中,区别在于 URL 的写法不同。

•使用 @RequestParam 时,URL 是这样的:http://host:port/path?参数名=参数值•使用 @PathVariable 时,URL 是这样的:http://host:port/path/参数值@Autowired@Autowired 可以对成员变量、成员方法和构造函数进行标注,来完成自动装配工作。

@Service、 @Contrller、 @Repository 和 @Component@Service、 @Contrller、 @Repository 其实这 3 个注解和 @Component 是等效的,用在实现类上:•@Service 用于标注业务层组件•@Controller 用于标注控制层组件•@Repository 用于编著数据访问组件•@Component 泛指组件,当组件不好归类时,可以使用这个注解进行标注@Value在 Spring 3.0 中,可以通过使用 @Value,对一些如 xxx.properties 文件中的文件,进行键值对的注入。

浅谈springDI依赖注入方式和区别

浅谈springDI依赖注入方式和区别

浅谈springDI依赖注⼊⽅式和区别⽬录springDI3种DI注解的区别1@Autowired2@Inject3@Resource3种注⼊⽅式的区别1field注⼊2构造器注⼊3setter注⼊构造器注⼊的好处1依赖不可变2依赖不为空3完全初始化状态4避免循环依赖5总结spring DISpring框架对Java开发的重要性不⾔⽽喻,其核⼼特性就是IOC(Inversion of Control,控制反转)和AOP,平时使⽤最多的就是其中的IOC,我们通过将组件交由Spring的IOC容器管理,将对象的依赖关系由Spring控制,避免硬编码所造成的过度程序耦合。

3种DI注解的区别1 @Autowired使⽤特点Autowired注解是spring框架提供的Autowired注解优先byType获取java bean,其次byNameAutowired注解配合Qualifier注解区分java bean的名称,主要⽤于同⼀个类型的javabean有多个实Autowired注解注⼊的对象,⼀般要求⾮null,如果允许为null,需要required=false属性声明@Autowired可以作⽤在变量、setter⽅法、构造函数上使⽤过程a、将@autowored写在被注⼊的成员变量上,就不⽤再xml⽂件中配置了,在程序中去掉相应的setter和getter⽅法,b、还可以写在构造⽅法上、setter⽅法上c、@Qualifier@Qualifier("XXX") 中的 XX是 Bean 的名称,所以 @Autowired 和 @Qualifier 结合使⽤时,⾃动注⼊的策略就从 byType 转变成 byName 了。

不过需要注意的是@Autowired 可以对成员变量、⽅法以及构造函数进⾏注释,⽽ @Qualifier 的标注对象是成员变量、⽅法⼊参、构造函数⼊参。

2 @Inject使⽤特点@Inject是JSR330 (Dependency Injection for Java)中的规范,需要导⼊javax.inject.Inject; 实现注⼊@Inject是根据类型进⾏⾃动装配的,如果需要按名称进⾏装配,则需要配合@Named@Inject可以作⽤在变量、setter⽅法、构造函数上与@Autowired使⽤类似,想⽐之下,采⽤spring提供的@Autowired更为普遍使⽤过程a、将@Inject可以作⽤在变量、setter⽅法、构造函数上,和@Autowired⼀样b、@Named@Named("XXX") 中的 XX是 Bean 的名称,所以 @Inject和 @Named结合使⽤时,⾃动注⼊的策略就从 byType 转变成byName 了。

SpringBoot构造器注入、Setter方法注入和Field注入对比

SpringBoot构造器注入、Setter方法注入和Field注入对比

SpringBoot构造器注⼊、Setter⽅法注⼊和Field注⼊对⽐0. 引⼊今天在看项⽬代码的时候发现在依赖注⼊的时候使⽤了构造器注⼊,之前使⽤过 Field 注⼊和 Setter ⽅法注⼊,对构造器注⼊不是很了解。

经过查阅资料看到,Spring 推荐使⽤构造器注⼊的⽅式,下⾯介绍构造器注⼊到底有什么⽞机。

1. 常见的三种注解注⼊⽅式对⽐Field 注⼊@Controllerpublic class HelloController {@Autowiredprivate AlphaService alphaService;@Autowiredprivate BetaService betaService;}field 注⼊⽅式是使⽤最多的,原因是这种⽅式使⽤起来⾮常简单,代码更加简洁。

Setter ⽅法注⼊@Controllerpublic class HelloController {private AlphaService alphaService;private BetaService betaService;@Autowiredpublic void setAlphaService(AlphaService alphaService) {this.alphaService = alphaService;}@Autowiredpublic void setBetaService(BetaService betaService) {this.betaService = betaService;}}在 Spring 3.x 刚推出的时候,Spring 官⽅在对⽐构造器注⼊和 Setter 注⼊时,推荐使⽤ Setter ⽅法注⼊:The Spring team generally advocates setter injection, because large numbers of constructor arguments can get unwieldy, especially when properties are optional. Setter methods also make objects of that class amenable to reconfiguration or re-injection later. Management through is a compelling use case.Some purists favor constructor-based injection. Supplying all object dependencies means that the object is always returned to client (calling) code ina totally initialized state. The disadvantage is that the object becomes less amenable to reconfiguration and re-injection.意思是说,当出现很多注⼊项的时候,构造器参数可能会变得臃肿,特别是当参数时可选的时候。

详解Spring依赖注入:@Autowired,@Resource和@Inject区别与实现原理

详解Spring依赖注入:@Autowired,@Resource和@Inject区别与实现原理

详解Spring依赖注⼊:@Autowired,@Resource和@Inject区别与实现原理⼀、spring依赖注⼊使⽤⽅式@Autowired是spring框架提供的实现依赖注⼊的注解,主要⽀持在set⽅法,field,构造函数中完成bean注⼊,注⼊⽅式为通过类型查找bean,即byType的,如果存在多个同⼀类型的bean,则使⽤@Qualifier来指定注⼊哪个beanName的bean。

与JDK的@Resource的区别:@Resource是基于bean的名字,即beanName,来从spring的IOC容器查找bean注⼊的,⽽@Autowried是基于类型byType来查找bean注⼊的。

与JDK的@Inject的区别:@Inject也是基于类型来查找bean注⼊的,如果需要指定名称beanName,则可以结合使⽤@Named注解,⽽@Autowired是结合@Qualifier注解来指定名称beanName。

⼆、spring依赖注⼊注解的实现原理注解处理器在spring框架内部实现当中,注解实现注⼊主要是通过bean后置处理器BeanPostProcessor接⼝的实现类来⽣效的。

BeanPostProcessor后置处理器是在spring容器启动时,创建bean对象实例后,马上执⾏的,对bean对象实例进⾏加⼯处理。

@Autowired是通过BeanPostProcessor接⼝的实现类AutowiredAnnotationBeanPostProcessor来实现对bean对象对其他bean对象的依赖注⼊的;@Resource和@Inject是通过BeanPostProcessor接⼝的实现类CommonAnnotationBeanPostProcessor来实现的,其中如名字所述,即公共注解CommonAnotation,CommonAnnotationBeanPostProcessor是spring中统⼀处理JDK中定义的注解的⼀个BeanPostProcessor。

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

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

pring对于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注入方式之前进行。

Spring各种注解的含义及用法(持续更新)

Spring各种注解的含义及用法(持续更新)

Spring各种注解的含义及⽤法(持续更新)1.基础(SpringMVC和SpringBoot都有在⽤)@Controller通常⽤于标注在控制层类上。

@Service通常⽤于标注在业务层实现类上。

可以设置⾃定义service类的别名,在控制层引⼊时就需要根据设置的别名进⾏引⼊。

@Mapper不需要在启动类上配置扫描,会在运⾏时通过动态代理⽣成实现类。

@Component泛指组件,当组件不好归属于控制层/业务层的时候,我们可以使⽤这个注解进⾏标注@ServletComponentScan在SpringBootApplication上使⽤@ServletComponentScan注解后,Servlet、Filter、Listener可以直接通过@WebServlet、@WebFilter、@WebListener注解⾃动注册,⽆需其他代码@ComponentScan(basePackages ={'可配置扫描的路径"})扫描配置路径中的类,⽣成实现类,把依赖的组件注⼊进去@Autowired关联依赖的组件,当该组件接⼝有2个以上的实现类时,须添加 @Qualifier("实现类的名称") 说明具体是哪个实现类使⽤了该注解可不⽤写get set⽅法 Spring会帮你完成@Primary当2个类实现同⼀个接⼝时,在使⽤改接⼝时,把这个注解加在其中⼀个实现类上,就会优先选择使⽤改注解的类@Scope("prototype")默认是singleton单例模式的,prototype表⽰每次调⽤时都会创建⼀个新的对象@Bean注解将会告诉 Spring 其修饰的⽅法将会返回⼀个对象,该⽅法要注册为 Spring 应⽤上下⽂的 bean,默认情况下bean 的 ID 与带有 @Bean 注解的⽅法名保持⼀致。

可以 @Bean(name="定义其他名称")@Configuration标注在类上,相当于把该类作为spring的xml配置⽂件中的,作⽤为:配置spring容器(应⽤上下⽂) @Configuration注解的spring容器加载⽅式,⽤AnnotationConfigApplicationContext替换ClassPathXmlApplicationContextApplicationContext context = new AnnotationConfigApplicationContext(TestConfiguration.class);如果加载spring-context.xml⽂件:ApplicationContext context = new ClassPathXmlApplicationContext("spring-context.xml");@Param标记在dao层⽅法中的普通参数前,可以在xml中不需要使⽤ parameterType 进⾏声明可以直接使⽤,标记在实体类参数前,需要在xml中使⽤别名.属性的⽅式使⽤实体类的变量,建议实体类参数不加,不加可以在xml中直接使⽤变量名。

  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。

不过基本原理是一样。

相关文档
最新文档