目录
容器创建实例Bean有多少种?
- 通过反射调用构造方法创建Bean对象
- 通过静态工厂方法创建Bean对象
- 通过实例工厂方法创建Bean对象
- 通过FactoryBean创建Bean对象
通过反射调用构造方法创建Bean对象
调用类的构造方法获取对应的bean实例,是使用最多的方式,这种方式只需要在xml bean元素中指定 class属性,spring容器内部会自动调用该类型的构造方法来创建bean对象,并将其放在容器中以供使用。
语法
<bean id="bean的名称" name="bean的名称或者别名" class="bean的完整路径">
<constructor-arg index="索引位置" value="bean的值" ref="引用的bean的名称"/>
<constructor-arg index="索引位置" value="bean的值" ref="引用的bean的名称"/>
<constructor-arg index="索引位置" value="bean的值" ref="引用的bean的名称"/>
<constructor-arg index="索引位置" value="bean的值" ref="引用的bean的名称"/>
<constructor-arg index="索引位置" value="bean的值" ref="引用的bean的名称"/>
。
。
。
</bean>
constructor-arg用于指定构造方法参数的值
index:构造方法中参数的位置,从0开始,依次递增
value:指定参数的值
ref:当插入的值为容器内其他bean的时候,这个值为容器中对应bean的名称
案列:
@Data
public class User {
private String name;
private Integer age;
User(){}
User(String name,Integer age){
this.name=name;
this.age=age;
}
}
<?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="user" class="com.example.sd.User">
<constructor-arg index="0" value="张三" />
<constructor-arg index="1" value="20"/>
</bean>
</beans>
@SpringBootTest
class CreateBeanApplicationTests {
@Test
public void test1(){
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
//getBeanDefinitionNames用于获取容器中所有bean的名称
for (String beanName:context.getBeanDefinitionNames()){
System.out.println(beanName+":"+context.getBean(beanName));
}
}
}
通过静态工厂方法创建Bean对象
我们可以创建静态工厂,内部提供一些静态方法来生成所需要的对象,将这些静态方法创建的对象交给 spring以供使用。
语法
<bean id="bean名称" name="" class="静态工厂完整类名" factory-method="静态工厂的方法">
<constructor-arg index="0" value="bean的值" ref="引用的bean名称" />
<constructor-arg index="1" value="bean的值" ref="引用的bean名称" />
<constructor-arg index="2" value="bean的值" ref="引用的bean名称" />
....
<constructor-arg index="n" value="bean的值" ref="引用的bean名称" />
</bean>
class:指定静态工厂完整的类名
factory-method:静态工厂中的静态方法,返回需要的对象。
constructor-arg用于指定静态方法参数的值,用法和上面介绍的构造方法一样。
spring容器会自动调用静态工厂的静态方法获取指定的对象,将其放在容器中以供使用。
案列:
public class UserStaticFactory {
public static User build(String name,Integer age){
User user = new User(name,age);
return user;
}
}
<bean id="userStaticFactory" class="com.example.sd.UserStaticFactory" factory-method="build">
<constructor-arg index="0" value="李四"/>
<constructor-arg index="1" value="25"/>
</bean>
运行后控制台打印
通过实例工厂方法创建Bean对象
让spring容器去调用某些对象的某些实例方法来生成bean对象放在容器中以供使用。
语法
<bean id="bean名称" factory-bean="需要调用的实例对象bean名称" factory-method="bean对象
中的方法">
<constructor-arg index="0" value="bean的值" ref="引用的bean名称" />
<constructor-arg index="1" value="bean的值" ref="引用的bean名称" />
<constructor-arg index="2" value="bean的值" ref="引用的bean名称" />
....
<constructor-arg index="n" value="bean的值" ref="引用的bean名称" />
</bean>
spring容器以factory-bean的值为bean名称查找对应的bean对象,然后调用该对象中factory-method 属性值指定的方法,将这个方法返回的对象作为当前bean对象放在容器中供使用。
案例:
public class UserFactory {
public User build(String name,Integer age){
User user = new User(name, age);
return user;
}
}
<bean id="userFactory" class="com.example.sd.UserFactory" />
<bean id="createBeanByUserFactory" factory-bean="userFactory" factory-method="build">
<constructor-arg index="0" value="王五"/>
<constructor-arg index="1" value="30"/>
</bean>
控制台打印
通过FactoryBean来创建Bean对象
FactoryBean接口源码:
public interface FactoryBean<T> {
/**
* 返回创建好的对象
*/
@Nullable
T getObject() throws Exception;
/**
* 返回需要创建的对象的类型
*/
@Nullable
Class<?> getObjectType();
/**
* bean是否是单例的
**/
default boolean isSingleton() {
return true;
}
}
接口中有3个方法,前面2个方法需要我们去实现,getObject方法内部由开发者自己去实现对象的创 建,然后将创建好的对象返回给Spring容器,getObjectType需要指定我们创建的bean的类型;最后一 个方法isSingleton表示通过这个接口创建的对象是否是单例的,如果返回false,那么每次从容器中获取 对象的时候都会调用这个接口的getObject() 去生成bean对象。
语法
<bean id="bean名称" class="FactoryBean接口实现类" />
案例:
public class UserFactoryBean implements FactoryBean<User> {
/**
* 获取对象,由开发者自己实现
*/
@Override
public User getObject() throws Exception {
User user = new User();
user.setName("陈六");
user.setAge(35);
return user;
}
/**
* 返回对象的类型
*/
@Override
public Class<?> getObjectType() {
return User.class;
}
/**
* 该bean是否为单例
*/
@Override
public boolean isSingleton() {
return true;
}
}
<bean id="userFactoryBean" class="com.example.sd.UserFactoryBean" />
运行后控制台打印
总结
spring容器提供了4种创建bean实例的方式,除了构造函数的方式,其他几种方式可以让我们手动去控 制对象的创建,这几种方式大家都掌握一下,能够灵活使用。