Spring学习笔记之基础、IOC、DI(1)

0.0 Spring基本特性
Spring是一个开源框架;是基于Core来架构多层JavaEE系统
1.0 IOC
控制反转:把对象的创建过程交给spring容器来做。

1.1 applicationContext.xml
    beans  存放了很多个类
        把一个类放入到spring容器中,该类就是bean
    一个bean就是描述一个类
      id就是标示符
            命名规范:类的第一个字母变成小写,其他的字母保持不变
      class为类的全名


1.2 别名,模块别名
<alias name="helloWorld" alias="雷">
1.3 对象的创建方式
    1.3.1 无参构造函数。(多数使用)
<bean id=“personService" class="com.demo.bean.impl.PersonServiceImpl"/>
/**
             * spring容器在默认的情况下使用默认的构造函数创建对象
             */
            @Test
            public void testCreateObject_Default(){
                ApplicationContext context = 
                        new ClassPathXmlApplicationContext("applicationContext.xml");
                HelloWorld helloWorld = (HelloWorld)context.getBean("helloWorld");
                helloWorld.hello();
            }
    1.3.2 静态工厂。
<bean id="helloWorld2" 
                class="come.demo.spring.ioc.createobject.method.HelloWorldFactory" 
                factory-method="getInstance"></bean>

            public class HelloWorldFactory {
                public static HelloWorld getInstance(){
                    return new HelloWorld();
                }
            }


                /**
                 * 在spring容器 内部,调用了HelloWorldFactory中的getInstance方法
                 * 而该方法的内容就是创建对象的过程,是由程序员来完成
                 */
                @Test
                public void testCreateObject_StaticFactory(){
                    ApplicationContext context = 
                            new ClassPathXmlApplicationContext("applicationContext.xml");
                    HelloWorld helloWorld = (HelloWorld)context.getBean("helloWorld2");
                    helloWorld.hello();
                }
    1.3.3 实例工厂。
<bean id="helloWorldFactory" class="come.demo.spring.ioc.createobject.method.HelloWorldFactory2"></bean>
            <!-- 
                factory-bean指向了实力工厂的bean
                factory-method实例工厂对象的方法
             -->
            <bean id="helloWorld3" factory-bean="helloWorldFactory" factory-method="getInstance"></bean>
public class HelloWorldFactory2 {
                public HelloWorld getInstance(){
                    return new HelloWorld();
                }
            }
            /**
             * 实例工厂
             *   1、spring容器创建一个实例工厂bean
             *   2、该bean调用了工厂方法getInstance产生对象
             */
            @Test
            public void testCreateObject_InstanceFactory(){
                ApplicationContext context = 
                        new ClassPathXmlApplicationContext("applicationContext.xml");
                HelloWorld helloWorld = (HelloWorld)context.getBean("helloWorld3");
                helloWorld.hello();
            }
1.4 范围

    1.4.1 在默认情况下,spring容器产生的对象是单例的
        <bean id="helloWorld" 
        class="come.demo.spring.ioc.scope.HelloWorld"></bean>
public class HelloWorld {
                public HelloWorld(){
                    System.out.println("new instance");
                }

                public void hello(){
                    System.out.println("hello world");
                }
            }
            @Test
            public void testScope_Default(){
                ApplicationContext context
                 = new ClassPathXmlApplicationContext("applicationContext.xml");
                HelloWorld helloWorld = (HelloWorld)context.getBean("helloWorld");
                System.out.println(helloWorld);
                HelloWorld helloWorld2 = (HelloWorld)context.getBean("helloWorld");
                System.out.println(helloWorld2);
            }
    1.4.2 如果scope为"prototype",则为多实例
<bean id="helloWorld" 
        class="come.demo.spring.ioc.scope.HelloWorld"
        scope="prototype"></bean>

        @Test
        public void testScope_Prototype(){
            ApplicationContext context
             = new ClassPathXmlApplicationContext("applicationContext.xml");
            HelloWorld helloWorld = (HelloWorld)context.getBean("helloWorld");
            HelloWorld helloWorld2 = (HelloWorld)context.getBean("helloWorld");
        }
    1.4.3 larzyscope
        如果scope为"prototype",多例。
        那么lazy-init属性将失去作用
