理解spring的ioc容器功能并且手动(java)实现该功能

spring的确是一个非常好用的轻量级框架。关于spring的几大特色我这里就不说了,网上一大堆。我这里主要说说spring中的ioc容器的理解。

IOC全称:Inversion of Control,意思是控制反转。那么什么叫控制反转?提出这个概念目的是解决什么?

  那我们首先来回答第一个问题(什么叫控制反转?):在我们平时用java写程序的时候,如果要用到别的类,那么我们会创建一个类的对象--new Object()。这样的话这个对象是由自己主动创建的,与使用该类的对象的耦合程度很高。而控制反转就是spring的一个容器来创建对象,在一个类中需要另一个类的对象时,只需要从该容器中取出来就是了,该对象的控制权在该容器中,控制权发生了反转。

  第二个问题(提出这个概念的目的是什么?):IoC 不是一种技术,只是一种思想,一个重要的面向对象编程的法则,它能指导我们如何设计出松耦合、更优良的程序。传统应用程序都是由我们在类内部主动创建依赖对象,从而导致类与类之间高耦合,难于测试;有了IoC容器后,把创建和查找依赖对象的控制权交给了容器,由容器进行注入组合对象,所以对象与对象之间是 松散耦合,这样也方便测试,利于功能复用,更重要的是使得程序的整个体系结构变得非常灵活。

  提到IOC就不得不提DI(依赖注入)。

DI全称:Dependency Injection,意思是依赖注入。那么这个概念怎么理解?

  自然是从字面拆分来理解:依赖谁?注入谁?谁依赖?谁注入?目的是什么?

  第一个问题(依赖谁?):应用程序依赖于IOC容器

  第二个问题(注入谁?):IOC容器将应用程序需要的对象和资源注入到应用程序里面

  第三个问题(谁依赖?):应用程序依赖。(这里也可以看到控制反转的概念,一般而言,我们平时写代码需要资源时,就是从该类中主动去获取,使用IOC后,从IOC中获取)

  第四个问题(谁注入?):IOC容器向应用程序中注入资源

  第五个问题(目的是什么?):依赖注入的目的并非为软件系统带来更多功能,而是为了提升组件重用的频率,并为系统搭建一个灵活、可扩展的平台。通过依赖注入机制,我们只需要通过简单的配置,而无需任何代码就可指定目标需要的资源,完成自身的业务逻辑,而不需要关心具体的资源来自何处,由谁实现。

 

那么IOC和DI的关系呢?

  个人理解一句话:IOC容器中的对象需要依赖注入来完成具体的配置。两者其实是一种概念的不同方面所看待。

注:以上理解是看完以下博客后掺杂自己的思路所写。

https://www.cnblogs.com/liubin1988/p/8909610.html

 

 

 

那我们就来看看如何通过思路来简单实现IOC容器。

  在spring中,一般而言获取对象的方法如下:

  

ApplicationContext bean = new ClassPathXmlApplicationContext("bean.xml");
StudentInfo student = (StudentInfo) bean.getBean("student");

 

 

配置项如下:

<beans>
    <bean id="student" class = "myspring_ioc.bean.StudentInfo">
            <propertity name="age" value = "18"></propertity>    
            <propertity name="name" value = "张三"></propertity>    
    </bean>
</beans>

 

 

那么我们这里就要模拟两个类:ApplicationContext 和 ClassPathXmlApplicationContext。其中ApplicationContext 我们可以定义为抽象类,给个抽象方法,ClassPathXmlApplicationContext要继承该抽象类并且要实现该抽象方法。

ApplicationContext 类如下:

package myspring_ioc.org.springframework.context.support.ApplicationContext;
/**
 * 
 * @author xujinren
 *    applicationContext
 *
 */
public abstract class ApplicationContext {
    /**
     * get bean
     * @return
     */
    public abstract Object getBean(String id);
}

ClassPathXmlApplicationContext类如下:

/**
 *
 * @author xujinren
 *
 *parse the bean.xml and create BeanFactory
 *
 */
public class ClassPathXmlApplicationContext  extends ApplicationContext{
 
public ClassPathXmlApplicationContext(String xmlPath){

}
@Override
public Object getBean(String id){ } }

 然后怎么做?

按照思路,我们首先要将传进来的xml文件解析好,并通过反射机制创建好对象,接着就是给该对象中的属性来初始化,最后放到一个map中,以id为键,对象为值。

