前言
在庞大的java体系中,spring有着举足轻重的地位,它给每位开发者带来了极大的便利和惊喜。我们都知道spring是创建和管理bean的工厂,它提供了多种定义bean的方式,能够满足我们日常工作中的多种业务场景。
那么问题来了,你知道spring中有哪些方式可以定义bean?
我估计很多人会说出以下三种:
没错,但我想说的是以上三种方式只是开胃小菜,实际上spring的功能远比你想象中更强大。
各位看官如果不信,请继续往下看。
1. xml文件配置bean
我们先从xml配置bean开始,它是spring最早支持的方式。后来,随着springboot越来越受欢迎,该方法目前已经用得很少了,但我建议我们还是有必要了解一下。
1.1 构造器
如果你之前有在bean.xml文件中配置过bean的经历,那么对如下的配置肯定不会陌生:
<bean id="personService" class="com.sue.cache.service.test7.PersonService">
</bean>
这种方式是以前使用最多的方式,它默认使用了无参构造器创建bean。
当然我们还可以使用有参的构造器,通过<constructor-arg>标签来完成配置。
<bean id="personService" class="com.sue.cache.service.test7.PersonService">
<constructor-arg index="0" value="susan"></constructor-arg>
<constructor-arg index="1" ref="baseInfo"></constructor-arg>
</bean>
其中:
- index表示下标,从0开始。
- value表示常量值
- ref表示引用另一个bean
1.2 setter方法
除此之外,spring还提供了另外一种思路:通过setter方法设置bean所需参数,这种方式耦合性相对较低,比有参构造器使用更为广泛。
先定义Person实体:
@Data
public class Person {
private String name;
private int age;
}
它里面包含:成员变量name和age,getter/setter方法。
然后在bean.xml文件中配置bean时,加上<property>标签设置bean所需参数。
<bean id="person" class="com.sue.cache.service.test7.Person">
<property name="name" value="susan"></constructor-arg>
<property name="age" value="18"></constructor-arg>
</bean>
1.3 静态工厂
这种方式的关键是需要定义一个工厂类,它里面包含一个创建bean的静态方法。例如:
public class SusanBeanFactory {
public static Person createPerson(String name, int age) {
return new Person(name, age);
}
}
接下来定义Person类如下:
@AllArgsConstructor
@NoArgsConstructor
@Data
public class Person {
private String name;
private int age;
}
它里面包含:成员变量name和age,getter/setter方法,无参构造器和全参构造器。
然后在bean.xml文件中配置bean时,通过factory-method参数指定静态工厂方法,同时通过<constructor-arg>设置相关参数。
<bean class="com.sue.cache.service.test7.SusanBeanFactory" factory-method="createPerson">
<constructor-arg index="0" value="susan"></constructor-arg>
<constructor-arg index="1" value="18"></constructor-arg>
</bean>
1.4 实例工厂方法
这种方式也需要定义一个工厂类,但里面包含非静态的创建bean的方法。
public class SusanBeanFactory {
public Person createPerson(String name, int age) {
return new Person(name, age);
}
}
Person类跟上面一样,就不多说了。
然后bean.xml文件中配置bean时,需要先配置工厂bean。然后在配置实例bean时,通过factory-bean参数指定该工厂bean的引用。
<bean id="susanBeanFactory" class="com.sue.cache.service.test7.SusanBeanFactory">
</bean>
<bean factory-bean="susanBeanFactory" factory-method="createPerson">
<constructor-arg index="0" value="susan"></constructor-arg>
<constructor-arg index="1" value="18"></constructor-arg>
</bean>
1.5 FactoryBean
不知道大家有没有发现,上面的实例工厂方法每次都需要创建一个工厂类,不方面统一管理。
这时我们可以使用FactoryBean接口。
public class UserFactoryBean implements FactoryBean<User> {
@Override
public User getObject() throws Exception {
return new User();
}
@Override
public Class<?> getObjectType() {
return User.class;
}
}
在它的getObject方法中可以实现我们自己的逻辑创建对象,并且在getObjectType方法中我们可以定义对象的类型。
然后在bean.xml文件中配置bean时,只需像普通的bean一样配置即可。
<bean id="userFactoryBean" cla