Spring factory method to create (instantiate) bean instance code, springbean
Clear objectives
Briefly describe the problems to be solved in this article: how to transfer the Bean creation process to developers instead of using Spring to create Bean instances in Spring.
Clear thinking
How to Create a Bean instance:
1) through the constructor (with or without parameters)
Method:<bean id="" class=""/>
2) Static factory Method
Method:<Bean id = "" class = "factory class" factory-method = "static factory method"/>
Note: The factory instance is not created.
3) use the instance factory method (non-static method)
Method:
<Bean id = "factory" class = "factory class"/>
<Bean id = "" factory-bean = "factory" factory-method = "instance factory method"/>
Note: The factory instance is created.
Practical Method
Example 1:
Requirements:
1. I don't want to instantiate the bean when loading bean. xml, but want to separate the loaded bean. xml from the instantiated object.
2. Implement single-instance bean
You can use the factory method factory-method to create beans.
In this way, the bean. xml will not be directly instantiated, but the actual instantiation will start only when the method referred to by factory-method is called.
Implementation: Use spring's factory-method to create bean for a singleton
First, create a singleton object through the static internal class
Package com. spring. test. factorymethod; public class Stage {public void perform () {System. out. println ("start... ");} private Stage () {} private static class StageSingletonHolder {static Stage instance = new Stage ();} public static Stage getInstance () {return StageSingletonHolder. instance ;}}
Specify the Loading Method getInstance in the spring configuration file.
<?xml version="1.0" encoding="UTF-8"?><beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.springframework.org/schema/beans" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> <bean id="theStage" class="com.spring.test.factorymethod.Stage" factory-method="getInstance"></bean></beans>
Use the application context to call bean to obtain the instance
package com.spring.test.factorymethod;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;public class test { public static void main(String[] args) { ApplicationContext ctx = new ClassPathXmlApplicationContext("bean.xml"); Stage stage = ((Stage)ctx.getBean("theStage"));//.getInstance(); stage.perform(); }}
Execution result
January 24 6:38:18 org. springframework. context. support. abstractApplicationContext prepareRefresh information: Refreshing org. springframework. context. support. classPathXmlApplicationContext @ 512dbd1a: startup date [Sat Jan 24 18:38:18 CST 2015]; root of context hierarchy January 24, 2015 6:38:19 org. springframework. beans. factory. xml. xmlBeanDefinitionReader loadBeanDefinitions information: Loading XML bean definitions from class path resource [bean. xml] January 24 6:38:19 org. springframework. beans. factory. support. defaultListableBeanFactory preInstantiateSingletons: Pre-instantiating singletons in org. springframework. beans. factory. support. defaultListableBeanFactory @ 2d1879ea: defining beans [duke, sonnet29, poeticDuke, theStage]; root of factory hierarchy start...
Introduction to creating beans using factory methods
1. Create a Bean using the static factory Method
When using the static factory method to create a Bean instance, the class attribute must also be specified. However, the class attribute does not specify the Bean instance implementation class, but the static factory class. Because Spring needs to know which factory is used to create Bean instances. In addition, you also need to use factory-method to specify the static factory method name. Spring will call the static factory method (may contain a set of parameters) to return a Bean instance, once a specified Bean instance is obtained, the processing steps after Spring are exactly the same as creating a Bean instance using a common method. Note that when the static factory method is used to create a Bean, the factory-method must be static. This article sounds a bit dizzy, not to mention, on the Code:
First, define an interface. The static method will generate an instance of this interface:
public interface Animal { public void sayHello();}
The following are two implementation classes of the interface:
Public class Cat implements Animal {private String msg; // The setter method required for dependency injection public void setMsg (String msg) {this. msg = msg ;}@ Override public void sayHello () {System. out. println (msg + ", meow ~ Meow ~ ") ;}} Public class Dog implements Animal {private String msg; // The setter method public void setMsg (String msg) {this. msg = msg ;}@ Override public void sayHello () {System. out. println (msg + ", Wang ~ Trademanager ~ ");}}
The following AnimalFactory factory contains a static getAnimal method, which determines which object to create based on the input parameters. This is a typical static factory design model.
public clas AnimalFactory { public static Animal getAnimal(String type){ if ("cat".equalsIgnoreCase(type)){ return new Cat(); } else { return new Dog(); } }}
If you need to specify Spring to use AnimalFactory to generate Animal objects, you can make the following configuration in the Spring configuration file:
<! -- Configure the getAnimal method of AnimalFactory to generate Cat --> <bean id = "cat" class = "com. abc. AnimalFactory" factory-method = "getAnimal"> <! -- Configure the parameters of the static factory method. The getAnimal method will generate Cat-type objects --> <constructor-arg value = "cat"/> <! -- Common attributes injected by setter --> <property name = "msg" value = "cat"/> </bean> <! -- Configure the getAnimal method of AnimalFactory to generate Dog --> <bean id = "dog" class = "com. abc. AnimalFactory" factory-method = "getAnimal"> <! -- Configure the parameters of the static factory method. The getAnimal method will generate the Dog type object --> <constructor-arg value = "dog"/> <! -- Common attributes injected by setter --> <property name = "msg" value = "dog"/> </bean>
From the preceding configuration, we can see that the class and factory-method of the cat and dog Bean configurations are identical, this is because both instances use the same static factory class and the same static factory method. Only the parameters specified for this static factory method are different. Use the <constructor-arg/> element to specify parameters for the static factory method.
The method used by the main program to obtain the cat and dog Bean instances remains unchanged. You only need to call the getBean () of the Spring container:
public class Test { public static void main(String args[]){ ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); Animal a1 = context.getBean("cat", Animal.class); a1.sayHello(); Animal a2 = context.getBean("dog", Animal.class); a2.sayHello(); }}
Output result:
<Code class = "hljs"> CAT, meow ~ Meow ~ Dog, Wang ~ Trademanager ~ </Code>
When creating an instance using the static factory method, you must provide the factory class and the static factory method that generates the instance. When creating an instance using the static factory method, you need to make the following changes to the Spring configuration file;
The class attribute is not the Implementation class of the Bean instance, but the static factory class for generating the Bean instance.
Use factory-method to specify the static factory method for producing Bean instances
If the static factory method requires a parameter, use the <constructor-arg/> element to configure it.
When Spring is specified to use the static factory method to create a Bean instance, Spring will first parse the configuration file and call the static factory method of the static factory class through reflection based on the information specified in the configuration file, the Return Value of the static factory method is used as the Bean instance. In this process, Spring is no longer responsible for creating Bean instances, and Bean instances are provided by the user's static factory method.
2. Create a Bean using the instance factory Method
The instance factory method is different from the static factory method: to call the static factory method, you only need to use the factory class. To call the instance factory method, you must use the factory instance. So there is only one difference in Spring configuration: configure the static factory method to specify the static factory class, and configure the instance factory method to specify the factory instance. Similarly, the above example changes AnimalFactory:
Public clas AnimalFactory {public Animal getAnimal (String type) {// here, only the static keyword if ("cat" is removed ". repeated signorecase (type) {return new Cat () ;}else {return new Dog ();}}}
Modify the Spring file:
<! -- Configure the factory class first --> <bean id = "animalFactory" class = "com. abc. AnimalFactory"/> <! -- Use factory-bean to specify the instance factory class Object --> <bean id = "cat" factory-bean = "animalFactory" factory-method = "getAnimal"> <! -- Also specify the factory-method parameter --> <constructor-arg value = "cat"/> <property name = "msg" value = "cat"/> </bean> <bean id = "dog" factory-bean = "animalFactory" factory-method = "getAnimal"> <constructor-arg value = "dog"/> <property name = "msg" value = "dog"/> </bean>
The test class does not need to be modified, and the output result is the same as above.
In many cases, use <bean id = "bean1" class = "..." /> Define a bean. Spring will call the default non-parameter constructor to create a Bean instance. In addition, you can create Bean instances in the factory mode to separate Bean creation and use, and submit Bean creation to the factory.
Configure the factory Bean in three ways.
Abstract interface:
public interface IMusicBox { public void play(); }
1. Obtain Bean instances using static factory methods
Factory type:
public class MusicBoxFactory { public static IMusicBox createMusicBox(){ return new IMusicBox(){ public void play(){ System.out.println("Play piano..."); } }; } }
Configuration file:
<bean id="musicBox" class="test.spring.MusicBoxFactory" factory-method="createMusicBox" />
Test class:
public static void main(String[] args) { ApplicationContext ctx = new ClassPathXmlApplicationContext("bean-config.xml"); IMusicBox musicbox = (IMusicBox)ctx.getBean("musicBox"); musicbox.play(); }
2. Obtain the Bean instance using the factory instance method
Factory type:
Public class MusicBoxFactory {public IMusicBox createMusicBox () {// return new IMusicBox () {public void play () {System. out. println ("Play piano... ");}};}}
Configuration file:
<bean id="factoryBean" class="test.spring.MusicBoxFactory" /> <bean id="musicBox" factory-bean="factoryBean" factory-method="createMusicBox" />
The "factory-bean" attribute specifies the factory Bean, and the "factory-method" attribute specifies the factory method to obtain the Bean instance.
Test class:
public static void main(String[] args) { ApplicationContext ctx = new ClassPathXmlApplicationContext("bean-config.xml"); IMusicBox musicbox = (IMusicBox)ctx.getBean("musicBox"); musicbox.play(); }
3. Implement the org. springframework. beans. factory. FacotryBean interface in the factory class.
Factory type:
import org.springframework.beans.factory.FactoryBean; public class MusicBoxFactory2 implements FactoryBean { public Object getObject() throws Exception { return new IMusicBox(){ public void play(){ System.out.println("Play piano..."); } }; } public Class getObjectType() { return IMusicBox.class; } public boolean isSingleton() { return false; } }
Configuration file:
<bean id="musicBox" class="test.spring.MusicBoxFactory2"/>
Test class:
Public static void main (String [] args) {ApplicationContext ctx = new ClassPathXmlApplicationContext ("bean-config.xml"); // do not add & Return to the factory's "product" IMusicBox musicbox = (IMusicBox) ctx. getBean ("musicBox"); musicbox. play (); // Add & Return factory class instance Object obj = ctx. getBean ("& musicBox"); System. out. println (obj. getClass (). getName ());}
Classes that implement the FactoryBean interface will not be treated as common beans. Spring will automatically detect and call the getObject method to obtain Bean instances.
Summary
Let's take a look at the introduction of Spring factory method instantiation bean instances. If you have any shortcomings, leave a message to us. Thank you for your support!