广州网站开发哪家专业,婚纱手机网站,淘宝优化标题都是用什么软件,网站建设要学哪些软件依赖注入依赖注入就是在Spring创建Bean的时候#xff0c;去实例化该Bean构造函数所需的参数#xff0c;或者通过Setter方法去设置该Bean的属性。Spring的依赖注入有两种基于构造函数的依赖注入和基于setter的依赖注入。基于构造函数的依赖注入构造函数的注入是通过构造函数的…依赖注入依赖注入就是在Spring创建Bean的时候去实例化该Bean构造函数所需的参数或者通过Setter方法去设置该Bean的属性。Spring的依赖注入有两种基于构造函数的依赖注入和基于setter的依赖注入。基于构造函数的依赖注入构造函数的注入是通过构造函数的参数来实现的。如下所示public class ExampleBean {// Number of years to calculate the Ultimate Answerprivate int years;// The Answer to Life, the Universe, and Everythingprivate String ultimateAnswer;public ExampleBean(int years, String ultimateAnswer) {this.years years;this.ultimateAnswer ultimateAnswer;}} 该Bean有一个两个参数的构造函数那么怎么注入这些参数呢有三种方法。方法1按构造函数的类型匹配这里通过指定参数的类型即可以指定哪个参数是years哪个参数是ultimateAnswer。方法2构造函数索引Spring中可以通过构造函数的索引来指定特定的参数。要注意Spring的索引是从0开始的。方法3构造函数名字匹配如果通过构造函数的名字来匹配需要注意必须在编译的时候开启调试标志要不然Spring不能在构造函数中找到参数名。如果不想启用调试标志则必须使用ConstructorProperties JDK注解显式命名构造函数参数。public class ExampleBeanWithConstructorProperties {// Number of years to calculate the Ultimate Answerprivate int years;// The Answer to Life, the Universe, and Everythingprivate String ultimateAnswer;ConstructorProperties ({years, ultimateAnswer})public ExampleBeanWithConstructorProperties (int years, String ultimateAnswer) {this.years years;this.ultimateAnswer ultimateAnswer;}}基于Setter的注入Setter注入主要用来无参构造器或者获得对象实例之后才设置对象的属性。下面是Setter的例子public class SimpleMovieLister {// the SimpleMovieLister has a dependency on the MovieFinderprivate MovieFinder movieFinder;// a setter method so that the Spring container can inject a MovieFinderpublic void setMovieFinder (MovieFinder movieFinder) {this.movieFinder movieFinder;}// business logic that actually uses the injected MovieFinder is omitted...}对于的XML文件如下除了XML配置也可以使用注解Component、Controller。或者使用Configuration注解中的Bean方法。如何选择既然有这样两种注入方式我们怎么选择呢通常来说对于必须的属性我们通过构造函数来注入。对于可选属性我们通过Setter注入。当然你也可以在Setter方法中使用Required注解。当然如果第三方类不公开任何setter方法那么构造函数注入可能是DI的唯一可用形式。循环依赖循环依赖主要出现在构造函数注入的情况。类A通过构造函数注入需要类B的实例类B通过构造函数注入需要类A的实例。如果为要相互注入的类A和类B配置bean那么SpringIOC容器在运行时检测到这个循环引用会抛出BeanCurrentlyInCreationException。解决方式就是使用Setter注入。依赖注入的配置详解基本类型字符串或者其他如果 property/元素的value属性是基本类型Spring会将其转换为类需要的类型配置如下这是一个常见的Setter注入。为了简洁也可以使用p-namespace如下?xml version1.0 encodingUTF-8?Spring容器使用JavaBeans属性编辑器机制将 value/元素中的文本转换为java.util.properties实例。这是一个很好的快捷方式如下所示jdbc.driver.className com.mysql.jdbc.Driverjdbc.urljdbc: mysql://localhost:3306/mydb注意上面例子中的value里面的值。ref通过 ref/标记的bean属性允许在同一容器或父容器中创建对任何bean的引用而不管它是否在同一XML文件中。bean属性的值可以与目标bean的id属性相同也可以与目标bean的name属性中的一个值相同。以下示例显示如何使用ref元素内部bean在 property/ 或者 constructor-arg/元素内部的 bean/元素可以定义一个内部bean,下面是个例子内部bean定义不需要ID或名称。如果指定容器也不会使用这个值作为标识符。容器在创建时也忽略作用域标志因为内部bean总是匿名的并且总是用外部bean创建的。不可能单独访问内部bean也不可能将它们注入到除封闭bean之外的协作bean中。集合 list/, set/, map/,和 props/ 分别被用来设置Java Collection类型List, Set, Map和 Properties 类型的属性和参数。 下面是个例子 administratorexample.org supportexample.org developmentexample.orga list element followed by a referencejust some string强类型集合通过在Java 5中引入泛型类型可以使用强类型集合。也就是说可以声明集合类型使其只能包含(例如)字符串元素。如果使用Spring将强类型集合注入bean则可以利用Spring的类型转换支持以便在将强类型集合实例的元素添加到集合之前将其转换为适当的类型。下面的Java类和bean定义的例子public class SomeClass {private Map accounts;public void setAccounts (Map accounts) {this.accounts accounts;}}Null和Empty字符串值Null和空字符串是不一样的如下上面的例子相当于exampleBean.setEmail();下面是怎么设置null上面的例子相当于exampleBean.setEmail(null);c-namespace上面讲到了p-namespace专门是设置bean的属性用的同样的c-namespace是用来设置构造函数参数的如下所示depends-on通常一个bean依赖另一个bean我们会在XML中使用 ref/来引用但是这种依赖关系并不直接。我们可以使用depends-on属性来显式强制一个或多个bean在使用此元素的bean初始化之前进行初始化,如下所示lazy-init正常来说ApplicationContext中配置成单例模式的bean都会随Spring启动而初始化如果有特殊的需要想延长初始化该bean则可以使用 lazy-init 。一个lazy-initialized bean告诉IOC容器在第一次请求bean实例时创建它而不是在启动时。但是当一个惰性初始化bean是一个非惰性初始化的singleton bean的依赖项时ApplicationContext会在启动时创建惰性初始化bean因为它必须满足singleton的依赖项。您还可以通过在 beans/元素上使用默认的lazy init属性在容器级别控制lazy初始化下面的示例显示自动装载如果你想让Spring自动帮你注入bean的依赖bean时候可以使用Spring的autowiring功能。autowiring 有4种模式自动注入的限制和缺陷虽然自动注入用起来很爽但是它也有如下的缺陷property和constructor-arg的显示设置会覆盖自动注入并且自动注入不能注入简单类型。自动注入不如显示配置精确。自动注入可能和容器中的很多bean相匹配。可能会出现问题。从自动装载中排除Bean使用autowire-candidate属性设置为false可以防止bean被自动注入。该属性只会影响按类型注入的方式。如果按name注入则不受影响。下面是自动注入的例子SimpleMovieLister如下package com.flydean.beans;import lombok.Data;Datapublic class SimpleMovieLister {// the SimpleMovieLister has a dependency on the MovieFinderprivate MovieFinder movieFinder;// a setter method so that the Spring container can inject a MovieFinderpublic void setMovieFinder (MovieFinder movieFinder) {this.movieFinder movieFinder;}// business logic that actually uses the injected MovieFinder is omitted...}在上面的例子中movieFinder属性将会被自动注入。方法注入在bean的生命周期不同的时候如果一个bean要依赖于另外一个bean则可能出现问题。 比如一个单例模式的beanA 依赖于多例模式的beanB。 因为beanA是单例模式的所以在创建beanA的时候就已经将其依赖的beanB创建了不可能在每次beanA需要beanB的时候都创建一个新的beanB的实例。解决方法有很多种我们一一进行讲解。方法1实现ApplicationContextAware如果实现了ApplicationContextAware则可以通过getBean方法在每次需要beanB的时候请求他的新的实例如下public class CommandManager implements ApplicationContextAware {private ApplicationContext applicationContext;public Object process (Map commandState) {// grab a new instance of the appropriate CommandCommand command createCommand();// set the state on the (hopefully brand new) Command instancecommand.setState(commandState);return command.execute();}protected Command createCommand() {// notice the Spring API dependency!return this.applicationContext.getBean (command, Command.class);}public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {this.applicationContext applicationContext;}}这种方法并不可取的因为业务代码和Spring框架产生了耦合。方法注入是Spring IoC 容器的一个高级特性它可以很好的处理这种情况。查找方法注入查找方法注入是指容器重写container-managed bean上的方法并返回容器中另一个命名bean。查找通常涉及一个原型bean如前一节中描述的场景中所示。Spring框架通过使用cglib库中的字节码动态生成覆盖该方法的子类来实现该方法注入。因为使用了cglib所以bean不能是final类方法也不能是final类型。查找方法不适用于工厂方法尤其不适用于配置类中的Bean方法因为在这种情况下容器不负责创建实例因此无法动态创建运行时生成的子类。下面是一个查找方法的例子public abstract class CommandManagerB {public Object process (Map commandState) {// grab a new instance of the appropriate Command interfaceAsyncCommand command createCommand();return null;}// okay... but where is the implementation of this method?public abstract AsyncCommand createCommand();}这里我们定义了一个抽象类要查找的方法就是createCommand。返回的对象类如下public class AsyncCommand {}下面是XML配置文件CommandMangerB每次调用createCommand都会返回一个新的AsyncCommand实例。在基于注解的情况下也可以这样使用public abstract class CommandManagerC {public Object process (Object commandState) {Command command createCommand();return command.execute();}Lookup(myCommand)protected abstract Command createCommand();}其中Lookup(“myCommand”) 中的名字也可以省略则按照默认的类型来解析。任意方法替换我们甚至可以使用replaced-method替换bean的方法实现。我们有个MyValueCalculator类有一个我们想重写的方法computeValue。public class MyValueCalculator {public String computeValue(String input) {// some real code...return abc;}// some other methods...}一个实现了org.springframework.beans.factory.support.MethodReplacer接口的类提供了新的方法如下所示public class ReplacementComputeValue implements MethodReplacer {public Object reimplement (Object o, Method m, Object[] args) throws Throwable {// get the input value, work with it, and return a computed resultString input (String) args[0];return def;}}bean的定义如下String本章的例子可以参考bean-di中的bean-di部分。