@Test
            public void testScope_Prototype_Lazy_Default(){
                ApplicationContext context
                 = new ClassPathXmlApplicationContext("applicationContext.xml");
                HelloWorld helloWorld = (HelloWorld)context.getBean("helloWorld");
                HelloWorld helloWorld2 = (HelloWorld)context.getBean("helloWorld");
                System.out.println(helloWorld);
                System.out.println(helloWorld2);
            }
    1.4.4 spring创建对象的时间。
        1.0 默认(一般更安全,若果spring配置文件有错误,在启动spring容器时就会报错)
<bean id="helloWorld" 
        class="come.demo.spring.ioc.scope.HelloWorld"></bean>
        1.1 加载spring容器
        1.2 spring容器调用默认的构造函数为bean创造对象
        1.3 利用context.getBean把对象取出来
        2.0 lazy-init=“true" ,在启动spring容器的时候是发现不了错误的
<bean id="helloWorld" 
        class="come.demo.spring.ioc.scope.HelloWorld"
        lazy-init="true"></bean>
        2.1 启动spring容器
        2.2 执行context.getBean
        2.3 spring容器为该bean创建对象

    1.5 ioc和destory
        1.5.1 applicationContext.xml
<!-- 
                destroy-method  销毁该对象的方法        
            -->
            <bean id="helloWorld" 
                class="come.demo.spring.ioc.initdestroy.HelloWorld"
                init-method="init"
                destroy-method="destroy"
                scope="prototype"></bean>
        1.5.2 HelloWorld
public class HelloWorld {

                public HelloWorld(){
                    System.out.println("new instance");
                }                               
                public void init(){
                    System.out.println("init");
                }
                public void destroy(){
                    System.out.println("detroy");
                }
                public void hello(){
                    System.out.println("hello world");
                }
            }   
        1.5.3 InitDestroyTest.java
public class InitDestroyTest {
                /**
                 * 1、启动spring容器
                 * 2、创建helloWorld对象
                 * 3、执行init方法  该方法是由spring容器内部调用
                 * 4、context.getBean把对象提取出来
                 * 5、对象调用方法
                 * 6、当执行close方法的时候,执行该对象的destroy方法  是由spring容器内部调用
                 */
                @Test
                public void testInitDestroy_Scope_Default(){
                    ApplicationContext context = new 
                            ClassPathXmlApplicationContext("applicationContext.xml");
                    HelloWorld helloWorld = (HelloWorld)context.getBean("helloWorld");
                    helloWorld.hello();
                    ClassPathXmlApplicationContext applicationContext = 
                            (ClassPathXmlApplicationContext)context;
                    applicationContext.close();
                }


                /**
                 * 1、启动spring容器
                 * 2、context.getBean把对象提取出来
                 * 3、创建helloWorld对象
                 * 4、执行init方法  该方法是由spring容器内部调用
                 * 5、对象调用方法
                 * 说明:不负责销毁
                 */
                @Test
                public void testInitDestroy_Scope_Prototype(){
                    ApplicationContext context = new 
                            ClassPathXmlApplicationContext("applicationContext.xml");
                    HelloWorld helloWorld = (HelloWorld)context.getBean("helloWorld");
                    helloWorld.hello();
                    ClassPathXmlApplicationContext applicationContext = 
                            (ClassPathXmlApplicationContext)context;
                    applicationContext.close();
                }
            }

