博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Spring学习笔记之 Spring IOC容器(二) 之注入参数值,自动组件扫描方式,控制Bean实例化方式,使用注解方式...
阅读量:5773 次
发布时间:2019-06-18

本文共 29056 字,大约阅读时间需要 96 分钟。

 

 本节主要内容:

    1. 给MessageBean注入参数值
    2. 测试Spring自动组件扫描方式
    3. 如何控制ExampleBean实例化方式
    4. 使用注解方式重构JdbcDataSource, UserDAO, UserService

本文作者:souvc

本文出处: 

 

1 给MessageBean注入参数值

1.1 问题

 

Spring可以通过配置文件为bean注入多种类型的属性, MessageBean类用于演示Spring的多种类型数据的注入方式, 这些类型数据和注入方式包括:

1. 注入基本值。

2. 注入Bean对象(请参考Unit 1案例)。

3. 直接集合注入。

4. 引用方式集合注入

5. 注入Spring表达式值。

6. 注入null或空字符串。

 

1.2 步骤

步骤一:新建工程,导入Spring API jar包

新建名为SouvcSpringIoC_02的web工程,在该工程导入5个jar包。

 
commons-logging.jar
spring-core.jar
spring-context.jar
spring-beans.jar
spring-expression.jar
 
网盘下载jar包 :http://yunpan.cn/cQJhPMPRZeLH7  访问密码 2bf8

 

步骤二:新建Spring配置文件

在src目录下,新建Spring配置文件applicationContext.xml。该文件名为Spring默认的配置文件名,也可以自由定义名称。

applicationContext.xml文件中的代码如下所示:

 

 

步骤三:新建类MessageBean 添加基本值属性

新建类MessageBean,在该类中添加如下代码中的四个属性,并生成这几个属性对应的getter和setter方法;最后在execute方法获取这几个属性的信息,代码如下所示:

package com.souvc.bean;public class MessageBean {    private String moduleName;    private int pageSize;    private String username;    private String password = "";    public String getUsername() {        return username;    }    public void setUsername(String username) {        this.username = username;    }    public String getPassword() {        return password;    }    public void setPassword(String password) {        this.password = password;    }    public String getModuleName() {        return moduleName;    }    public void setModuleName(String moduleName) {        this.moduleName = moduleName;    }    public int getPageSize() {        return pageSize;    }    public void setPageSize(int pageSize) {        this.pageSize = pageSize;    }    public String execute() {        System.out.println("moduleName=" + moduleName);        System.out.println("pageSize=" + pageSize);        System.out.println("username=" + username);        System.out.println("password=" + password);        System.out.println("---List信息如下---");        return "success";    }}

 

步骤四:修改applicationContext.xml文件, 增加属性基本值注入

修改applicationContext.xml文件,为MessageBean的四个属性注入基本参数值,代码如图-3所示:

 

步骤五:新建类Test1, 添加测试方法获取MessageBean对象测试注入结果

新建类Test1,在类中使用ApplicationContext的方式实例化Spring容器,获取MessageBean对象,并调用execute方法。

@Test    public void test1() {        String conf = "applicationContext.xml";        ApplicationContext ac = new ClassPathXmlApplicationContext(conf);        System.out.println(ac);        MessageBean messagebean = ac.getBean("messagebean", MessageBean.class);        System.out.println(messagebean.toString());        messagebean.execute();    }

 

步骤六:运行Test1类, 测试注入结果

运行Test1类,控制台输入结果

org.springframework.context.support.ClassPathXmlApplicationContext@65b4fad5: startup date [Wed Jun 17 11:16:13 CST 2015]; root of context hierarchycom.souvc.bean.MessageBean@5d3e754fmoduleName=测试基本属性pageSize=5username=daliu_itpassword=123456---List信息如下---

 

控制台输出所示的信息,说明获取到了注入的基本属性值。

 

步骤七:为MessageBean添加集合属性,用于注入集合测试

1. 修改类MessageBean,在该类中添加如下加粗代码中的四个属性,并生成这几个属性对应的getter和setter方法;最后在execute方法获取这几个属性的信息,代码如下所示:

 
  •     private List<String> someList;
  •     private Set<String> someSet;
  •     private Map<String,Object> someMap;
  •     private Properties someProps;
 
 
