spring中FactoryBean的使用
一 源码中的说明
-
If a bean implements this interface, it is used as a factory for an object to expose, not directly as a bean instance that will be exposed itself.
-
翻译:如果一个bean实现了这个接口,那么这个bean将作为一个生成object的工厂来暴漏,而不是直接将这个bean暴漏出去。
-
理解:其实暴漏的是实现方法中getObject()所生成的对象,这个bean是生成object的一个工厂。
-
This interface is heavily used within the framework itself, for example for the AOP {@link org.springframework.aop.framework.ProxyFactoryBean} or the {@link org.springframework.jndi.JndiObjectFactoryBean}. It can be used for
custom components as well; however, this is only common for infrastructure code. -
翻译:这个接口经常被用在框架本身,比如AOP中的ProxyFactoryBean或者JndiObjectFactoryBean。当然它也可以应用于常规组件。总的来说,用于基础代码比较常见。
-
理解:一般用于框架中,在实际开发中用的少。使用场景一般是,我们创建某个object比较复杂,那就需要一个实现FactoryBean接口的bean作为生成object的工厂注册到spring中。重在理解这个接口,后续在读源码时理解它的应用。
二 实例如下:
package com.springDemodemo;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.stereotype.Component;
@Component("myFactoryBean")
public class MyFactoryBean implements FactoryBean<Book> {
@Override
public Book getObject() throws Exception {
System.out.println("create book");
return new Book();
}
@Override
public Class<?> getObjectType() {
return Book.class;
}
@Override
public boolean isSingleton() {
return false;
}
}
package com.springDemodemo;
public class Book {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Book{" +
"name='" + name + '\'' +
'}';
}
}
package com.springDemodemo;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.ApplicationContext;
@SpringBootTest
class DemoApplicationTests {
@Autowired
ApplicationContext context;
@Test
void testFactoryBean() {
Object o = context.getBean("myFactoryBean");
System.out.println(o);
}
}
打印结果为:
create bookBook
{name='null'}
三 如果想获取MyFactoryBean这个bean本身(不常用),可以采用如下方式:
package com.springDemodemo;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.ApplicationContext;
@SpringBootTest
class DemoApplicationTests {
@Autowired
ApplicationContext context;
@Test
void testFactoryBean() {
Object o = context.getBean("&myFactoryBean");
System.out.println(o);
}
}
打印结果为:com.springDemodemo.MyFactoryBean@41b0ae4c