2.0 DI(依赖注入)给属性赋值的过程就是依赖注入
2.1 DI setter
2.1.1 applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
    <bean id="person" class="come.demo.spring.di.xml.setter.Person">
        <!-- 
            property描述的就是bean中的属性
              name属性就是描述属性的名称
              value就是值   如果是基本属性(String),就用value赋值
              ref  如果是引用类型,用ref赋值
         -->
        <property name="pid" value="1"></property>
        <property name="name" value="王二麻子"></property>
        <property name="student" ref="student"></property>
        <property name="lists">//装配,给list赋值的过程。
            <list>
                <value>list1</value>
                <value>list2</value>
                <!-- 
                    list中存放一个student对象
                 -->
                <ref bean="student"/>
            </list>
        </property>
        <property name="objects">
            <list>
                <value>obj1</value>
                <ref bean="student"/>
            </list>
        </property>
        <property name="sets">
            <set>
                <value>set1</value>
                <ref bean="student"/>
            </set>
        </property>
        <property name="map">
            <map>
                <entry key="m1">
                    <value>m1</value>
                </entry>
                <entry key="m2">
                    <ref bean="student"/>
                </entry>
            </map>
        </property>
        <property name="properties">
            <props>
                <prop key="p1">p1</prop>
                <prop key="p2">p2</prop>
            </props>
        </property>
    </bean>
    <bean id="student" class="come.demo.spring.di.xml.setter.Student"
        scope="prototype"></bean>
</beans>

2.1.2 person.java

public class Person {
    private Long pid;
    private String name;
    private Student student;//引用类型
    private List lists;
    private Set sets;//集合
    private Map map;
    private Object[] objects;//数组
    private Properties properties;

    public Person(){
        System.out.println("person");
    }
    public Long getPid() {
        return pid;
    }
    public void setPid(Long pid) {
        this.pid = pid;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Student getStudent() {
        return student;
    }
    public void setStudent(Student student) {
        this.student = student;
    }
    public List getLists() {
        return lists;
    }
    public void setLists(List lists) {
        this.lists = lists;
    }
    public Set getSets() {
        return sets;
    }
    public void setSets(Set sets) {
        this.sets = sets;
    }
    public Map getMap() {
        return map;
    }
    public void setMap(Map map) {
        this.map = map;
    }
    public Object[] getObjects() {
        return objects;
    }
    public void setObjects(Object[] objects) {
        this.objects = objects;
    }
    public Properties getProperties() {
        return properties;
    }
    public void setProperties(Properties properties) {
        this.properties = properties;
    }
    @Override
    public String toString() {
        return "Person [pid=" + pid + ", name=" + name + ", student=" + student
                + ", lists=" + lists + ", sets=" + sets + ", map=" + map
                + ", objects=" + Arrays.toString(objects) + ", properties="
                + properties + "]";
    }
}

student.java

public class Student {
    public Student(){
        System.out.println("student");
    }
    public void say(){
        System.out.println("student");
    }
}

2.1.3
Test.java

public class DIXMLSetterTest {
    /**
     * 1、启动spring容器
     * 2、给person创建对象
     * 3、给student创建对象
     * 4、调用person的各个属性的setter方法赋值
     * 5、context.getBean
     * 6、对象调用方法
     */
    @Test
    public void testDI_XML_Setter_Default(){
        ApplicationContext context = 
                new ClassPathXmlApplicationContext("applicationContext.xml");
        Person person = (Person)context.getBean("person");
        System.out.println(person.toString());
    }

    @Test
    public void testDI_XML_Setter_Person_Default_Student_Lazyinit_TRUE(){
        ApplicationContext context = 
                new ClassPathXmlApplicationContext("applicationContext.xml");
        Person person = (Person)context.getBean("person");
        System.out.println(person.toString());
    }


    /**
     * 1、启动spring容器
     * 2、创建Student对象
     * 3、context.getBean
     * 4、创建person对象
     * 5、调用setter方法赋值
     * 6、对象调用方法
     */
    @Test
    public void testDI_XML_Setter_Person_Lazyinit_TRUE_Student_Lazyinit_Default(){
        ApplicationContext context = 
                new ClassPathXmlApplicationContext("applicationContext.xml");
        Person person = (Person)context.getBean("person");
        System.out.println(person.toString());
    }


