前言Spring是Java后端程序员必须掌握的框架技术。Spring的诞生大大简化了企业级应用开发的复杂度。Spring框架中的核心技术是:IOC(InversionofControl):是面向对象编程中的一个设计原则,可以用来降低计算机代码之间的耦合度(百度百科)。通俗地说,对象创建的控制权被转移了。本来,对象创建的控制权在开发者手中。现在控制权通过IOC交给了Spring,由Spring统一管理对象的创建和销毁。AOP(AspectProgramming):一种在运行时通过预编译和动态代理实现程序功能统一维护的技术(百度百科)。通俗地说,将一些公共行为(如权限验证、日志记录等)封装成可复用的公共模块,可以降低耦合,提高程序的复用性。本文将主要介绍Spring中IOC的依赖注入。控制反转IOCIOC主要有两种实现方式:依赖查找(DependencyLookup)容器中的受控对象通过容器的API找到自己所依赖的资源和协作对象。通俗地说,容器已经为我们创建了对象,开发者可以从容器中获取他们需要的东西。DependencyInjection(简称DI,IOC最常见的方式)是一种依赖查找的优化,即开发者不需要手动在容器中寻找对象,只要告诉容器自己需要什么对象,容器将注入创建的对象。DependencyinjectionDI在Spring中的依赖注入主要有两种形式:基于XML的形式Annotation-based形式Annotation-basedDI有三种形式:基于属性的注入,基于属性的setter注入,基于构造函数的注入,三种常规注入,属性基于注入日常开发中最常用的方法:@ServicepublicclassUserServiceImplimplementsUserService{@AutowiredprivatePhoneServicephoneService;}@ServicepublicclassUserServiceImplimplementsUserService{@ResourceprivatePhoneServicephoneService;}@Autowired注解和@Resource注解的区别:@Autowired@ResourceSpring的注解,它的包是org.springframework.beans.factory.annotation.Autowired不是一个Spring的注解,它的包是javax.annotation.Resource只根据byType注入,默认是自动根据byName注入。有两个重要的属性。:name和type的组装顺序@Resource:如果同时指定了name和type,会从Spring上下文中寻找唯一匹配的bean进行组装,找不到则抛出异常。如果指定了名称,则从上下文中找到与该名称匹配的bean进行组装,如果找不到bean则抛出异常。如果指定了类型,则从上下文中搜索唯一匹配该类型的bean进行组装,如果没有找到或找到多个bean,将抛出异常。如果既不指定名称也不指定类型,则自动按照byName方法进行组装;如果不匹配,则回退到原来的类型进行匹配,如果匹配,则自动组装。基于setter方法的注入@ServicepublicclassUserServiceImplimplementsUserService{privatePhoneServicephoneService;@AutowiredpublicvoidsetPhoneService(PhoneServicephoneService){this.phoneService=phoneService;}}基于构造函数注入(Spring官方推荐)@ServicepublicclassUserServiceImplimplementsUserService{privatefinalPhoneServicephoneService;@AutowiredpublicUserServiceImpl(PhoneServicephoneService){this.phoneService=phoneService;}}为什么Spring官方推荐使用构造函数注入?保证依赖不可变(final关键字)保证依赖不为空(除了程序启动时因为注入对象为空而报异常)避免循环依赖,提高代码复用性(在非IOC环境下,可以使用new实例Objectofthisclass)interfaceinjection当我们使用以上三种方式注入接口时,当接口有多个实现类时,程序启动时会报错,因为Spring不知道注入哪个实现类。那么如何解决接口的多个实现类的注入问题呢?结合@Autowired注解和@Qualifier注解@ServicepublicclassUserServiceImplimplementsUserService{@Autowired@Qualifier("applePhoneServieImpl")privatePhoneServicephoneService;}@Qualifier("applePhoneServieImpl")指定要引入的具体实现类。通过@Resource注解动态获取@ServicepublicclassUserServiceImplimplementsUserService{@Resource(name="applePhoneServieImpl")privatePhoneServicephoneService;}通过@Primary注解优先注入@Service@PrimarypublicclassApplePhoneServieImplimplementsPhoneService{}@Primary注解表示何时有当一个bean满足注入条件时,被注解修改的bean会被优先注入。注入@Service@ConditionalOnProperty(prefix="phone",name="impl",havingValue="vivo")publicclassVivoPhoneServieImplimplementsPhoneService{}@ConditionalOnProperty(prefix="phone",name="通过@ConditionalOnProperty注解结合配置fileimpl",havingValue="vivo")表示当配置文件中phone.impl=vivo时,VivoPhoneServieImpl会被注入到容器中。通过其他@Condition条件注解@ConditionalOnBean:当某个Bean存在时,将这个类初始化到容器中。@ConditionalOnClass:当一个类存在时,初始化这个类的容器。@ConditionalOnMissingBean:当一个Bean不存在时,将这个类初始化到容器中。@ConditionalOnMissingClass:当某个类不存在时,将这个类初始化到容器中。...通过集合注入@ServicepublicclassUserServiceImplimplementsUserService{@AutowiredprivateList
