spring依赖注入
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了spring依赖注入相关的知识,希望对你有一定的参考价值。
依赖注入
1.属性注入
属性注入要求Bean提供一个默认的构造函数,并为需要注入的属性提供对应的Setter
方法。Spring先调用Bean的默认的构造函数实例化Bean对象,然后通赤反射的方式调用
Setter方法注入属性值。变量的前两个字母要么全部大写,要重叠全部小写,如:brand,
IDCode,IC是合法的,而iC,iCard,iDCode是不合法的。
2.构造函数注入
1)<bean id="" class="">
<constructor-arg type="java.lang.String">
<value>红旗</value>
</constructor-arg>
<constructor-arg type="double">
<value>2000</value>
</constructor-arg>
</bean>
2)按索引匹配入参
<bean id="" class="">
<constructor-arg index="0" value="红旗CA72"/>
<constructor-arg index="1" value="中国一汽"/>
<constructor-arg index="2" value="2000"/>
</bean>
3)联合使用类型和索引匹配入参
<bean id="" class="">
<constrctor-arg index="0" type="java.lang.String">
<value>红旗</value>
</constrctor-arg>
<constrctor-arg index="1" type="java.lang.String">
<value>中国一汽</value>
</constrctor-arg>
<constrctor-arg index="2" type="int">
<value>200</value>
</constrctor-arg>
</bean>
3.工厂方法注入
1)非静态工厂方法
有些工厂方法是非静态的,即必须实例化工厂类后才能调用工厂方法。
package com.baobaotao.ditype;
public class CarFactory
{
//1,创建Car的工厂方法
Car car = new Car();
car.setBrand("红旗CA72");
return car;
}
工厂类负责创建一个或多个目标类实例,工厂类类方法一般以接口或抽象类变量的形式返回目标类实例,
工厂类对外屏蔽了目标类的实例化步骤,调用者甚至不用知道具体的目标类是什么。在上面的例子中,
CarFactory工厂类仅负责创建Car类型的对象。
<!--1工厂类Bean>
<bean id="carFactory" class="com.baobaotao.ditype.CarFactory"/>
<!--factory-bean 指定1处的工厂类Bean:factory-method指定工厂类Bean 创建该Bean的工厂方法-->
<bean id="car5" factory-bean="carFactory" factory-method="createHongQiCar"/>
由于CarFactory工厂类的工厂方法不是静态的,所以首先要定义一个工厂类的Bean,然后通过factory-bean引
用工厂类实例,再通过factory-method指定对应的工厂类方法。
2)静态工厂方法
很多工厂类的方法都是静态的,这意味着用户在无须创建工厂类实例的情况下就可以调用工厂类的方法,因此
,静态工厂方法比非静态工厂方法的调用更方便。
package com.baobaotao.ditype;
public class CarFactory
{
//1.工厂类方法是静态的
public static Car createHongQiCar()
{
...
}
}
当使用静态工厂类的方法后,用户应无须在配置文件中定义工厂类的Bean了,只须按以下方式进行配置即可;
<bean id="car6" class="com.baobaotao.ditype.CarFactory" factory-method="getInstance">
直接在<bean>中通过class属性指定工厂类,然后再通过factory-method指定对应的工厂方法。
----------------------------------------------------------------
集合类型属性
java.util包中集合类是最常用的数据类型,主要包括List,Set,Map,Properties
List
<bean id="" class="">
<property name="favorites">
<list>
<value>看报</value>
<value>赛车</value>
<value>高尔夫</value>
</list>
</property>
</bean>
List属性既可以通过<value>注入字符串,也可以通过<ref>注入容器中其他的Bean。
假设一个属性类型可以通过字符串字面值进行配置,那么该类型对应的数组类型的
属性(如String[]、int[]等)也可能通过采用<list>方式进行配置。
Set
<bean id="" class="">
<property name="">
<set>
<value></value>
<value></value>
<value></value>
</set>
</property>
</bean>
Map
<bean id="" class="">
<property name="">
<map>
<entry>
<key><value>key1</value></key>
<value>value1</value>
</entry>
<entry>
<key><value>key1</value></key>
<value>value1</value>
</entry>
</map>
</property>
</bean>
Propertry
<bean id="" class="">
<property name="">
<props>
<prop key=""></prop>
<prop key=""></prop>
</props>
</property>
</bean>
----------------------------------------------------------------------------------
自动装配
Spring IoC容器了解容器中所有Bean配置信息,此外通过Java反射机制还以获知实现类的结构信息(如构造函数方法的结构,属性信息)
。Spring IoC容器就可以执照某种规则对容器中的Bean进行自动装配,而无须我们通过显式的方式进行配置。Spring为厌恶配置的开发
人员提供了一条偷懒的方法,可以按照某种规则进行Bean自动装配。
<bean>元素提供了一个指定自动装配类型的属性:autowire="<自动装类型>"。Spring 提供了4种自动装配类型,
自动装配类型 说明
------------------------------------------------------------------------------------------------------------------------------------------
byName 根据名称进行自动匹配。假设Boss有一个名为car属性,如果容器中刚好有一个名为car的Bean,Spring 应会自动将其装配给Boss的car属性
byType 根据类型进行自动匹配。假设Boss有一个Car类型的属性,如果容器中刚好有一个Car类型的Bean,Spring就会自动将其装配给Boss的这个属性
constructor 与ByType 类型,只不过它是针对构造函数注入而言的,如果Boss有一个构造函数,构造函数包含一个Car类型的入参,如果容器中有一个Car类型
的Bean则Spring将会自动把为个Bean作为Boss构造函数的入参,如果容器中没有找到和构造函数入参匹类型的Bean,Spring将抛出异常、
autodetect 根据Bean的自省机制决定采用byType还是constructor进行自动装配:如果Bean提供了默认的构造函数,则采用byType;否则采用construtor
--------------------------------------------------------------------------------
<beans>元素标签中的default-autowire属性可以配置全局自动匹配,default-autowire属性的默认的值为no,表示从不启用自动装配,其他个可选配置分别为
byName,byType,construtor,autodetect,这几个配置值的意义是不言自明的。不过在<beans>中定义的自动装配策略可以被<bean>和自动装配策略覆盖。
------------------------------------------------------------------------------------------------------------------------------------------
lookup 方法注入
Spring IoC容器拥有复写Bean方法的能力,这项魔术般的功能归于CGLib类包。CGLib可以在运行期动态操作Class字节码,为Bean动态分创建子类或实现类.
package com.baobaotao.injectfun;
public interface MagicBoss
{
Car getCar();
}
下面匀不编写任何实现类,仅通过配置为该接口提供动态实现,让getCar()接口方法每次都返回新的Car Bean:
<!--1.prototype 类型的Bean-->
<bean id="car" class="com.baobaotao.injectfun.Car"
p:brand="红旗CA72"
p:price="2000"
scope="prototype"/>
<!--2.实施方法注入-->
<bean id="magicBoss" class="com.baobaotao.injectfun.MagicBoss">
<lookup-method name="getCar" bean="car">
</bean>
通过lookup-method 元素标签为MagicBoss的getCar()提供动态实现,返回prototype的car Bean,这样Spring
将在动行期为MagicBoss接口提供动态实现。其效果等同于:
package com.baobaotao.injectfun;
public class MagicBossImpl implements MagicBoss ,ApplicationContextAware
{
private ApplicationContext ctx;
public Car getCar()
{
return (Car)ctx.getBean("car");
}
public void setApplicationContext(ApplicationContext ctx)throws BeansException
{
this.ctx = ctx;
}
}
以上是关于spring依赖注入的主要内容,如果未能解决你的问题,请参考以下文章
初识Spring源码 -- doResolveDependency | findAutowireCandidates | @Order@Priority调用排序 | @Autowired注入(代码片段