    /**
     * 1、启动spring容器
     * 2、创建Student对象
     * 3、context.getBean
     * 4、创建person对象
     * 5、调用setter方法赋值
     * 6、对象调用方法
     */
    @Test
    public void testDI_XML_Setter_Person_Scope_Prototype_Student_Scope_Default(){
        ApplicationContext context = 
                new ClassPathXmlApplicationContext("applicationContext.xml");
        Person person = (Person)context.getBean("person");
        System.out.println(person.toString());
    }


    /**
     * 1、启动spring容器
     * 2、创建person对象
     * 3、创建student对象   student的scope为"prototype",但是创建对象在spring容器启动的时候
     *       因为Person中的很多属性都依赖于student,而这些属性的赋值发生在spring容器启动的时候
     * 4、调用setter方法赋值
     * 5、 context.getBean
     * 6、对象调用方法
     */
    @Test
    public void testDI_XML_Setter_Person_Scope_Default_Student_Scope_Prototype(){
        ApplicationContext context = 
                new ClassPathXmlApplicationContext("applicationContext.xml");
        Person person = (Person)context.getBean("person");
        System.out.println(person.toString());
    }
}

2.2 Di的init、destroy执行顺序
2.2.1 applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
    <bean id="person" class="come.demo.spring.di.xml.setterinitdestroy.Person"
        init-method="init">
        <!-- 
            property描述的就是bean中的属性
              name属性就是描述属性的名称
              value就是值   如果是基本属性(String),就用value赋值
              ref  如果是引用类型,用ref赋值
         -->
        <property name="pid" value="1"></property>
        <property name="name" value="王二麻子"></property>
        <property name="student" ref="student"></property>
        <property name="lists">
            <list>
                <value>list1</value>
                <value>list2</value>
                <!-- 
                    list中存放一个student对象
                 -->
                <ref bean="student"/>
            </list>
        </property>
        <property name="objects">
            <list>
                <value>obj1</value>
                <ref bean="student"/>
            </list>
        </property>
        <property name="sets">
            <set>
                <value>set1</value>
                <ref bean="student"/>
            </set>
        </property>
        <property name="map">
            <map>
                <entry key="m1">
                    <value>m1</value>
                </entry>
                <entry key="m2">
                    <ref bean="student"/>
                </entry>
            </map>
        </property>
        <property name="properties">
            <props>
                <prop key="p1">p1</prop>
                <prop key="p2">p2</prop>
            </props>
        </property>
    </bean>
    <bean id="student" class="come.demo.spring.di.xml.setterinitdestroy.Student"></bean>
</beans>

2.2.2 java文件
Person.java

public class Person {
    private Long pid;
    private String name;
    private Student student;
    private List lists;
    private Set sets;
    private Map map;
    private Object[] objects;
    private Properties properties;

    public void init(){
        System.out.println("init");
    }