package com.souvc.bean;import java.util.List;import java.util.Map;import java.util.Properties;import java.util.Set;public class MessageBean {    private String moduleName;    private int pageSize;    private String username;    private String password = "";         private List
someList; private Set
someSet; private Map
someMap; private Properties someProps; public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getModuleName() { return moduleName; } public void setModuleName(String moduleName) { this.moduleName = moduleName; } public int getPageSize() { return pageSize; } public void setPageSize(int pageSize) { this.pageSize = pageSize; } public List
getSomeList() { return someList; } public void setSomeList(List
someList) { this.someList = someList; } public Set
getSomeSet() { return someSet; } public void setSomeSet(Set
someSet) { this.someSet = someSet; } public Map
getSomeMap() { return someMap; } public void setSomeMap(Map
someMap) { this.someMap = someMap; } public Properties getSomeProps() { return someProps; } public void setSomeProps(Properties someProps) { this.someProps = someProps; } public String execute() { System.out.println("moduleName=" + moduleName); System.out.println("pageSize=" + pageSize); System.out.println("username=" + username); System.out.println("password=" + password); System.out.println("---List信息如下---"); for(String s : someList){ System.out.println(s); } System.out.println("---Set信息如下---"); for(String s : someSet){ System.out.println(s); } System.out.println("---Map信息如下---"); Set
keys = someMap.keySet(); for(String key : keys){ System.out.println(key+"=" +someMap.get(key)); } System.out.println("---Properties信息如下---"); Set
keys1 = someProps.keySet(); for(Object key : keys1){ System.out.println(key+"=" +someProps.getProperty(key.toString())); } return "success"; }}

 

2. 修改applicationContext.xml文件,为MessageBean的四个属性注入集合参数值:

北京
上海
广州
James Gosling
Martin fowler
Larry Ellision
root
1234

 

3. 运行Test1类,控制台输出结果所示:

 
org.springframework.context.support.ClassPathXmlApplicationContext@42704baa: startup date [Wed Jun 17 11:30:43 CST 2015]; root of context hierarchycom.souvc.bean.MessageBean@25961581moduleName=测试基本属性的注入pageSize=5username=daliu_itpassword=123456---List信息如下---北京上海广州---Set信息如下---James GoslingMartin fowlerLarry Ellision---Map信息如下---1001=Java语言基础1002=Java Web基础1003=Spring使用基础---Properties信息如下---password=1234username=root

 

控制台输出的信息,说明只需要通过配置Spring就可以为Bean注入集合参数值。

 

步骤八:测试引用方式集合注入

1.为Spring配置文件applicationContext.xml增加如下配置, 采用引用方式注入集合对象, 代码参考如下:

Tom
Andy
James Gosling
Martin fowler
root
1234

 

 

2. 增加Test2类测试如上配置, Test2代码如下:

package com.souvc.test;import org.junit.Test;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;import com.souvc.bean.MessageBean;public class TestCase {    @Test    public void test1() {        String conf = "applicationContext.xml";        ApplicationContext ac = new ClassPathXmlApplicationContext(conf);        System.out.println(ac);        MessageBean messagebean = ac.getBean("messagebean", MessageBean.class);        System.out.println(messagebean.toString());        messagebean.execute();    }    @Test    public void test2() {        String conf = "applicationContext.xml";        ApplicationContext ac = new ClassPathXmlApplicationContext(conf);        MessageBean bean = ac.getBean("messagebean2", MessageBean.class);        bean.execute();    }}

 

 
 

3. 执行Test2 有如下结果所示:

moduleName=资费管理pageSize=5username=andypassword=123---List信息如下---TomAndy---Set信息如下---James GoslingMartin fowler---Map信息如下---1001=Java语言基础1002=Java Web基础---Properties信息如下---password=1234username=root

 

这个结果说明, 通过引用方式也可以为bean注入集合属性.

步骤九:利用 Spring表达式注入属性值

1.在工程的src下,新建属性文件db.properties,文件内容如下:

    user=scott

2. 修改applicationContext.xml文件,注入Spring表达式值,代码所示:

 

