Spring依赖注入(DI)

基于 Setter 的依赖注入
ApplicationContext 支持对其管理的 bean 进行基于字段的依赖注入。 IoC 容器在调用无参数构造函数或无参数静态方法进行实例化后调用托管 bean 的 setter 方法。
基于构造函数和基于设置器的注入可以组合用于同一个 bean。
Setter DI 的基于 XML 的配置
bean-config.xml
<?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/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="item" scope="prototype" class="basic.ioc.setter.xml.Item"/>
<bean id="store" scope="prototype" class="basic.ioc.setter.xml.Store">
<property name="id" value="#{ T(java.util.UUID).randomUUID().toString() }"/>
<property name="item" ref="item"/>
</bean>
</beans>
TestXmlSetterInjection.java
package basic.ioc.setter.xml;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestXmlSetterInjection {
public static void main(String[] args) {
ApplicationContext context
= new ClassPathXmlApplicationContext("basic.ioc.setter.bean-config.xml");
Store store = context.getBean(Store.class);
System.out.println(store);
}
}
用于 setter 注入的基于 Java 的配置
BasicIocSetterConfig.java
package basic.ioc.setter.annotation;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;
import java.util.UUID;
@Configuration
public class BasicIocSetterConfig {
@Bean
@Scope("prototype")
public Item item() {
return new Item();
}
@Bean
@Scope("prototype")
public Store store() {
Store storeObj = new Store();
storeObj.setId(UUID.randomUUID().toString());
storeObj.setItem(this.item());
return storeObj;
}
}
TestSetterInjection.java
package basic.ioc.setter.annotation;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class TestSetterInjection {
public static void main(String[] args) {
ApplicationContext context
= new AnnotationConfigApplicationContext(BasicIocSetterConfig.class);
Store store = context.getBean(Store.class);
System.out.println(store);
}
}
基于字段的注解驱动的依赖注入
您可以使用 @Component 注释将一个类声明为 Spring 管理的 bean 类。这是一种常见的做法。
注意:您可以在字段(属性)上使用@Inject 或@Autowired 注释。但由于性能影响,不建议这样做。相反,在 setter 或构造函数上使用相同的注释。
Store.java
package basic.ioc.autowire;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import java.util.StringJoiner;
import java.util.UUID;
@Component
@Scope("prototype")
public class Store {
private String id;
/* Field injection is not recommended. Instead use, Constructor
or Setter injection
*/
@Autowired
private Item item;
public Store() {
id = UUID.randomUUID().toString();
}
public Store(String id, Item item) {
this.id = id;
this.item = item;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public Item getItem() {
return item;
}
public void setItem(Item item) {
this.item = item;
}
@Override
public String toString() {
return new StringJoiner(", ", Store.class.getSimpleName() + "[", "]")
.add("id=" + id)
.add("item=" + item)
.toString();
}
}
Item.java
package basic.ioc.autowire;
import java.util.StringJoiner;
public class Item {
private Long id;
private String name;
public Item() {
}
public Item(Long id, String name) {
this.id = id;
this.name = name;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return new StringJoiner(", ", Item.class.getSimpleName() + "[", "]")
.add("id=" + id)
.add("name='" + name + "'")
.toString();
}
}
AutowireBeanConfig.java
package basic.ioc.autowire;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;
import java.util.Random;
import java.util.UUID;
@Configuration
@ComponentScan("basic.ioc.autowire")
public class AutowireBeanConfig {
@Bean
@Scope("prototype")
public Item item(){
return new Item (
new Random().nextLong(),
UUID.randomUUID().toString()
);
}
}
TestAutowireExample.java
package basic.ioc.autowire;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class TestAutowireExample {
public static void main(String[] args) {
ApplicationContext context
= new AnnotationConfigApplicationContext(AutowireBeanConfig.class);
System.out.println(context.getBean(Store.class));
System.out.println(context.getBean(Store.class));
}
}
输出如下:
Store[id=c00b6e1c-253b-4957-a0ec-dc59a0a9161c, item=Item[id=-5148911103221427956, name='dd87f4ad-79bf-48e0-9e2f-3881fd874d47']]
Store[id=81cdfbb3-1026-4c8f-83da-997806c09415, item=Item[id=2474607863045812177, name='381c9dbf-e21e-4ad3-922c-fdd62884da63']
Spring中延迟初始化的Bean
默认情况下,ApplicationContext 实现会立即创建所有 Singleton bean。您可以通过将单例 bean 标记为惰性 bean 来控制其预实例化的行为。
<bean id="lazyPDFReader" class="com.something.PDFReader" lazy-init="true"/>
如果惰性初始化 bean 是非惰性单例 bean 的依赖项,则 Spring 将在应用程序启动时创建惰性 bean 的实例。