1.解析xml文件,解析的方法有很多种,我这里使用SAXReader来解析,需要的jar包为dom4j,请自行到网上下载。

这里说说SAXReader解析的思路。

  将xml文件以流的方式读入内存,然后生成一个document,通过操作节点的方式获得该文档中一系列的数据。注:需要导入的类都是dom4j里面的。

  我写的解析类如下:SAXReaderParseXml.java

  

package myspring_ioc.utils;

import java.io.IOException;
import java.io.InputStream;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.io.SAXReader;

public class SAXReaderParseXml {
    
    /**
     * init class ClassPathXmlApplicationContext and parse xml by 
     * SAXReader using dom4j.jar
     * @param xmlPath
     * @return document
     */
    public Document saxReaderParseXml(String xmlPath){
        InputStream is = null;
        SAXReader reader = new SAXReader();
        Document doc = null;
        try {
                is = this.getClass().getClassLoader().getResourceAsStream(xmlPath);
                if(is == null){
                    //if the xmlPath is invalid
                    throw new IOException("this xmlPath is null");
                }else{
                    doc = reader.read(is);
                    if(doc == null){
                        throw new IOException("this document is null");
                    }
                }
            
        } catch (IOException e) {
            e.printStackTrace();
        } catch (DocumentException e) {
            e.printStackTrace();
        }
        
        return doc;
    }
}

 

bean.xml配置如下:

<?xml version="1.0" encoding="utf-8"?>
<beans>
    <bean id="student" class = "myspring_ioc.bean.StudentInfo">
            <propertity name="age" value = "18"></propertity>    
            <propertity name="name" value = "张三"></propertity>    
            <propertity name="address" ref="address"></propertity>    
    </bean>
    
    <bean id = "address" class = "myspring_ioc.bean.Address">
        <propertity name = "city" value = "衡阳市"></propertity>    
        <propertity name = "province" value = "湖南省"></propertity>    
    </bean>
</beans>

 将该bean.xml放到src目录下面

 

解析生成文档返回后,就需要ClassPathXmlApplicationContext来操作该文档获得数据。首先要获得配置文件中的bean。在获得之前,要创建一个Bean类来存储信息和一个proertity类来存储要创建对象中属性的初始化值。 如下:

 1 package myspring_ioc.bean;
 2 
 3 import java.util.ArrayList;
 4 import java.util.List;
 5 
 6 /**
 7  * 
 8  * @author xujinren
 9  * this is a bean class coming from xml
10  *
11  */
12 public class Bean {
13     
14     private List<Propertity> properties = new ArrayList<>();
15     
16     private String id;
17     
18     private String classPath;
19 
20     @Override
21     public String toString() {
22         return "Bean [properties=" + properties + ", id=" + id + ", classPath=" + classPath + "]";
23     }
24 
25     public List<Propertity> getProperties() {
26         return properties;
27     }
28 
29     public void setProperties(List<Propertity> properties) {
30         this.properties = properties;
31     }
32 
33     public String getId() {
34         return id;
35     }
36 
37     public void setId(String id) {
38         this.id = id;
39     }
40 
41     public String getClassPath() {
42         return classPath;
43     }
44 
45     public void setClassPath(String classPath) {
46         this.classPath = classPath;
47     }
48 
49     @Override
50     public int hashCode() {
51         final int prime = 31;
52         int result = 1;
53         result = prime * result + ((classPath == null) ? 0 : classPath.hashCode());
54         result = prime * result + ((id == null) ? 0 : id.hashCode());
55         result = prime * result + ((properties == null) ? 0 : properties.hashCode());
56         return result;
57     }
58 
59     @Override
60     public boolean equals(Object obj) {
61         if (this == obj)
62             return true;
63         if (obj == null)
64             return false;
65         if (getClass() != obj.getClass())
66             return false;
67         Bean other = (Bean) obj;
68         if (classPath == null) {
69             if (other.classPath != null)
70                 return false;
71         } else if (!classPath.equals(other.classPath))
72             return false;
73         if (id == null) {
74             if (other.id != null)
75                 return false;
76         } else if (!id.equals(other.id))
77             return false;
78         if (properties == null) {
79             if (other.properties != null)
80                 return false;
81         } else if (!properties.equals(other.properties))
82             return false;
83         return true;
84     }
85 
86     public Bean(List<Propertity> properties, String id, String classPath) {
87         super();
88         this.properties = properties;
89         this.id = id;
90         this.classPath = classPath;
91     }
92 
93     public Bean() {
94     }
95     
96 }
Bean.java

 

