First of all, we need to know that there are four ways for java to get objects:
1. Instantiate an object through a new statement.
2. Create objects through reflection mechanism.
3. Create objects by clone() method
3. Create objects by deserialization
In spring framework, in order to reduce coupling, you can use xml,properties to load configuration files, and then get objects by reflection. Now let's talk about how to get proxy objects by loading configuration files of properties.
First step
create profile
accountService=com.itheima.service.impl.AccountServiceImpl accountDao=com.itheima.dao.impl.AccountDaoImpl
Profile description:
accountService is key.
com.itheima.service.impl.AccountServiceImpl is value, that is, fully qualified class name (why fully qualified class name, because object is obtained by reflection)
Step 2
The next step is to instantiate the properties object to read the configuration file using the object's method load.
After reading the configuration file, you will get a fully qualified class name, which makes it easier to create objects.
package com.itheima.factory; import java.io.IOException; import java.io.InputStream; import java.util.Properties; public class BeanFactory { private static Properties props; static { InputStream in = BeanFactory.class.getClassLoader().getResourceAsStream("bean.properties"); //Instance object props = new Properties(); try { //Read configuration files props.load(in); } catch (IOException e) { e.printStackTrace(); } } public static Object getBean(String beanName){ Object bean = null; //Official Document Interpretation of getProperty Method /* Search for properties using the key specified in this property list. */ String beanPath = props.getProperty(beanName); try { //Obtain objects bean = Class.forName(beanPath).newInstance(); } catch (Exception e) { e.printStackTrace(); } //Return object, who calls me, who I return to return bean; } }
Step 3
Reform issues
The above code still has problems, as shown below.
public static void main(String[] args) { //IAccountService as = new AccountServiceImpl(); for(int i=0;i<5;i++){ IAccountService as = (IAccountService)BeanFactory.getBean("accountService"); as.saveAccount(); System.out.println(as); } }
In the above code, I let him loop five times and output different results each time, as shown in the figure.
Without a single call, a new object will be generated, which will cause inefficiency.
So let's go to step four and see how we can solve this problem (step four is equivalent to introducing the concept of spring containers)
Step 4
The first thing you need to know is why each call to the getBean method creates a new object, and that's why newInstance()
The solution is to store the object in Map after it is created, so the static code block not only needs to get the object, but also instantiate the container Map, and add the object to the container.
package com.itheima.factory; import java.io.IOException; import java.io.InputStream; import java.util.Enumeration; import java.util.HashMap; import java.util.Map; import java.util.Properties; public class BeanFactory { private static Properties props; private static Map<String,Object> beans; static { InputStream in = BeanFactory.class.getClassLoader().getResourceAsStream("bean.properties"); //Instance object props = new Properties(); try { //Read configuration files props.load(in); //Instance container beans = new HashMap(); //Viewing API Document Discovery //keys() inherits from Hashtable < Object, Object > //All keys of the configuration file can be retrieved using keys(). Enumeration keys = props.keys(); //Traversal enumeration while(keys.hasMoreElements()){ String key = keys.nextElement().toString(); //Get value from Key String beanPath = props.getProperty(key); //Reflective Creation Object Object value = Class.forName(beanPath).newInstance(); //Save key s and value s into the map collection beans.put(key,value); } } catch (Exception e) { e.printStackTrace(); } } //Objects are already created at initialization time, so getting them is not that difficult. public static Object getBean(String beanName) { return beans.get(beanName); } }
Last step
Now, no matter how many times getBean is called, there is only one object. Why is there only one object? Because the object is created when the static code block is initialized and added to the container, you get it from the container through the getBean method, not from the new Instance () again?
Write after the article:
I remember learning spring for the first time, 20 days ago.
Today, I started learning spring again. Suddenly, I felt that I could write an article about it. Ha-ha.
Passing big fellows, see me write bad, more advice.