    public Person(){
        System.out.println("person");
    }
    public Long getPid() {
        return pid;
    }
    public void setPid(Long pid) {
        this.pid = pid;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Student getStudent() {
        return student;
    }
    public void setStudent(Student student) {
        this.student = student;
    }
    public List getLists() {
        return lists;
    }
    public void setLists(List lists) {
        this.lists = lists;
    }
    public Set getSets() {
        return sets;
    }
    public void setSets(Set sets) {
        this.sets = sets;
    }
    public Map getMap() {
        return map;
    }
    public void setMap(Map map) {
        this.map = map;
    }
    public Object[] getObjects() {
        return objects;
    }
    public void setObjects(Object[] objects) {
        this.objects = objects;
    }
    public Properties getProperties() {
        return properties;
    }
    public void setProperties(Properties properties) {
        this.properties = properties;
    }
    @Override
    public String toString() {
        return "Person [pid=" + pid + ", name=" + name + ", student=" + student
                + ", lists=" + lists + ", sets=" + sets + ", map=" + map
                + ", objects=" + Arrays.toString(objects) + ", properties="
                + properties + "]";
    }
}

Student.java

public class Student {
    public Student(){
        System.out.println("student");
    }
    public void say(){
        System.out.println("student");
    }
}

2.2.3 TEST
DIXMLSetterInitDetroyTest.java

public class DIXMLSetterInitDetroyTest {
    /**
     * 1、启动spring容器
     * 2、实例化person,student
     * 3、调用person的setter方法进行装配
     * 4、调用person的init方法
     * 5、context.getBean
     * 6、person调用方法完成任务
     */
    @Test
    public void testDI_XML_Setter_InitDestroy(){
        ApplicationContext context = 
                new ClassPathXmlApplicationContext("applicationContext.xml");
        Person person = (Person)context.getBean("person");
        System.out.println(person.toString());
    }
}

2.3 DI的Setter和Constructor(构造器)
2.3.1 applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
    <bean id="person" class="come.demo.spring.di.xml.constructor.Person">
        <!-- 
            constructor-arg  代表某一个构造器的参数
              index 构造器参数的下标
              value
              ref
              type  类型
         -->
        <constructor-arg index="0" value="1" type="java.lang.String"></constructor-arg>
        <constructor-arg index="1" ref="student"></constructor-arg>
    </bean>
    <bean id="student" class="come.demo.spring.di.xml.constructor.Student"></bean>
</beans>

2.3.2
Person.java

public class Person {
    private Long pid;
    private String name;
    private Student student;
    private List lists;
    private Set sets;
    private Map map;
    private Object[] objects;
    private Properties properties;

    //构造函数
    public Person(Long pid,String name){
        this.pid = pid;
        this.name = name;
    }
    public Person(String name,Student student){
        this.name  = name;
        this.student = student;
    }

    public void init(){
        System.out.println("init");
    }
    @Override
    public String toString() {
        return "Person [pid=" + pid + ", name=" + name + ", student=" + student
                + ", lists=" + lists + ", sets=" + sets + ", map=" + map
                + ", objects=" + Arrays.toString(objects) + ", properties="
                + properties + "]";
    }
}

Student.java

public class Student {
    public Student(){
        System.out.println("student");
    }
    public void say(){
        System.out.println("student");
    }
}

2.3.3 DIXMLSetterConstructorTest.java

public class DIXMLSetterConstructorTest {
    @Test
    public void testDI_XML_Constructor(){
        ApplicationContext context = 
                new ClassPathXmlApplicationContext("applicationContext.xml");
        Person person = (Person)context.getBean("person");
        System.out.println(person.toString());
    }
}

2.3.4 如果person.java有set方法,则构造器和set均可以用
person.java

public class Person {
    private Long pid;
    private String name;
    private Student student;

    public Person(){}

    public Person(String name,Student student){
        this.name = name;
        this.student = student;
    }

    public Long getPid() {
        return pid;
    }

    public void setPid(Long pid) {
        this.pid = pid;
    }

    public String getName() {
        return name;
    }

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

    public Student getStudent() {
        return student;
    }

    public void setStudent(Student student) {
        this.student = student;
    }

    @Override
    public String toString() {
        return "Person [pid=" + pid + ", name=" + name + ", student=" + student
                + "]";
    }
}

2.4 IOC和DI的整合,完全的面向接口编程。Document实现。
applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
    <!-- 
        把documentManager,wordDocument,excelDocument,pdfDocument放入到spring容器中
     -->
     <bean id="documentManager" class="come.demo.spring.di.xml.iocdi.setter.DocumentManager">
        <!-- 
            该属性是一个接口
         -->
        <property name="document">
            <ref bean="excelDocument"/>
        </property>
     </bean>
     <bean id="wordDocument" class="come.demo.spring.di.xml.iocdi.setter.WordDocument">
     </bean>
     <bean id="excelDocument" class="come.demo.spring.di.xml.iocdi.setter.ExcelDocument">
     </bean>
    <bean id="pdfDocument" class="come.demo.spring.di.xml.iocdi.setter.PDFDocument">
    </bean>
</beans>

Document.java

public interface Document {
    public void read();
    public void write();
}

DocumentManager.java

public class DocumentManager {
    /**
     * 接口
     */
    private Document document;