package myspring_ioc.bean;

/**
 * 
 * @author xujinren
 * Properties in XML
 *
 */
public class Propertity {
    
    private String name;
    private String value;
        private String ref;
    
    public Propertity(String name, String value, String ref) {
            this.name = name;
            this.value = value;
            this.ref = ref;
        }

    public String getRef() {
            return ref;
        }

        public void setRef(String ref) {
            this.ref = ref;
        }

    @Override
    public String toString() {
        return "Propertity [name=" + name + ", value=" + value + ", ref=" + ref + "]";
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((name == null) ? 0 : name.hashCode());
        result = prime * result + ((ref == null) ? 0 : ref.hashCode());
        result = prime * result + ((value == null) ? 0 : value.hashCode());
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Propertity other = (Propertity) obj;
        if (name == null) {
            if (other.name != null)
                return false;
        } else if (!name.equals(other.name))
            return false;
        if (ref == null) {
            if (other.ref != null)
                return false;
        } else if (!ref.equals(other.ref))
            return false;
        if (value == null) {
            if (other.value != null)
                return false;
        } else if (!value.equals(other.value))
            return false;
        return true;
    }

    public Propertity(String name, String value) {
        this.name = name;
        this.value = value;
    }

    public Propertity() {
        super();
    }
    
    
}
Propertity.java

 

ClassPathXmlApplicationContext操作获取bean信息的方法如下:

/**
     *  store bean to beans from Document
     * @param doc
     */
    private void toStoreBean(Document doc) {
        Element root = doc.getRootElement();
        //get the chidren Element Iterator
        Iterator it = root.elementIterator();
        if(it != null){
            Element el  = null;
            Bean bean = null;
            while(it.hasNext()){
                el = (Element) it.next();
                bean = getBeanFromElement(el);
                //add to beans, beans is a parameter , type is List<Bean> 
                beans.add(bean);

            }
        }
    }


/**
     * get Bean from Element
     * @param el Element
     */
    private Bean getBeanFromElement(Element el) {
        Bean bean = new Bean();
        //get id
        bean.setId(el.attributeValue("id"));
        //get classPath
        bean.setClassPath(el.attributeValue("class"));
        //get propertity
        Iterator it = el.elementIterator();
        if(it != null){
            Element e = null;
            Propertity propertity = null;
            while(it.hasNext()){
                propertity = new Propertity();
                e = (Element) it.next();
                //Matching propertity
                if(e.getName().trim().equalsIgnoreCase("propertity")){
                    propertity = new Propertity();
                    if(e.attributeValue("name") != null){
                        propertity.setName(e.attributeValue("name"));
                    }

                    if(e.attributeValue("value") != null){
                        propertity.setValue(e.attributeValue("value"));
                    }

                    if(e.attributeValue("ref") != null){
                        propertity.setRef(e.attributeValue("ref"));
                    }

                    bean.getProperties().add(propertity);
                }
            }
        }
        return bean;
    }

上面的beans为一个List<Bean>的对象,用于存储bean。

获取了bean以后,就需要处理bean里面的数据,要根据classPath来反射生成对象,然后还要激活propertity里面存储的相关的set方法达到初始化成员变量。

如下:

