Spring IoC容器注入依赖资源主要有以下两种基本实现方式:
构造器注入:就是容器实例化Bean时注入那些依赖,通过在在Bean定义中指定构造器参数进行注入依赖,包括实例工厂方法参数注入依赖,但静态工厂方法参数不允许注入依赖;
setter注入:通过setter方法进行注入依赖;
构造器注入,使用构造器注入通过配置构造器参数实现,构造器参数就是依赖。除了构造器方式,还有静态工厂、实例工厂方法可以进行构造器注入。
1 根据参数类型进行注入
<bean
id
=
"exampleBean"
class
=
"examples.ExampleBean"
>
<constructor-arg
type
=
"int"
value
=
"7500000"
/>
<constructor-arg
type
=
"java.lang.String"
value
=
"42"
/>
</bean>
2 根据参数索引注入
<bean
id
=
"exampleBean"
class
=
"examples.ExampleBean"
>
<constructor-arg
index
=
"0"
value
=
"7500000"
/>
<constructor-arg
index
=
"1"
value
=
"42"
/>
</bean>
3 根据参数名进行注入
需要在构造器上使用
@ConstructorProperties(java.beans.ConstructorProperties)注解来指定参数名
public class
ExampleBean {
// Fields omitted
@ConstructorProperties({"years", "ultimateAnswer"})
public
ExampleBean(
int
years, String ultimateAnswer) {
this
.years = years;
this
.ultimateAnswer = ultimateAnswer;
}
}
<bean
id
=
"exampleBean"
class
=
"examples.ExampleBean"
>
<constructor-arg
name
=
"years"
value
=
"7500000"
/>
<constructor-arg
name
=
"ultimateanswer"
value
=
"42"
/>
</bean>
Spring3.1之后可用c命名空间,xmlns:c="http://www.springframework.org/schema/c"
<bean id="messageProvider" class = "com.apress.prospring3.ch4.ConfigurableMessageProvider"
c:_0 = "This is c:message" />
这里的message 是 构造方法的参数名称
setter注入,
<bean
id
=
"exampleBean"
class
=
"examples.ExampleBean"
>
<!-- setter injection using the nested <ref/> element -->
<property
name
=
"beanOne"
><ref
bean
=
"anotherExampleBean"
/></property>
<!-- setter injection using the neater 'ref' attribute -->
<property
name
=
"beanTwo"
ref
=
"yetAnotherBean"
/>
<property
name
=
"integerProperty"
value
=
"1"
/>
</bean>
<bean
id
=
"anotherExampleBean"
class
=
"examples.AnotherBean"
/>
<bean
id
=
"yetAnotherBean"
class
=
"examples.YetAnotherBean"
/>
如果使用的Spring2.5以后,并且引入P命名空间
<beans
xmlns
=
"http://www.springframework.org/schema/beans"
xmlns:xsi
=
"http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation
=
"http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd"
>
<bean
id
=
"myDataSource"
class
=
"org.apache.commons.dbcp.BasicDataSource"
destroy-method
=
"close"
p:driverClassName
=
"com.mysql.jdbc.Driver"
p:url
=
"jdbc:mysql://localhost:3306/mydb"
p:username
=
"root"
p:password
=
"masterkaoli"
/>
</beans>
注入集合、数组和字典
<bean
id
=
"moreComplexObject"
class
=
"example.ComplexObject"
>
<!-- results in a setAdminEmails(java.util.Properties) call -->
<property
name
=
"adminEmails"
>
<props>
<prop
key
=
"administrator"
>
administrator@example.org
</prop>
<prop
key
=
"support"
>
support@example.org
</prop>
<prop
key
=
"development"
>
development@example.org
</prop>
</props>
</property>
<!-- results in a setSomeList(java.util.List) call -->
<property
name
=
"someList"
>
<list>
<value>
a list element followed by a reference
</value>
<ref
bean
=
"myDataSource"
/>
</list>
</property>
<!-- results in a setSomeMap(java.util.Map) call -->
<property
name
=
"someMap"
>
<map>
<entry
key
=
"an entry"
value
=
"just some string"
/>
<entry
key
=
"a ref"
value-ref
=
"myDataSource"
/>
</map>
</property>
<!-- results in a setSomeSet(java.util.Set) call -->
<property
name
=
"someSet"
>
<set>
<value>
just some string
</value>
<ref
bean
=
"myDataSource"
/>
</set>
</property>
</bean>
depends-on,指定Bean初始化及销毁时的顺序,
<bean id="helloApi" class="cn.javass.spring.chapter2.helloworld.HelloImpl"/>
<bean id="decorator" class="cn.javass.spring.chapter3.bean.HelloApiDecorator"
depends-on="helloApi">
<property name="helloApi"><ref bean="helloApi"/></property>
</bean>
在“decorator”Bean初始化之前要先初始化“helloApi”,而在销毁“helloApi”之前先要销毁“decorator”,
lazy-init,延迟初始化Bean,指不提前初始化Bean,而是只有在真正使用时才创建及初始化Bean。 Spring容器会在创建容器时提前初始化“singleton”作用域的Bean,“singleton”就是单例的意思即整个容器每个Bean只有一个实例
<bean id="helloApi" class="cn.javass.spring.chapter2.helloworld.HelloImpl"
lazy-init="true"/>
自动装配就是指由Spring来自动地注入依赖对象,无需人工参与。Spring3.0已不推荐使用之前版本的“autodetect”自动装配,推荐使用Java 5+支持的(@Autowired)注解方式代替
<bean id="kenny" class="com.springinaction.springidol.Instrumentalist"
autowire="byName">
<property name="song" value="JingleBells"/>
</bean>
<bean id="duke" class="com.springinaction.springidol.PoeticJuggler"
autowire="constructor"/>
@Autowired
public voidsetInstrument(Instrument instrument){
this.instrument=instrument;
}
@Autowired可以直接注解在属性上,实际上是byType装配。
@Autowired
private Instrument instrument;
避免找不到bean时报错,可以:
@Autowired(required=false)
private Instrument instrument;
避免找到多个bean,可以用
Qualifier指定bean id
@Autowired
@Qualifier("guitar")
private Instrument instrument;
Bean 范围,默认Spring生成的bean都是单例的。如果需要每次生成新的实例,可以:
<bean id="ticket" class="com.springinaction.springidol.Ticket"
scope="prototype"/>
singleton | 单例,默认 |
prototype | 每次调用重新生成 |
request | 适用与WEB |
session |
适用与WEB
|
global-session |
Bean生命周期管理,Spring提供3中方式,interface-based, method-based, and annotation-based
1 Spring实例化bean
2 Spring注入bean的属性
3 如果bean实现了BeanNameAware,Spring会执行setBeanName()
4 如果bean实现了BeanFactoryAware,Spring会执行setBeanFactory()
5 如果bean实现了ApplicationContextAware,Spring会执行setApplicationContext()
6 如果bean实现了BeanPostProcessor,Spring会执行postProcessBeforeInitialization()
7 如果bean实现了
InitializingBean,Spring会执行afterPropertiesSet(),类似如果声明了
init-method,会执行自定义的方法
8 如果bean实现了BeanPostProcessor,Spring会执行postProcessAfterInitialization()
9 bean保持在ApplicationContext中,直到应用关闭
10 如果bean实现了
DisposableBean,Spring会执行destroy(),类似如果声明了
destroy-method,会执行自定义的方法
可以使用
init-method 和
destroy-method 定义bean在初始化和销毁时要执行的方法。
<bean id="auditorium" class="com.springinaction.springidol.Auditorium"
init-method="turnOnLights"
destroy-method="turnOffLights"/>
如果有的多个bean 需要用
init-method 和
destroy-method 。可以:
<?xml version="1.0"encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans-3.0.xsd"default-init-method="turnOnLights"default-destroy-method="turnOffLights">
</beans>
也可以用注解:
@PostConstruct,@
PreDestroy
BeanNameAware 接口,可以实现
BeanNameAware接口,其中有个setBeanName(String),Spring会在配置完成Bean之后,其他初始化方法之前,调用setBeanName(String),把Bean 名称注入。
ApplicationContextAware,可以获得ApplicationContext的引用