本文仅供学习交流使用,侵权必删。
不作商业用途,转载请注明出处
Spring Bean的实例化有不同方式,本文将展示Spring Bean的各种实例化方式。
构造器方式
构造器方式实例化Bean只需在Bean的Class中定义构造器即可,然后将对应的Bean信息注册到容器中。
以下例子通过Xml配置的方式展示
- Bean的类定义
public class User {
private String name;
private Integer age;
public User() {
}
public User(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
- Xml配置信息
<!-- 构造器方法实例化bean配置-->
<bean id="user-by-constructor" class="com.kgyam.domain.User"/>
- 启动类
public class BeanInstantiationDemo {
public static void main(String[] args) {
BeanFactory beanFactory = new ClassPathXmlApplicationContext ("classpath:META-INF/bean-instantiation-context.xml");
User constructorUser = instantiationByConstructor (beanFactory);
}
static User instantiationByConstructor(BeanFactory beanFactory) {
User user = beanFactory.getBean ("user-by-constructor", User.class);
System.out.println ("instantiationByConstructor user:" + user);
return user;
}
}
静态工厂方法
静态工厂方法就是在刚才的User类中添加一个静态工厂方法,然后将这个方法配置到Bean的配置信息factory-method
- User中添加一个静态工厂方法
public class User {
private String name;
private Integer age;
public User() {
}
public User(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
public static User createUser() {
return new User();
}
}
- Xml配置信息
<!-- 静态工厂方法实例化bean配置-->
<bean id="user-by-static-method" factory-method="createUser" class="com.kgyam.domain.User"/>
- 启动类
public class BeanInstantiationDemo {
public static void main(String[] args) {
BeanFactory beanFactory = new ClassPathXmlApplicationContext ("classpath:META-INF/bean-instantiation-context.xml");
User staticUser = instantiationByStaticMethod (beanFactory);
}
static User instantiationByStaticMethod(BeanFactory beanFactory) {
User user = beanFactory.getBean ("user-by-static-method", User.class);
System.out.println ("instantiationByStaticMethod user:" + user);
return user;
}
}
Factory Method
工厂方法需要定义一个能创建User的工厂Bean,将这个工厂Bean配置到factory-bean。
- UserFactory接口
public interface UserFactory {
User createUser();
}
- UserFactory的默认实现
/**
* User实例工厂
*/
public class DefaultUserFactory implements UserFactory {
@Override
public User createUser() {
return User.createUser();
}
}
- Xml配置
<bean id="user-by-factory-method" factory-bean="user-factory" class="com.kgyam.domain.User"></bean>
<!-- 工厂方法的工厂bean配置-->
<bean id="user-factory" class="com.kgyam.factory.DefaultUserFactory"/>
- 启动类跟上面的是一样的,只是getBean的BeanName改下就好
FactoryBean
需要实现FactoryBean接口,并将实现类注册到容器中
- FactoryBean的实现类
/**
* User的FactoryBean
*/
public class UserFactoryBean implements FactoryBean {
@Override
public Object getObject() throws Exception {
return new User ();
}
@Override
public Class<?> getObjectType() {
return User.class;
}
}
- Xml配置
<!-- 通过factoryBean实例化user的factoryBean配置 -->
<bean id="user-factory-bean" class="com.kgyam.domain.UserFactoryBean" />
- 启动类这里,虽然bean定义的class是UserFactoryBean,但是接收返回的类型还是使用User,beanName改成对应Xml配置定义的。获取Bean的方法如下
static User instantiationByFactroyBean(BeanFactory beanFactory) {
User user = beanFactory.getBean ("user-factory-bean", User.class);
System.out.println ("instantiationByFactroyBean user:" + user);
return user;
}
ServiceLoaderFactoryBean
通过ServiceLoaderFactoryBean的这种方式实例化Bean利用的是SPI机制实现的。
- 接口类
public interface UserService {
User createUser();
}
- 接口实现类
这里定义两个接口实现类
public class DefaultUserServiceImpl implements UserService {
@Override
public User createUser() {
User user = User.createUser();
user.setName("defaultUser");
return user;
}
}
public class CustomUserServiceImpl implements UserService {
@Override
public User createUser() {
User user = User.createUser();
user.setName("customUser");
return user;
}
}
- META-INF下services配置
这里注意的是配置文件名称需要时接口的限定类名,配置文件中配置的是实现类的限定类名。这里属于SPI的知识,不过多阐述
com.kgyam.domain.service.DefaultUserServiceImpl
com.kgyam.domain.service.CustomUserServiceImpl
- Xml配置
注意这里的class配置的是ServiceLoaderFactoryBean
<bean id="service-loader-factory-bean" class="org.springframework.beans.factory.serviceloader.ServiceLoaderFactoryBean">
<property name="serviceType" value="com.kgyam.domain.service.UserService"/>
</bean>
- 启动类
public class BeanInstantiationDemo {
public static void main(String[] args) {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:META-INF/bean-instantiation-special-context.xml");
instantiationByServiceLoader(applicationContext);
}
}
/**
* 通过ServiceLoaderFactoryBean方式实例化bean
* <p>
* 使用SPI的方式还是需要遵循SPI原来的规范,META-INF下设定好services的文件
* 否则会无法找到这些实现类。
*
* @param beanFactory
*/
static void instantiationByServiceLoader(BeanFactory beanFactory) {
ServiceLoader<UserService> services = beanFactory.getBean("service-loader-factory-bean", ServiceLoader.class);
Iterator<UserService> iterator = services.iterator();
while (iterator.hasNext()) {
User user = iterator.next().createUser();
System.out.println(user);
}
}
BeanDefinitionRegistry
通过BeanDefinitionRegistry注册BeanDefinition实现Bean实例化
- 启动类
这里AnnotationConfigApplicationContext实现了BeanDefinitionRegistry,
所以通过上下文对象注册即可。
public class BeanInstantiationDemo {
public static void main(String[] args) {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext ();
applicationContext.register (BeanInstantiationSpecialDemo.class);
BeanDefinitionBuilder beanDefinitionBuilder = genericBeanDefinition (User.class);
beanDefinitionBuilder.addPropertyValue ("name", "dali");
/*
因为AnnotationConfigApplicationContext实现了BeanDefinitionRegistry接口,所以可以直接调用
*/
applicationContext.registerBeanDefinition ("dali-user", beanDefinitionBuilder.getBeanDefinition ());
applicationContext.refresh ();
User user = applicationContext.getBean ("dali-user", User.class);
System.out.println ("BeanDefinitionRegistry#registerBeanDefinition(String,Object):" + user);
applicationContext.close ();
}
}
网友评论