Spring has two interfaces, BeanFactory and FactoryBean, which are very similar in name and easy to confuse.
A, the BeanFactory
BeanFactory is an interface that is the top-level specification for factories in Spring. It is the core interface of the SpringIoc container and defines common methods for managing beans such as getBean() and containsBean(). Spring’s containers are all implementations of it such as:
-
DefaultListableBeanFactory
-
XmlBeanFactory
-
ApplicationContext
These implementation classes in turn have different extensions from different dimensions.
1.1, the source code
public interface BeanFactory {
// Escape the FactoryBean definition, because if a FactoryBean is retrieved using the bean name, the result is a factory-generated object,
// If you want to get the factory itself, you need to escape
String FACTORY_BEAN_PREFIX = "&";
// Based on the bean name, get the bean instance in the IOC container
Object getBean(String name) throws BeansException;
// Get the bean instance according to the bean name and Class type, add type safety verification mechanism.
<T> T getBean(String name, @Nullable Class<T> requiredType) throws BeansException;
Object getBean(String name, Object... args) throws BeansException;
<T> T getBean(Class<T> requiredType) throws BeansException;
<T> T getBean(Class<T> requiredType, Object... args) throws BeansException;
// Provide a retrieval of the bean to see if there is a bean with this name in the IOC container
boolean containsBean(String name);
// Get the bean instance based on the bean name and determine whether the bean is a singleton
boolean isSingleton(String name) throws NoSuchBeanDefinitionException;
boolean isPrototype(String name) throws NoSuchBeanDefinitionException;
boolean isTypeMatch(String name, ResolvableType typeToMatch) throws NoSuchBeanDefinitionException;
boolean isTypeMatch(String name, @Nullable Class
typeToMatch) throws NoSuchBeanDefinitionException;
// Get the Class type of the bean instance
@NullableClass<? > getType(String name)throws NoSuchBeanDefinitionException;
// Get the alias of the bean, and its original name will also be retrieved if retrieved by the alias
String[] getAliases(String name);
}
Copy the code
1.1. Application Scenarios
- Get beans (byName or byType) from the Ioc container
- Retrieves whether the specified Bean is contained in the Ioc container
- Determine whether the Bean is a singleton
Second, the FactoryBean
It is a Bean first, but not just a Bean. It is a factory Bean that produces or decorates object generation, similar to the Factory and decorator patterns in design patterns. It can produce an object when needed, and not just itself, it can return an instance of any Bean.
2.1, the source code
public interface FactoryBean<T> {
// Get the bean from the factory
@Nullable
T getObject(a) throws Exception;
// Gets the type of the object created by the Bean factory
@NullableClass<? > getObjectType();// Whether the object created by the Bean factory is a singleton
default boolean isSingleton(a) {
return true; }}Copy the code
As you can see from the interface it defines, a FactoryBean represents the responsibilities of a factory. That is, if A Bean A implements the FactoryBean interface, then A becomes A factory. The name of A is actually the object returned by the factory call to getObject(), not A itself. If you want to get an instance of factory A itself, you need to prefix the name with an am&.
- GetObject (‘name’) returns the instance in the factory
- GetObject (‘&name’) returns an instance of the factory itself
In general, beans don’t have to implement the factory pattern themselves; the Spring container acts as the factory; But in rare cases, the beans in the container are factories themselves, producing other bean instances. Other bean instances produced by the factory bean are no longer produced by the Spring container, so class elements are no longer required, unlike normal bean configurations.
2.2, the sample
Start by defining a Bean that implements the FactoryBean interface
@Component
public class MyBean implements FactoryBean {
private String message;
public MyBean(a) {
this.message = "Initialize instance by constructor";
}
@Override
public Object getObject(a) throws Exception {
It is not necessary to return an instance of MyBean itself; it can be an instance of any other object.
//如return new Student()...
return new MyBean("Create an instance from FactoryBean.getobject ()");
}
@Override
publicClass<? > getObjectType() {return MyBean.class;
}
public String getMessage(a) {
returnmessage; }}Copy the code
MyBean implements two methods of the FactoryBean interface. GetObject () returns an instance of any object. Here the test returns MyBean itself and assigns a value to the Message field before returning. We also assign a value to message in the constructor. The test code then gets the Bean instance by name, prints the message content, and then gets the instance by &+ name and prints the Message content.
@RunWith(SpringRunner.class)
@SpringBootTest(classes = TestApplication.class)
public class FactoryBeanTest {
@Autowired
private ApplicationContext context;
@Test
public void test(a) {
MyBean myBean1 = (MyBean) context.getBean("myBean");
System.out.println("myBean1 = " + myBean1.getMessage());
MyBean myBean2 = (MyBean) context.getBean("&myBean");
System.out.println("myBean2 = " + myBean2.getMessage());
System.out.println("myBean1.equals(myBean2) = "+ myBean1.equals(myBean2)); }}Copy the code
MyBean1 = instantiate myBean2 by factoryBean.getobject () = instantiate myBean1.equals(myBean2) by constructor =false
Copy the code
2.3 Application Scenarios
So why are there factorybeans? What do they do? One of the most typical uses of FactoryBeans in Spring is to create proxy objects for AOP.
We know that AOP actually means that Spring creates a proxy object at run time, that is, the object is created at run time rather than defined from the start, which fits nicely with the factory method pattern. More graphically, AN AOP proxy object creates a proxy object at run time through Java’s reflection mechanism, with methods woven into the target methods of the proxy object based on business requirements. This object in Spring is ProxyFactoryBean.
So, FactoryBeans give us a more flexible way to instantiate beans, and we can create more complex Bean instances from FactoryBeans.
Third, the difference between
- They’re both factories, but
FactoryBean
It’s essentially a BeanBeanFactory
management BeanFactory
Is the top-level interface of the Spring container,FactoryBean
More like a user-defined factory interface.
conclusion
The difference between BeanFactory and FactoryBean can be confusing, and rote memorization is not enough. It is best to understand it from the source level and in the Spring environment.
Reference: www.cnblogs.com/yulinfeng/p… www.cnblogs.com/guitu18/p/1…