/**
     * to create Object from beans, and store Object to BeanTOn
     * 
     */
    private  void storeBeanToBeanTon() {
        try {
            for(Bean bean : beans){
            //beanTon is a Map<String, Object>, storing the Object beanTon.put(bean.getId(), instance(bean)); } }
catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } /** * create object * @param bean * @return * @throws Exception */ private Object instance(Bean bean) throws Exception { Object obj = null; Method[] methods = null; Class<?> cls; String type = null; String setMethodName = null; //If the IOC container has the ID of this bean if(beanTon.containsKey(bean.getId())){ throw new Exception("this bean has common's id"); } //get Object from className using reflex obj = Class.forName(bean.getClassPath()).newInstance(); //get the fields methods = obj.getClass().getDeclaredMethods(); for(Method method : methods){ //if this method is start whth "set" if(method.getName().startsWith("set")){ //Then get the parameter type in this method cls = method.getParameterTypes()[0]; //Get the short name of the parameter type type = cls.getSimpleName(); //Initialize the parameters in the bean for(Propertity protertity : bean.getProperties()){ /*If the parameter is equal to the method and the string beginning with set is removed */ if(protertity.getName() != null && protertity.getName().equalsIgnoreCase(method.getName().substring(3))){ //Then the value in the property has a value and ref has no value if(protertity.getRef() == null && protertity.getValue() != null){ if(type.equals("int")){ //Reverse activation method.invoke(obj, Integer.parseInt(protertity.getValue())); }else if(type.equalsIgnoreCase("Double")){ //Reverse activation method.invoke(obj, Double.parseDouble(protertity.getValue())); }else if(type.equalsIgnoreCase("Float")){ //Reverse activation method.invoke(obj, Float.parseFloat(protertity.getValue())); }else{ //Reverse activation method.invoke(obj, protertity.getValue()); } //if ref != null }else if(protertity.getRef().trim().equalsIgnoreCase(method.getName().substring(3).trim()) && protertity.getValue() == null){ //if beanTon has the Object if(beanTon.containsKey(protertity.getRef())){ method.invoke(obj, beanTon.get(bean.getId())); }else{ Object ob = null; for(Bean bean_1 : beans){ if(protertity.getRef().equals(bean_1.getId())){ ob = instance(bean_1); break; } } method.invoke(obj, ob); } } } } } } return obj; }

 

上面方法中最关键的是:

  获取反向生成对象的类中的set开头的方法,接着从bean里面来取出propertity,一一循环与set开头的方法比较,如果那些方法去掉set后,并且忽略大小比较相等的话,就说明该对象的该成员变量在bean里面配置了初始化的参数。

  接着就取出该方法里面的参数的类别,通过类别比较来将propertity的value值的String类型转为相应参数的类型。比如:有一个propertity的name属性为“age”,value = “12”,在bean里面配置的value都为字符串。可是setAge(int  age)的方法的参数为int型,这就需要进行强制类型转换为int,再激活该对象的方法:

invoke(obj, Integer.valueOf(propertity.getValue()))

上述的obj为反射生成的对象。

 

在属性中有一个ref引用如何解决?:在spring中的bean配置是可以引用bean的。

我这里的解决方案是:在bean中如果propertity中有ref,则要先判断beanTon中是否有该相对应的id,因为ref引用的都是bean的id。

1.有,则激活就行

    方式:首先判断该propertity的name值和循环到的method的方法名是否对应(method的方法名去掉开头的set后忽略大小写与name比较),如果对应,则:

method.invoke(obj, beanTon.get(propertity.getRef()))

2.没有,则来通过反射生成一下该对象并且初始化参数

上面的函数我封装出来了一个方法:

  private Object instance(Bean bean)

那么就需要将那个要生成对象的bean传进去就行,如下:

  

Object ob = null;
for(Bean bean_1 : beans){
                                        
    if(protertity.getRef().equals(bean_1.getId())){
    ob = instance(bean_1);
        break;
        }
    }
method.invoke(obj, ob);

 

 

至此,完毕,完整的ClassPathXmlApplicationContext代码如下:

package myspring_ioc.org.springframework.context.support.ClassPathXmlApplicationContext;


import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.dom4j.Document;
import org.dom4j.Element;

import myspring_ioc.bean.Address;
import myspring_ioc.bean.Bean;
import myspring_ioc.bean.Propertity;
import myspring_ioc.bean.StudentInfo;
import myspring_ioc.org.springframework.context.support.ApplicationContext.ApplicationContext;
import myspring_ioc.utils.SAXReaderParseXml;

/**
 *
 * @author xujinren
 *
 *parse the bean.xml and create BeanFactory
 *
 */
public class ClassPathXmlApplicationContext  extends ApplicationContext{

    private SAXReaderParseXml saxReader;

    //Used to store beans obtained from XML
    private List<Bean> beans = new ArrayList<>();

    //Map for storing ID and object
    private Map<String, Object> beanTon = new HashMap<>();


    /**
     * init class ClassPathXmlApplicationContext and parse xml by 
     * SAXReader using dom4j.jar
     * @param xmlPath
     */
    public ClassPathXmlApplicationContext(String xmlPath){
        //parse the xml
        saxReader = new SAXReaderParseXml();
        Document doc = saxReader.saxReaderParseXml(xmlPath);

        toStoreBean(doc);

        storeBeanToBeanTon();
    }

    /**
     * to create Object from beans, and store Object to BeanTOn
     * 
     */
    private  void storeBeanToBeanTon() {
        try {
            for(Bean bean : beans){
                beanTon.put(bean.getId(), instance(bean));
            }
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    /**
     * create object 
     * @param bean
     * @return
     * @throws Exception
     */
    private Object instance(Bean bean) throws Exception {

        Object obj = null;

        Method[] methods = null;

        Class<?> cls;

        String type = null;

        String setMethodName = null;
        //If the IOC container has the ID of this bean
        if(beanTon.containsKey(bean.getId())){
            throw new Exception("this bean has common's id");
        }

        //get Object from className using reflex
        obj = Class.forName(bean.getClassPath()).newInstance();
        //get the fields
        methods = obj.getClass().getDeclaredMethods();

        for(Method method : methods){

            //if this method is start whth "set"
            if(method.getName().startsWith("set")){

                //Then get the parameter type in this method
                cls = method.getParameterTypes()[0];

                //Get the short name of the parameter type
                type = cls.getSimpleName();

                //Initialize the parameters in the bean
                for(Propertity protertity : bean.getProperties()){

                    /*If the parameter is equal to the method 
                    and the string beginning with set is removed
                     */
                    if(protertity.getName() != null && protertity.getName().equalsIgnoreCase(method.getName().substring(3))){
                        //Then the value in the property has a value and ref has no value
                        if(protertity.getRef() == null && protertity.getValue() != null){

                            if(type.equals("int") || type.equals("Integer")){

                                //Reverse activation
                                method.invoke(obj, Integer.parseInt(protertity.getValue()));

                            }else if(type.equalsIgnoreCase("Double")){

                                //Reverse activation
                                method.invoke(obj, Double.parseDouble(protertity.getValue()));
                            }else if(type.equalsIgnoreCase("Float")){

                                //Reverse activation
                                method.invoke(obj, Float.parseFloat(protertity.getValue()));
                            }else{

                                //Reverse activation
                                method.invoke(obj, protertity.getValue());
                            }

                            //if ref != null 
                        }else if(protertity.getRef().trim().equalsIgnoreCase(method.getName().substring(3).trim()) && protertity.getValue() == null){

                            //if beanTon has the Object
                            if(beanTon.containsKey(protertity.getRef())){
                                method.invoke(obj, beanTon.get(bean.getId()));
                            }else{
                                Object ob = null;
                                for(Bean bean_1 : beans){
                                    if(protertity.getRef().equals(bean_1.getId())){
                                        ob = instance(bean_1);
                                        break;
                                    }
                                }
                                method.invoke(obj, ob);
                            }
                        }
                    }
                }
            }
        }
        return obj;
    }
    /**
     *  store bean to beans from Document
     * @param doc
     */
    private void toStoreBean(Document doc) {
        Element root = doc.getRootElement();
        //get the chidren Element Iterator
        Iterator it = root.elementIterator();
        if(it != null){
            Element el  = null;
            Bean bean = null;
            while(it.hasNext()){
                el = (Element) it.next();
                bean = getBeanFromElement(el);
                //add to beans
                beans.add(bean);

            }
        }
    }


    /**
     * get Bean from Element
     * @param el Element
     */
    private Bean getBeanFromElement(Element el) {
        Bean bean = new Bean();
        //get id
        bean.setId(el.attributeValue("id"));
        //get classPath
        bean.setClassPath(el.attributeValue("class"));
        //get propertity
        Iterator it = el.elementIterator();
        if(it != null){
            Element e = null;
            Propertity propertity = null;
            while(it.hasNext()){
                propertity = new Propertity();
                e = (Element) it.next();
                //Matching propertity
                if(e.getName().trim().equalsIgnoreCase("propertity")){
                    propertity = new Propertity();
                    if(e.attributeValue("name") != null){
                        propertity.setName(e.attributeValue("name"));
                    }

                    if(e.attributeValue("value") != null){
                        propertity.setValue(e.attributeValue("value"));
                    }

                    if(e.attributeValue("ref") != null){
                        propertity.setRef(e.attributeValue("ref"));
                    }

                    bean.getProperties().add(propertity);
                }
            }
        }
        return bean;
    }

    
    
    
    @Override
    public Object getBean(String id) {
        return beanTon.get(id);
    }
}

测试如下:

测试所需要的pojo类如下:

 1 package myspring_ioc.bean;
 2 /**
 3  * 
 4  * @author xujinren
 5  *the entity of StudentInfo
 6  */
 7 public class StudentInfo {
 8     private String name;
 9     private int age;
10     private Address address;
11     
12     @Override
13     public String toString() {
14         return "StudentInfo [name=" + name + ", age=" + age + ", address=" + address + "]";
15     }
16 
17     public String getName() {
18         return name;
19     }
20 
21     public void setName(String name) {
22         this.name = name;
23     }
24 
25     public int getAge() {
26         return age;
27     }
28 
29     public void setAge(int age) {
30         this.age = age;
31     }
32 
33     public Address getAddress() {
34         return address;
35     }
36 
37     @Override
38     public int hashCode() {
39         final int prime = 31;
40         int result = 1;
41         result = prime * result + ((address == null) ? 0 : address.hashCode());
42         result = prime * result + age;
43         result = prime * result + ((name == null) ? 0 : name.hashCode());
44         return result;
45     }
46     
47     @Override
48     public boolean equals(Object obj) {
49         if (this == obj)
50             return true;
51         if (obj == null)
52             return false;
53         if (getClass() != obj.getClass())
54             return false;
55         StudentInfo other = (StudentInfo) obj;
56         if (address == null) {
57             if (other.address != null)
58                 return false;
59         } else if (!address.equals(other.address))
60             return false;
61         if (age != other.age)
62             return false;
63         if (name == null) {
64             if (other.name != null)
65                 return false;
66         } else if (!name.equals(other.name))
67             return false;
68         return true;
69     }
70 
71     public void setAddress(Address address) {
72         this.address = address;
73     }
74 
75     public StudentInfo(String name, int age, Address address) {
76         super();
77         this.name = name;
78         this.age = age;
79         this.address = address;
80     }
81 
82     public StudentInfo() {
83     }
84 }
StudentInfo.java
 1 package myspring_ioc.bean;
 2 /**
 3  * 
 4  * @author xujinren
 5  *the entity of Address
 6  */
 7 public class Address {
 8     
 9     //city
10     private String city;
11     //province
12     private String province;
13     
14     @Override
15     public String toString() {
16         return "Address [city=" + city + ", province=" + province + "]";
17     }
18 
19     public String getCity() {
20         return city;
21     }
22 
23     public void setCity(String city) {
24         this.city = city;
25     }
26 
27     public String getProvince() {
28         return province;
29     }
30 
31     public void setProvince(String province) {
32         this.province = province;
33     }
34 
35     @Override
36     public int hashCode() {
37         final int prime = 31;
38         int result = 1;
39         result = prime * result + ((city == null) ? 0 : city.hashCode());
40         result = prime * result + ((province == null) ? 0 : province.hashCode());
41         return result;
42     }
43 
44     @Override
45     public boolean equals(Object obj) {
46         if (this == obj)
47             return true;
48         if (obj == null)
49             return false;
50         if (getClass() != obj.getClass())
51             return false;
52         Address other = (Address) obj;
53         if (city == null) {
54             if (other.city != null)
55                 return false;
56         } else if (!city.equals(other.city))
57             return false;
58         if (province == null) {
59             if (other.province != null)
60                 return false;
61         } else if (!province.equals(other.province))
62             return false;
63         return true;
64     }
65 
66     public Address(String city, String province) {
67         this.city = city;
68         this.province = province;
69     }
70 
71     public Address() {
72         super();
73     }
74     
75     
76     
77     
78     
79 }
Address.java

测试类如下:

package myspring.test;

import myspring_ioc.bean.Address;
import myspring_ioc.bean.StudentInfo;
import myspring_ioc.org.springframework.context.support.ApplicationContext.ApplicationContext;
import myspring_ioc.org.springframework.context.support.ClassPathXmlApplicationContext.ClassPathXmlApplicationContext;

public class MySpring_Test {
    public static void main(String[] args) {
        ApplicationContext application = new ClassPathXmlApplicationContext("bean.xml");
        StudentInfo student = (StudentInfo) application.getBean("student");
        
        System.out.println(student);
        
        Address address = (Address) application.getBean("address");
        
        System.out.println(address);
    }
}

结果如下:

 

posted @ 2020-02-27 20:42  陆某人  阅读(443)  评论(0编辑  收藏  举报