I deconstruct how spring manages java objects with a simple example.
First, define a simple pojo, the code is as follows:
package com.jvk.ken.spring;public class Demo {private String name;public Demo() {name="I'm Demo.";}public void printName() {System.out.println(name);}public void setName(String name) {this.name = name;}}The corresponding spring configuration file is as follows:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation=" http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd"> <bean id="demo" /> </beans>
The simple test code is as follows:
package com.jvk.ken.spring;import org.springframework.beans.factory.BeanFactory;import org.springframework.beans.factory.xml.XmlBeanFactory;import org.springframework.core.io.ClassPathResource;public class Test {public static void main(String[] args) throws Exception {testSpring();}private static void testSpring() throws Exception {BeanFactory bf = new XmlBeanFactory(new ClassPathResource("applicationContext.xml"));Demo bean = (Demo) bf.getBean("demo");System.out.println(bean.getClass());bean.printName();}}Run the Test class and output the following information, indicating that a simple spring example has been successfully run.
2012-3-28 22:18:07 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions Information: Loading XML bean definitions from class path resource [applicationContext.xml] class com.jvk.ken.spring.Demo I'm Demo.
From the short Java code and xml configuration file, we can see that XmlBeanFactory assembles javabean by reading the xml configuration file, and returns the required object when the user calls the getBean method. To mimic its behavior, I define a simple beanFactory.
package com.jvk.ken.spring;import java.util.HashMap;import java.util.Map;public class MyBeanFactory {// Save the definition of bean Map<String, Class> beans = new HashMap<String, Class>();public Object getBean(String id) throws InstantiationException, IllegalAccessException {return beans.get(id).newInstance();}private String xmlFile;public MyBeanFactory(String xmlFile) throws ClassNotFoundException {super(); this.xmlFile = xmlFile;init();}private void init() throws ClassNotFoundException {// Initialize and parse XML, the actual parsing of XML is omitted here, and use hard code to imitate System.out.println("Configuration file: "+xmlFile);String className = "com.jvk.ken.spring.Demo";Class<?> loadClass = this.getClass().getClassLoader().loadClass( className);beans.put("demo", loadClass);}}The test code is as follows:
package com.jvk.ken.spring;public class Test {public static void main(String[] args) throws Exception {testNotSpring();}private static void testNotSpring() throws Exception {MyBeanFactory bf = new MyBeanFactory("applicationContext.xml");Demo bean = (Demo) bf.getBean("demo");System.out.println(bean.getClass());bean.printName();}}After running, the following information is output:
Configuration file: applicationContext.xml class com.jvk.ken.spring.Demo I'm Demo.
The above short code shows how spring acts as the simplest bean factory. Let’s adjust the code slightly below to analyze what happens in spring. First, change the parameterless construction method of the Demo class to private.
private Demo() { name="I'm Demo."; }Running the test code revealed that there was no difference in the spring test results, but my customized MyBeanFactory reported the following error message:
Exception in thread "main" java.lang.IllegalAccessException: Class com.jvk.ken.spring.MyBeanFactory can not access a member of class com.jvk.ken.spring.Demo with modifiers "private" at sun.reflect.Reflection.ensureMemberAccess(Reflection.java:65) at java.lang.Class.newInstance0(Class.java:349) at java.lang.Class.newInstance(Class.java:308) at com.jvk.ken.spring.MyBeanFactory.getBean(MyBeanFactory.java:12) at com.jvk.ken.spring.Test.testNotSpring(Test.java:25) at com.jvk.ken.spring.Test.main(Test.java:9)
Spring is so magical? No, the code I wrote is just too simple, and can be run directly with a slight modification.
public Object getBean(String id) throws Exception { Class class1 = beans.get(id); Constructor declaredConstructor = class1.getDeclaredConstructor(); declaredConstructor.setAccessible(true); return declaredConstructor.newInstance(); }The above is the purest javabean managed by spring container. Spring also supports another type of bean, called factory bean, the example is better than a thousand words, please see the code
package com.jvk.ken.spring;import org.springframework.beans.factory.FactoryBean;public class DemoFactory implements FactoryBean {@Override public Object getObject() throws Exception {return new Demo();}@Override public Class getObjectType() {return Demo.class;}@Override public Boolean isSingleton() {return false;}}After adding the DemoFactory class, modify the spring configuration file at the same time
<bean id="demo" />
The other codes are not modified. After running the test code, the output results are exactly the same as before. Why is the class com.jvk.ken.spring.DemoFactory with ID is configured, but the result returned is a Demo instance? This is because spring detects that DemoFactory is a special bean that implements the FactoryBean interface. The getObject method will be called before returning the result, so the final result is the Demo object. Of course, if we really need to get the factory bean, we can write bf.getBean("&demo") like this.
Summarize
The above is all the detailed explanation of the spring implementation bean object creation code, I hope it will be helpful to everyone. Interested friends can continue to refer to other related topics on this site. If there are any shortcomings, please leave a message to point it out. Thank you friends for your support for this site!