目录
1.2 自定义一个工厂 Bean,它需要实现 FactoryBean 接口并重写接口中定义的方法
3.1 创建一个牛奶静态工厂类,并定义一个生产牛奶的静态方法
4. 为什么静态工厂 Bean 中可以直接使用 factory-method 属性来配置方法,而实例工厂中不能使用 factory-method 属性来配置方法?
准备工作: 先创建一个maven项目,并pom.xml文件导入相关依赖。
我自己maven项目导入的相关依赖,可以参考参考。
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.19</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.3.19</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.8.2</version>
<scope>test</scope>
</dependency>
</dependencies>
1. 实现 FactoryBean 接口,并重写相应的方法
1.1 FactoryBean接口中定义的三个方法
getObject():用于书写创建复杂对象的代码,并把复杂对象作为方法的返回值返回。
getObjectType():返回所创建复杂对象的Class对象
isSingleton():设置该 Bean 对象是否为单例对象。true 表示只创建一个该类型的复杂对象,false 表示每一次都创建新的复杂对象。
1.2 自定义一个工厂 Bean,它需要实现 FactoryBean 接口并重写接口中定义的方法
public class MyFactoryBean implements FactoryBean<MyFactoryBean> {
//获取当前对象
@Override
public MyFactoryBean getObject() throws Exception {
return new MyFactoryBean();
}
//获取 Bean 对象的类型
@Override
public Class<?> getObjectType() {
return MyFactoryBean.class;
}
//设置该 Bean 对象是否为 Singleton 的实例对象
@Override
public boolean isSingleton() {
return true;
}
}
1.3 创建spring.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="myFactoryBean" class="com.funny.bean.MyFactoryBean"/>
</beans>
1.4 创建一个测试类进行测试
我在这个测试类中使用了几个注解,使用前提是必须导入开头我加的那些依赖。
@ExtendWith(SpringExtension.class) :SpringExtension.class是JUnit Jupiter的多个扩展API的实现,它为SpringTestContext Framework的现有功能集提供完全支持。通过@ExtendWith(SpringExtension.class)启用此支持。
@ContextConfiguration("classpath:spring.xml"): 使用该注解引入配置文件
@Autowired:根据类型进行自动装配
@ExtendWith(SpringExtension.class)
@ContextConfiguration("classpath:spring.xml")
public class SpringTest {
@Autowired
private ApplicationContext context;
@Test
public void test01() throws Exception {
MyFactoryBean myFactoryBean = context.getBean("myFactoryBean", MyFactoryBean.class);
System.out.println(myFactoryBean.getObject());
System.out.println(myFactoryBean.getObjectType());
System.out.println(myFactoryBean.isSingleton());
}
}
1.5 测试结果
2. 实例工厂
2.1 创建一个牛奶工厂类,并定义一个生产牛奶的方法
public class MilkFactory {
public void produceMilk() {
System.out.println("生产牛奶");
}
}
2.2 在spring.xml文件中配置
2.2.1 配置实例工厂 Bean
<bean id="milkFactory" class="com.funny.bean.MilkFactory"/>
2.2.2 配置工厂 Bean 中的工厂方法
id:引用名称,必须唯一。
factory-bean:定义工厂 Bean 的引用,实例化工厂类,必须是一个已经存在的 Bean 对象。
factory-method:指定工厂方法。无需重新调用工厂方法,在实例化对象的时候,会自己调用该方法。
<bean id="prod" factory-bean="milkFactory" factory-method="produceMilk"/>
<?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="milkFactory" class="com.funny.bean.MilkFactory"/>
<bean id="prod" factory-bean="milkFactory" factory-method="produceMilk"/>
</beans>
2.3 在测试类中进行测试
@Test
public void test02() {
MilkFactory factory = context.getBean("milkFactory",MilkFactory.class);
}
2.4 测试结果
3.静态工厂
3.1 创建一个牛奶静态工厂类,并定义一个生产牛奶的静态方法
public class MilkStaticFactory {
public static void produceMilk() {
System.out.println("Static 生产牛奶");
}
}
3.2 在spring.xml文件中配置
3.2.1 配置静态工厂 Bean
<?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="prod1" class="com.funny.bean.MilkStaticFactory" factory-method="produceMilk"/>
</beans>
3.3 测试结果
因为静态方法无须创建工厂类实例的情况下就可以调用工厂类方法,所以用实例工厂中的测试就能看到测试结果。
4. 为什么静态工厂 Bean 中可以直接使用 factory-method 属性来配置方法,而实例工厂中不能使用 factory-method 属性来配置方法?
因为实例对象中的方法必须通过对象才可以调用,而静态方法可以通过类名直接调用。