    public DocumentManager(){}

    public Document getDocument() {
        return document;
    }
    public void setDocument(Document document) {
        this.document = document;
    }
    public DocumentManager(Document document){
        this.document = document;
    }
    public void read(){
        //接口调用方法
        this.document.read();
    }
    public void write(){
        this.document.write();
    }
}

ExcelDocument.java

public class ExcelDocument implements Document{

    public void read() {
        // TODO Auto-generated method stub
        System.out.println("excel read");
    }

    public void write() {
        // TODO Auto-generated method stub
        System.out.println("excel write");
    }

}

PDFDocument.java

public class PDFDocument implements Document{

    public void read() {
        // TODO Auto-generated method stub
        System.out.println("pdf read");
    }

    public void write() {
        // TODO Auto-generated method stub
        System.out.println("pdf write");
    }

}

WordDocument.java

public class WordDocument implements Document{

    public void read() {
        // TODO Auto-generated method stub
        System.out.println("word read");
    }

    public void write() {
        // TODO Auto-generated method stub
        System.out.println("word write");
    }

}

DocumentTest.java

public class DocumentTest {
    @Test
    public void testDocument_NO_Spring(){
        /**
         * 等号的左边是接口,等号的右边是实现类
         */
        Document wordDocument = new WordDocument();
        DocumentManager documentManager = new DocumentManager(wordDocument);
        documentManager.read();
        documentManager.write();
    }

    /**
     *  在客户端做到了完全的面向接口编程,程序员再也不用在客户端关心document是由谁来实现的
     */
    @Test
    public void testDocument_Spring(){
        ApplicationContext context = 
                new ClassPathXmlApplicationContext("applicationContext.xml");
        DocumentManager documentManager = (DocumentManager)context.getBean("documentManager");
        documentManager.read();
        documentManager.write();
    }
}

2.5 IOC和DI整合,MVC实现。完全面向接口编程
applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
    <bean id="personDao" class="come.demo.spring.di.xml.iocdi.setter.mvc.PersonDaoImpl"></bean>
    <bean id="personService" class="come.demo.spring.di.xml.iocdi.setter.mvc.PersonServiceImpl">
        <property name="personDao">
            <ref bean="personDao"/>
        </property>
    </bean>
    <bean id="personAction" class="come.demo.spring.di.xml.iocdi.setter.mvc.PersonAction">
        <property name="personService">
            <ref bean="personService"/>
        </property>
    </bean>
</beans>

PersonAction.java

public class PersonAction {
    private PersonService personService;

    public PersonService getPersonService() {
        return personService;
    }

    public void setPersonService(PersonService personService) {
        this.personService = personService;
    }

    public void savePerson(){
        this.personService.savePerson();
    }
}

PersonDao.java

public interface PersonDao {
    public void savePerson();
}

PersonDaoImpl.java

public class PersonDaoImpl implements PersonDao{

    public void savePerson() {
        // TODO Auto-generated method stub
        System.out.println("save person");
    }

}

PersonService.java

public interface PersonService {
    public void savePerson();
}

PersonServiceImpl.java

public class PersonServiceImpl implements PersonService{
    private PersonDao personDao;

    public PersonDao getPersonDao() {
        return personDao;
    }

    public void setPersonDao(PersonDao personDao) {
        this.personDao = personDao;
    }

    public void savePerson() {
        // TODO Auto-generated method stub
        this.personDao.savePerson();
    }
}

MVCTest.java

public class MVCTest {
    @Test
    public void testMVC(){
        ApplicationContext context = 
                new ClassPathXmlApplicationContext("applicationContext.xml");
        PersonAction personAction = (PersonAction)context.getBean("personAction");
        personAction.savePerson();
    }
}
上一篇:VB编程:利用CallByName函数对对象进行操作


下一篇:第三章 Spring进阶-IoC容器