We're going to write simple in a few steps IOC, First design the components , Design the interface again , And then focus on Implementation .
1. Design components .
We remember Spring What are the most important components in ?BeanFactory
Containers ,BeanDefinition
Bean The basic data structure , Of course, you need to load Bean Of Resource loader
. Probably the most important components in the end .
The container is used to store initialized Bean,BeanDefinition Namely Bean The basic data structure , such as Bean The name of ,Bean Properties of PropertyValue
,Bean Methods , Whether to delay loading , Dependency, etc . The resource loader is simple , It's a read
2. Design interfaces
First of all, there must be a BeanFactory, Namely Bean Containers , The container interface has at least 2 The easiest way to do it , One is to get Bean, A registration Bean.
/** * Need one beanFactory Definition ioc Some behavior of the container For example, you can get bean, Such as registration bean, Parameter is bean The name of ,bean The definition of * * @author stateis0 * @version 1.0.0 * @Date 2017/11/30 */public interface BeanFactory { /** * according to bean The name of is taken from the container bean object * * @param name bean name * @return bean example * @throws Exception abnormal */ Object getBean(String name) throws Exception; /** * take bean Register in container * * @param name bean name * @param bean bean example * @throws Exception abnormal */ void registerBeanDefinition(String name, BeanDefinition bean) throws Exception;}
according to Bean Get the name of Bean object , The registration parameters are 2 individual , One is Bean Name , One is BeanDefinition object .
It's over Bean The most basic container , And it needs to be the simplest BeanDefinition Interface , For our convenience , But because we don't have to think about expansion , Therefore, it can be directly designed as a class ,BeanDefinition What elements and methods are needed ?
Need one Bean object , One Class object , One ClassName character string , You also need a collection of elements PropertyValues. That makes up a basic BeanDefinition The class . So what methods are needed ? In fact, it's these attributes get set Method .
Let's look at the details of this class :
package cn.thinkinjava.myspring;/*** bean The definition of ** @author stateis0*/public class BeanDefinition { /** * bean */ private Object bean; /** * bean Of CLass object */ private Class beanClass; /** * bean Class fully qualified name of */ private String ClassName; /** * The collection of properties of a class */ private PropertyValues propertyValues = new PropertyValues(); /** * obtain bean object */ public Object getBean() { return this.bean; } /** * Set up bean The object of */ public void setBean(Object bean) { this.bean = bean; } /** * obtain bean Of Class object */ public Class getBeanclass() { return this.beanClass; } /** * By setting the class name, reflection generates Class object */ public void setClassname(String name) { this.ClassName = name; try { this.beanClass = Class.forName(name); } catch (ClassNotFoundException e) { e.printStackTrace(); } } /** * obtain bean Property collection for */ public PropertyValues getPropertyValues() { return this.propertyValues; } /** * Set up bean Properties of */ public void setPropertyValues(PropertyValues pv) { this.propertyValues = pv; }}
With the basic BeanDefinition data structure , From another one
package cn.thinkinjava.myspring;import cn.thinkinjava.myspring.io.ResourceLoader;import java.util.HashMap;import java.util.Map;/** * In the abstract bean Define the read class * * @author stateis0 */public abstract class AbstractBeanDefinitionReader implements BeanDefinitionReader { /** * register bean Containers */ private Map<String, BeanDefinition> registry; /** * Resource loader */ private ResourceLoader resourceLoader; /** * The constructor must have a resource loader , The default plug-in creates a map Containers * * @param resourceLoader Resource loader */ protected AbstractBeanDefinitionReader(ResourceLoader resourceLoader) { this.registry = new HashMap<>(); this.resourceLoader = resourceLoader; } /** * Get the container */ public Map<String, BeanDefinition> getRegistry() { return registry; } /** * Get resource loader */ public ResourceLoader getResourceLoader() { return resourceLoader; } }
With these abstract classes and interfaces , We can basically form a prototype ,BeanDefinitionReader For from
3. How to achieve
We just talked about the specific process : from