3. 运行Test1类,控制台输出结果所示:

org.springframework.context.support.ClassPathXmlApplicationContext@68861f24: startup date [Wed Jun 17 11:41:35 CST 2015]; root of context hierarchycom.souvc.bean.MessageBean@209444d1moduleName=测试基本属性的注入pageSize=5username=daliu_itpassword=123456---List信息如下---北京上海广州---Set信息如下---James GoslingMartin fowlerLarry Ellision---Map信息如下---1001=Java语言基础1002=Java Web基础1003=Spring使用基础---Properties信息如下---password=1234username=root

 

控制台输出信息,说明获取到了注入的Spring表达式值。

 

步骤十:注入null值

1. 修改applicationContext.xml文件,将属性password注入null值,代码如图-11所示:

北京
上海
广州
James Gosling
Martin fowler
Larry Ellision
root
1234
Tom
Andy
James Gosling
Martin fowler
root
1234

 

 

2. 运行Test1类,控制台输出结果:

org.springframework.context.support.ClassPathXmlApplicationContext@2996c1b0: startup date [Wed Jun 17 11:42:47 CST 2015]; root of context hierarchycom.souvc.bean.MessageBean@195ed659moduleName=测试基本属性的注入pageSize=5username=daliu_itpassword=null---List信息如下---北京上海广州---Set信息如下---James GoslingMartin fowlerLarry Ellision---Map信息如下---1001=Java语言基础1002=Java Web基础1003=Spring使用基础---Properties信息如下---password=1234username=root

 

控制台输出所示的信息,说明获取到了注入的null值。

1.3 完整代码

MessageBean类的完整代码如下所示:

package com.souvc.bean;import java.util.List;import java.util.Map;import java.util.Properties;import java.util.Set;public class MessageBean {    private String moduleName;    private int pageSize;    private String username;    private String password = "";    private List
someList; private Set
someSet; private Map
someMap; private Properties someProps; public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getModuleName() { return moduleName; } public void setModuleName(String moduleName) { this.moduleName = moduleName; } public int getPageSize() { return pageSize; } public void setPageSize(int pageSize) { this.pageSize = pageSize; } public List
getSomeList() { return someList; } public void setSomeList(List
someList) { this.someList = someList; } public Set
getSomeSet() { return someSet; } public void setSomeSet(Set
someSet) { this.someSet = someSet; } public Map
getSomeMap() { return someMap; } public void setSomeMap(Map
someMap) { this.someMap = someMap; } public Properties getSomeProps() { return someProps; } public void setSomeProps(Properties someProps) { this.someProps = someProps; } public String execute() { System.out.println("moduleName=" + moduleName); System.out.println("pageSize=" + pageSize); System.out.println("username=" + username); System.out.println("password=" + password); System.out.println("---List信息如下---"); for (String s : someList) { System.out.println(s); } System.out.println("---Set信息如下---"); for (String s : someSet) { System.out.println(s); } System.out.println("---Map信息如下---"); Set
keys = someMap.keySet(); for (String key : keys) { System.out.println(key + "=" + someMap.get(key)); } System.out.println("---Properties信息如下---"); Set
keys1 = someProps.keySet(); for (Object key : keys1) { System.out.println(key + "=" + someProps.getProperty(key.toString())); } return "success"; }}

 

Test1,Test2的完整代码如下:

package com.souvc.test;import org.junit.Test;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;import com.souvc.bean.MessageBean;public class TestCase {    @Test    public void test1() {        String conf = "applicationContext.xml";        ApplicationContext ac = new ClassPathXmlApplicationContext(conf);        System.out.println(ac);        MessageBean messagebean = ac.getBean("messagebean", MessageBean.class);        System.out.println(messagebean.toString());        messagebean.execute();    }    @Test    public void test2() {        String conf = "applicationContext.xml";        ApplicationContext ac = new ClassPathXmlApplicationContext(conf);        MessageBean bean = ac.getBean("messagebean2", MessageBean.class);        bean.execute();    }}

 

applicationContext.xml完整代码如下:

北京
上海
广州
James Gosling
Martin fowler
Larry Ellision
root
1234
Tom
Andy
James Gosling
Martin fowler
root
1234

 

源码如下:http://yunpan.cn/cQVU3sLcMzXGC  访问密码 daf3

 

2 测试Spring自动组件扫描方式

2.1 问题

如何使用组件扫描的方式和"注解标记"配合获取容器中的ExampleBean对象。

2.2 方案

使用组件扫描,首先需要在XML配置中指定扫描类路径,配置代码如下:

 

 

上述配置,容器实例化时会自动扫描com.souvc 包及其子包下所有组件类。

指定扫描类路径后,并不是该路径下所有组件类都扫描到Spring容器的,只有在组件类定义前面有以下注解标记时,才会扫描到Spring容器。

@Component  泛指组件,当组件不好归类的时候,我们可以使用这个注解进行标注。@Name 通用注解@Service  业务层组件注解, 用于标注业务层组件@Repository  持久层组件注解,用于标注数据访问组件,即DAO组件@Controller  控制层组件注解,用于标注控制层组件(如struts中的action)

 

2.3 步骤

步骤一:新建类ExampleBean

新建类ExampleBean,在该类前使用通用组件注解“@Component”,表明ExampleBean为可被扫描的组件,代码如下所示:

package com.souvc.bean;import org.springframework.stereotype.Component;@Componentpublic class ExampleBean {    public ExampleBean() {        System.out.println("实例化ExampleBean");    }    public void execute() {        System.out.println("执行ExampleBean处理");    }}

 

 

步骤二: 修改applicationContext.xml

修改applicationContext.xml,使容器实例化时自动扫描org.tarena包及其子包下所有组件类

 

 

步骤三: 新建方法Test3

 

@Test    public void test3() {        String conf = "applicationContext.xml";        ApplicationContext ac = new ClassPathXmlApplicationContext(conf);        ExampleBean bean = ac.getBean("exampleBean", ExampleBean.class);        bean.execute();    }

 

运行Test3方法,控制台输出结果:

实例化ExampleBean
执行ExampleBean处理

 

控制台输出上述结果,说明Spring会自动使用组件扫描的方式创建ExampleBean实例, 并且Test3中获取到了这个ExampleBean对象。

2.4 完整代码

ExampleBean类的完整代码如下所示:

package com.souvc.bean;import org.springframework.stereotype.Component;@Componentpublic class ExampleBean {    public ExampleBean() {        System.out.println("实例化ExampleBean");    }    public void execute() {        System.out.println("执行ExampleBean处理");    }}

 

TestCase 类的完整代码如下所示:

package com.souvc.test;import org.junit.Test;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;import com.souvc.bean.ExampleBean;import com.souvc.bean.MessageBean;public class TestCase {    @Test    public void test1() {        String conf = "applicationContext.xml";        ApplicationContext ac = new ClassPathXmlApplicationContext(conf);        System.out.println(ac);        MessageBean messagebean = ac.getBean("messagebean", MessageBean.class);        System.out.println(messagebean.toString());        messagebean.execute();    }    @Test    public void test2() {        String conf = "applicationContext.xml";        ApplicationContext ac = new ClassPathXmlApplicationContext(conf);        MessageBean bean = ac.getBean("messagebean2", MessageBean.class);        bean.execute();    }    @Test    public void test3() {        String conf = "applicationContext.xml";        ApplicationContext ac = new ClassPathXmlApplicationContext(conf);        ExampleBean bean = ac.getBean("exampleBean", ExampleBean.class);        bean.execute();    }}

 

applicationContext.xml文件的完整代码如下所示:

北京
上海
广州
James Gosling
Martin fowler
Larry Ellision
root
1234
Tom
Andy
James Gosling
Martin fowler
root
1234

 

 

3 如何控制ExampleBean实例化方式

3.1 问题

使用组件扫描的方式,重构如何控制ExampleBean实例化为单例或非单例模式。

3.2 方案

1. 通常受Spring管理的组件,默认的作用域是"singleton"。如果需要其他的作用域可以使用@Scope注解,只要在注解中提供作用域的名称即可,代码如下:

@Component    @Scope("singleton")    public class ExampleBean {       ...        }

 

2. @PostConstruct和@PreDestroy注解标记分别用于指定初始化和销毁回调方法,代码如下:

public class ExampleBean {           @PostConstruct           public void init() {                //初始化回调方法          }                     @PreDestroy           public void destroy() {                  //销毁回调方法           }     }

 

 

3.3 步骤

步骤一:Bean对象的创建模式

1. 修改ExampleBean,使用prototype模式创建 ExampleBean 对象,修改的代码:

package com.souvc.bean;import javax.annotation.PostConstruct;import javax.annotation.PreDestroy;import org.springframework.context.annotation.Scope;import org.springframework.stereotype.Component;@Component@Scope("prototype")public class ExampleBean {    public ExampleBean() {        System.out.println("实例化ExampleBean");    }//    public void execute() {//        System.out.println("执行ExampleBean处理");//    }////    @PostConstruct//    public void init() {//        System.out.println("初始化ExampleBean对象");//    }////    @PreDestroy//    public void destroy() {//        System.out.println("销毁ExampleBean对象");//    }}

 

2. 新建类Test4在该类中创建两个ExampleBean对象,通过比较操作符==进行比较,代码如图-19所示:

@Test    public void test4() {        String conf = "applicationContext.xml";        AbstractApplicationContext ac = new ClassPathXmlApplicationContext(conf);        ExampleBean bean1 = ac.getBean("exampleBean", ExampleBean.class);        ExampleBean bean2 = ac.getBean("exampleBean", ExampleBean.class);        System.out.println(bean1 == bean2);        ac.close();    }

 

3. 运行Test4,控制台输出结果如下:

实例化ExampleBean实例化ExampleBeanfalse

 

通过前面的讲解,了解到默认情况下Spring容器是通过单例模式创建Bean对象的。通过本案例的运行结果,可以看出使用原型方式,调用了2次ExampleBean类的构造方法,说明创建了2个ExampleBean对象。

4. 如果想要使用单例模式创建对象,也可以使用注解的方式进行显示标注,修改ExampleBean类的代码所示:

package com.souvc.bean;import javax.annotation.PostConstruct;import javax.annotation.PreDestroy;import org.springframework.context.annotation.Scope;import org.springframework.stereotype.Component;@Component//@Scope("prototype")@Scope("singleton")public class ExampleBean {    public ExampleBean() {        System.out.println("实例化ExampleBean");    }//    public void execute() {//        System.out.println("执行ExampleBean处理");//    }////    @PostConstruct//    public void init() {//        System.out.println("初始化ExampleBean对象");//    }////    @PreDestroy//    public void destroy() {//        System.out.println("销毁ExampleBean对象");//    }}

 

5. 再次运行Test4,控制台输出结果如下:

实例化ExampleBeantrue
 

上述运行结果可以看得出,两个ExampleBean对象,通过比较操作符“ ==”进行比较的输出结果为true,说明Spring容器是通过单例模式创建Bean对象的。

步骤二:Bean对象的初始化和销毁

1. 修改ExampleBean类,加入方法init和方法destroy,并使用注解“@PostConstruct”和注解“@PreDestroy”指定init为初始化的回调方法、destroy为销毁的回调方法,代码如下所示:

package com.souvc.bean;import javax.annotation.PostConstruct;import javax.annotation.PreDestroy;import org.springframework.context.annotation.Scope;import org.springframework.stereotype.Component;@Component//@Scope("prototype")@Scope("singleton")public class ExampleBean {    public ExampleBean() {        System.out.println("实例化ExampleBean");    }    public void execute() {        System.out.println("执行ExampleBean处理");    }    @PostConstruct    public void init() {        System.out.println("初始化ExampleBean对象");    }    @PreDestroy    public void destroy() {        System.out.println("销毁ExampleBean对象");    }}

 

2.运行Test4类,控制台输出结果所示:

实例化ExampleBean初始化ExampleBean对象true2015-6-17 14:26:05 org.springframework.context.support.AbstractApplicationContext doClose信息: Closing org.springframework.context.support.ClassPathXmlApplicationContext@45b9ce4b: startup date [Wed Jun 17 14:26:04 CST 2015]; root of context hierarchy2015-6-17 14:26:05 org.springframework.beans.factory.support.DefaultSingletonBeanRegistry destroySingletons信息: Destroying singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@36f0b7f8: defining beans [jdbcProperties,messagebean,oneList,oneSet,oneMap,oneProps,messagebean2,exampleBean,org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.context.annotation.ConfigurationClassPostProcessor.importAwareProcessor]; root of factory hierarchy销毁ExampleBean对象

 

控制台输出了“初始化ExampleBean对象”和“销毁ExampleBean对象”,说明使用组件扫描的方式为ExampleBean类添加初始化和销毁的回调方法成功。

3.4 完整代码

ExampleBean类的完整代码如下所示:

package com.souvc.bean;import javax.annotation.PostConstruct;import javax.annotation.PreDestroy;import org.springframework.context.annotation.Scope;import org.springframework.stereotype.Component;@Component//@Scope("prototype")@Scope("singleton")public class ExampleBean {    public ExampleBean() {        System.out.println("实例化ExampleBean");    }    public void execute() {        System.out.println("执行ExampleBean处理");    }    @PostConstruct    public void init() {        System.out.println("初始化ExampleBean对象");    }    @PreDestroy    public void destroy() {        System.out.println("销毁ExampleBean对象");    }}

 

 

Test4类的完整代码如下所示:

package com.souvc.test;import org.junit.Test;import org.springframework.context.ApplicationContext;import org.springframework.context.support.AbstractApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;import com.souvc.bean.ExampleBean;import com.souvc.bean.MessageBean;public class TestCase {    @Test    public void test1() {        String conf = "applicationContext.xml";        ApplicationContext ac = new ClassPathXmlApplicationContext(conf);        System.out.println(ac);        MessageBean messagebean = ac.getBean("messagebean", MessageBean.class);        System.out.println(messagebean.toString());        messagebean.execute();    }    @Test    public void test2() {        String conf = "applicationContext.xml";        ApplicationContext ac = new ClassPathXmlApplicationContext(conf);        MessageBean bean = ac.getBean("messagebean2", MessageBean.class);        bean.execute();    }    @Test    public void test3() {        String conf = "applicationContext.xml";        ApplicationContext ac = new ClassPathXmlApplicationContext(conf);        ExampleBean bean = ac.getBean("exampleBean", ExampleBean.class);        //bean.execute();    }    @Test    public void test4() {        String conf = "applicationContext.xml";        AbstractApplicationContext ac = new ClassPathXmlApplicationContext(conf);        ExampleBean bean1 = ac.getBean("exampleBean", ExampleBean.class);        ExampleBean bean2 = ac.getBean("exampleBean", ExampleBean.class);        System.out.println(bean1 == bean2);        ac.close();    }}

 

applicationContext.xml文件的完整代码与前一案例相同。

北京
上海
广州
James Gosling
Martin fowler
Larry Ellision
root
1234
Tom
Andy
James Gosling
Martin fowler
root
1234

 

 

本文作者:souvc

本文出处: 

 

转载地址:http://uwaux.baihongyu.com/

你可能感兴趣的文章
Oracle 备份与恢复学习笔记(5_1)
查看>>
Oracle 备份与恢复学习笔记(14)
查看>>
分布式配置中心disconf第一部(基本介绍)
查看>>
Scenario 9-Shared Uplink Set with Active/Active uplink,802.3ad(LACP)-Flex-10
查看>>
UML类图中的六种关系
查看>>
探寻Interpolator源码,自定义插值器
查看>>
一致性哈希
查看>>
mysql(待整理)
查看>>
使用PullToRefresh实现下拉刷新和上拉加载
查看>>
mysql
查看>>
2012年电信业八大发展趋势
查看>>
Web日志安全分析工具 v2.0发布
查看>>
JS重载
查看>>
python2和python3同安装在Windows上,切换问题
查看>>
php加速工具xcache的安装与使用(基于LNMP环境)
查看>>
android超链接
查看>>
redhat tomcat
查看>>
统计数据库大小
查看>>
IO流的学习--文件夹下文件的复制
查看>>
第十六章:脚本化HTTP
查看>>