Spring框架第二篇之Bean的装配
一、默认装配方式
代码通过getBean();方式从容器中获取指定的Bean实例,容器首先会调用Bean类的无参构造器,创建空值的实例对象。
举例:
首先我在applicationContext.xml配置文件中配置了一个bean:
<?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.xsd"> <!-- 注册Service 这里相当于容器做了SomeServiceImpl myService = new SomeServiceImpl(); -->
<bean id="myService" class="com.ietree.spring.basic.ioc.SomeServiceImpl"/> </beans>
创建SomeServiceImpl对象,但需要注意的是该类的只具有带参构造函器,没有无参构造器:
package com.ietree.spring.basic.ioc; /**
* 实现类
*
* @author Root
*/
public class SomeServiceImpl implements ISomeService { private int a; // 这里注释掉了无参构造函数,希望容器通过带参构造函数创建对象
// public SomeServiceImpl() {
// System.out.println("执行无参构造器,创建SomeServiceImpl对象");
// } public SomeServiceImpl(int a) {
this.a = a;
} @Override
public void doSomeThing() {
System.out.println("执行doSomeThing()方法...");
} }
测试:
@Test
public void testConstructor() { // 创建容器对象,加载Spring配置文件
// ClassPathXmlApplicationContext会从类路径下查找配置文件
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml"); ISomeService service = (ISomeService) ac.getBean("myService");
service.doSomeThing();
}
此时程序会报以下的错误:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'myService' defined in class path resource [applicationContext.xml]: Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.ietree.spring.basic.ioc.SomeServiceImpl]: No default constructor found; nested exception is java.lang.NoSuchMethodException: com.ietree.spring.basic.ioc.SomeServiceImpl.<init>()
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:1155)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1099)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:513)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:761)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:867)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:543)
at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139)
at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:83)
at com.ietree.spring.basic.test.MyTest.testConstrutor(MyTest.java:67)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:678)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.ietree.spring.basic.ioc.SomeServiceImpl]: No default constructor found; nested exception is java.lang.NoSuchMethodException: com.ietree.spring.basic.ioc.SomeServiceImpl.<init>()
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:85)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:1147)
... 36 more
Caused by: java.lang.NoSuchMethodException: com.ietree.spring.basic.ioc.SomeServiceImpl.<init>()
at java.lang.Class.getConstructor0(Unknown Source)
at java.lang.Class.getDeclaredConstructor(Unknown Source)
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:80)
... 37 more
解析:这里的错误报的很明显,没有发现默认的构造器。
修改:为该类加上无参构造器:
package com.ietree.spring.basic.ioc; /**
* 实现类
*
* @author Root
*/
public class SomeServiceImpl implements ISomeService { private int a; public SomeServiceImpl() {
System.out.println("执行无参构造器,创建SomeServiceImpl对象");
} public SomeServiceImpl(int a) {
this.a = a;
} @Override
public void doSomeThing() {
System.out.println("执行doSomeThing()方法...");
} }
此时,再次运行测试用例,会发现运行成功。
结论:Spring容器实际上是使用了类的反射机制,会首先调用Bean类的无参构造器创建实例对象。
二、动态工厂Bean
创建SomeServiceImpl类:
package com.ietree.spring.basic.ioc; /**
* 实现类
*
* @author Root
*/
public class SomeServiceImpl implements ISomeService { public SomeServiceImpl() {
System.out.println("执行无参构造器,创建SomeServiceImpl对象");
} @Override
public void doSomeThing() {
System.out.println("执行doSomeThing()方法...");
} }
创建工厂类ServiceFactory:
package com.ietree.spring.basic.ioc; /**
* 工厂类
*
* @author Root
*/
public class ServiceFactory { public ISomeService getSomeService() {
return new SomeServiceImpl();
} }
使用动态工厂方式获取Bean对象,配置如下:
<?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.xsd"> <!-- 注册动态工厂 -->
<bean id="factory" class="com.ietree.spring.basic.ioc.ServiceFactory"/> <!-- 注册Service:动态工厂Bean -->
<bean id="myService" factory-bean="factory" factory-method="getSomeService"/> </beans>
在这里并没有注册SomeServiceImpl类,而是通过ServiceFactory工厂的getSomeService方法获取的。
测试:
@Test
public void testFactory1() { ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
ISomeService service = (ISomeService) ac.getBean("myService");
service.doSomeThing();
}
运行成功。
三、静态工厂Bean
静态工厂和动态工厂不同的是,静态工厂中使用的是静态方法创建对象,如:
package com.ietree.spring.basic.ioc; /**
* 工厂类
*
* @author Root
*/
public class ServiceFactory { // 使用静态方法创建对象
public static ISomeService getSomeService() {
return new SomeServiceImpl();
} }
对应的配置文件修改如下:
<?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.xsd"> <!-- 注册Service:静态工厂Bean -->
<bean id="myService" class="com.ietree.spring.basic.ioc.ServiceFactory" factory-method="getSomeService"/> </beans>
测试:
@Test
public void testFactory1() { ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
ISomeService service = (ISomeService) ac.getBean("myService");
service.doSomeThing();
}
成功创建SomeServiceImpl对象。
四、容器中的Bean的作用域
Bean的作用域(scope)分为四种,分别是singleton、prototype、request、session。
scope:
singleton(默认):单例模式,其对象的创建时机是在Spring容器初始化时创建,是默认值
prototype:原型模式,其对象的创建时机不是在Spring容器初始化时创建,而是在代码中真正访问时才创建,每次使用getBean方法获取的同一个<bean/>的实例都是一个新的实例
request:对于每次HTTP请求,都将会产生一个不同的Bean实例
session:对于每个不同的HTTP session,都将会产生一个不同的Bean实例
验证:
首先配置作用域为singleton:
<bean id="myService" class="com.ietree.spring.basic.ioc.SomeServiceImpl" scope="singleton"/>
测试:
@Test
public void test05() { ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml"); ISomeService service1 = (ISomeService) ac.getBean("myService");
ISomeService service2 = (ISomeService) ac.getBean("myService");
System.out.println("service1 = service2吗?" + (service1 == service2));
}
程序输出:
调用无参构造器
service1 = service2吗?true
结论:当作用域为singleton单例模式时,只会创建一个对象实例,并且对象是在Spring容器初始化时创建。
同样,当配置为prototype原型模式时:
<bean id="myService" class="com.ietree.spring.basic.ioc.SomeServiceImpl" scope="prototype"/>
程序输出:
调用无参构造器
调用无参构造器
service1 = service2吗?false
结论:构造器被调用了两次,说明创建的service1和service2不是同一个对象,并且对象是在被使用到时才创建的。
五、Bean后处理器
Bean后处理器是一种特殊的Bean,容器中所有的Bean在初始化时,均会自动执行该类的两个方法。由于该Bean是由其它Bean自动调用执行,不是程序员手工调用,故此Bean无须id属性。
需要做的是,在Bean后处理器类方法中,只要对Bean类与Bean类中的方法进行判断,就可实现对指定的Bean的指定的方法进行功能扩展与增强。方法返回的Bean对象,即是增强过的对象。
代码中需要自定义Bean后处理器类,该类就是实现了接口BeanPostProcessor的类。该接口中包含两个方法,分别在目标Bean初始化完毕之前与之后执行,它的返回值为功能被扩展或增强后的Bean对象。
举例:利用Bean后处理器实现大小写字符串转换
接口类ISomeService:
/**
* 接口类
*
* @author Root
*/
public interface ISomeService { String doSomeThing(); }
实现类SomeServiceImpl:
/**
* 实现类
*
* @author Root
*/
public class SomeServiceImpl implements ISomeService { public SomeServiceImpl() {
System.out.println("调用无参构造器");
} // 返回小写字母“abcde”
@Override
public String doSomeThing() {
return "abcde";
}
}
定义Bean处理器MyBeanPostProcessor:
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy; import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor; /**
* Bean后处理器
*
* @author Root
*/
public class MyBeanPostProcessor implements BeanPostProcessor { // bean:表示当前正在进行初始化的Bean对象
// beanName:表示当前正在进行初始化的Bean对象的id
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("执行----before()方法---");
return bean;
} @Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("执行----after()方法---"); Object obj = Proxy.newProxyInstance(
bean.getClass().getClassLoader(),
bean.getClass().getInterfaces(),
new InvocationHandler() { @Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object invoke = method.invoke(bean, args); return ((String) invoke).toUpperCase();
}
});
return obj;
} }
使用JDK动态代理实现大小写转换的功能。
配置文件:
<bean id="myService" class="com.ietree.spring.basic.ioc.method2.SomeServiceImpl"/> <!-- 注册Bean后处理器,由于该Bean是由其它Bean自动调用执行,不是程序员手工调用,故此Bean无须id属性 -->
<bean class="com.ietree.spring.basic.ioc.method2.MyBeanPostProcessor"></bean>
注意:Bean后处理器不需要配置id的,因为它是随着对象的创建自动调用的。
测试:
@Test
public void test05() { ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml"); ISomeService service = (ISomeService) ac.getBean("myService");
String result = service.doSomeThing();
System.out.println(result);
}
程序输出:
调用无参构造器
执行----before()方法---
执行----after()方法---
ABCDE
增强成功。可以判断代理类的类型,进行对单个或单独一类对象做增强。
六、定制Bean的生命周期
Bean实例从创建到最后销毁,需要经过很多过程,执行很多生命周期方法。
Step1:调用无参构造器,创建实例对象。
Step2:调用参数的setter,为属性注入值。
Step3:若Bean实现了BeanNameAware接口,则会执行接口方法setBeanName(String beanId),使Bean类可以获取其在容器中的id名称。
Step4:若Bean实现了BeanFactoryAware接口,则执行接口方法setBeanFactory(BeanFactory factory),使Bean类可以获取到BeanFactory对象。
Step5:若定义并注册了Bean后处理器BeanPostProcessor,则执行接口方法postProcessBeforeInitialization()。
Step6:若Bean实现了InitializingBean接口,则执行接口方法afterPropertiesSet()方法。该方法在Bean的所有属性的set方法执行完毕后执行,是Bean初始化结束的标志,即Bean实例化结束。
Step7:若设置了init-method方法,则执行。
Step8:若定义并注册了Bean后处理器BeanPostProcessor,则执行接口方法postProcessAfterInitialization().
Step9:执行业务方法。
Step10:若Bean实现了DisposableBean接口,则执行接口方法destroy()。
Step11:若设置了destroy-method方法,则执行。
举例:
创建接口类ISomeService:
/**
* 接口类
*
* @author Root
*/
public interface ISomeService { void doSomeThing(); }
创建接口实现类SomeServiceImpl:
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean; /**
* 实现类
*
* @author Root
*/
public class SomeServiceImpl implements ISomeService, BeanNameAware, BeanFactoryAware, InitializingBean, DisposableBean { // 两个属性
private String adao;
private String bdao; public void setAdao(String adao) {
this.adao = adao;
System.out.println("Step2:执行settter");
} public void setBdao(String bdao) {
this.bdao = bdao;
System.out.println("Step2:执行settter");
} public SomeServiceImpl() {
System.out.println("Step1:调用无参构造器");
} @Override
public void doSomeThing() {
System.out.println("Step9:执行doSomeThing()");
} public void setUp(){
System.out.println("Step7:初始化完毕之后 ");
} public void tearDown(){
System.out.println("Step11:销毁之前");
} @Override
public void setBeanName(String name) {
System.out.println("Step3:获取到bean的id = " + name);
} @Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
System.out.println("Step4:获取到BeanFactory容器 ");
} @Override
public void afterPropertiesSet() throws Exception {
System.out.println("Step6:Bean初始化完毕了 ");
} @Override
public void destroy() throws Exception {
System.out.println("Step10:实现的接口销毁之前 ");
}
}
创建BeanPostProcessor接口的实现类MyBeanPostProcessor:
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor; /**
* Bean后处理器
*
* @author Root
*/
public class MyBeanPostProcessor implements BeanPostProcessor { // bean:表示当前正在进行初始化的Bean对象
// beanName:表示当前正在进行初始化的Bean对象的id
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("Step5:执行----before()方法---");
return bean;
} @Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("Step8:执行----after()方法---");
return bean;
} }
配置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.xsd"> <!-- 注册Service -->
<bean id="myService" class="com.ietree.spring.basic.ioc.method3.SomeServiceImpl" init-method="setUp" destroy-method="tearDown">
<property name="adao" value="aaa"></property>
<property name="bdao" value="bbb"></property>
</bean> <!-- 注册Bean后处理器,由于该Bean是由其它Bean自动调用执行,不是程序员手工调用,故此Bean无须id属性 -->
<bean class="com.ietree.spring.basic.ioc.method3.MyBeanPostProcessor"></bean> </beans>
测试类:
@Test
public void test05() { String resource = "com/ietree/spring/basic/ioc/method3/applicationContext.xml";
ApplicationContext ac = new ClassPathXmlApplicationContext(resource); ISomeService service = (ISomeService) ac.getBean("myService");
service.doSomeThing();
// 对于销毁方法的执行,有两个条件:
// 1)当前的Bean需要是singleton的
// 2)要手工关闭容器
((ClassPathXmlApplicationContext) ac).close();
}
程序输出:
Step1:调用无参构造器
Step2:执行settter
Step2:执行settter
Step3:获取到bean的id = myService
Step4:获取到BeanFactory容器
Step5:执行----before()方法---
Step6:Bean初始化完毕了
Step7:初始化完毕之后
Step8:执行----after()方法---
Step9:执行doSomeThing()
Step10:实现的接口销毁之前
Step11:销毁之前
正如程序输出的序列一样,此顺序即是对象创建的调用顺序,在编程中可以在某一个过程对其进行增强操作。
七、<bean/>标签的id属性与name属性
一般情况下,命名<bean/>使用id属性,而不是用name属性,在没有id属性的情况下,name属性与id属性作用是相同的。但,当<bean/>中含有一些特殊字符时,就需要使用name属性了。
id的命名需要满足XML对ID属性命名规范:必须以字母开头,可以包含字母、数字、下划线、连字符、句号、冒号。
name属性值可以包含各种字符。
Spring框架第二篇之Bean的装配的更多相关文章
- Spring框架第二天
## Spring框架第二天 ## ---------- **课程回顾:Spring框架第一天** 1. 概述 * IOC和AOP 2. 框架的IOC的入门 * 创建applicationContex ...
- spring框架学习(四)自动装配
set注入和构造注入有时在做配置时比较麻烦.所以框架为了提高开发效率,提供自动装配功能,简化配置.spring框架式默认不支持自动装配的,要想使用自动装配需要修改spring配置文件中<bean ...
- Spring 框架基础(02):Bean的生命周期,作用域,装配总结
本文源码:GitHub·点这里 || GitEE·点这里 一.装配方式 Bean的概念:Spring框架管理的应用程序中,由Spring容器负责创建,装配,设置属性,进而管理整个生命周期的对象,称为B ...
- Spring框架是怎么解决Bean之间的循环依赖的 (转)
问题: 循环依赖其实就是循环引用,也就是两个或则两个以上的bean互相持有对方,最终形成闭环.比如A依赖于B,B依赖于C,C又依赖于A.如下图: 如何理解“依赖”呢,在Spring中有: 构造器循 ...
- Spring Cloud第二篇 | 使用并认识Eureka注册中心
本文是Spring Cloud专栏的第二篇文章,了解前一篇文章内容有助于更好的理解本文: Spring Cloud第一篇 | Spring Cloud前言及其常用组件介绍概览 一.Sprin ...
- Spring框架几种创建bean的方式
Spring框架下,Bean的创建和装配非常的灵活,提供了三种主要的方式,并且相互见可以互相看见,也就是你可以随意地采用你喜欢且合适的方式创建Bean,而不用担心他们之间的兼容问题. 一.使用XML显 ...
- 死磕Spring之IoC篇 - 开启 Bean 的加载
该系列文章是本人在学习 Spring 的过程中总结下来的,里面涉及到相关源码,可能对读者不太友好,请结合我的源码注释 Spring 源码分析 GitHub 地址 进行阅读 Spring 版本:5.1. ...
- Spring框架知识总结-注入Bean的各类异常
近日整合sping和hibernate框架时遇到了一系列的异常,本次主要说明一下spring框架可能出现的异常及解决方案. 我们借助sping强大的bean容器管理机制,通过BeanFactory轻松 ...
- Spring XML配置里的Bean自动装配
Spring自动装配 这段是我们之前编写的代码,代码中我们使用了P命名空间 并且使用手动装配的方式将car <bean id="address" class="cn ...
随机推荐
- 关于Unity中的transform组件(三)
game_root节点下右一个Cube子节点,和一个Sphere节点,脚本挂载在game_root下 四元数:(1)Quaternion rot (2)this.cube.rotation 欧拉角:V ...
- php -- php数组相关函数
array range ( mixed $low , mixed $high [, number $step ] ) 创建一个连续的数组 range('a','z'); foreach (range( ...
- Virtual Box下安装Oracle Linux 6.3
Oracle Linux 6.3已经公布快2年了,其功能有非常大的提升,增强了KVM,文件卷的在线resizing,LVM支持 raid4, 5, 6.支持很多其它的虚拟CPU数以及更大内存,详细能够 ...
- ThinkPHP项目笔记之模板篇
顾名思义:模板就是网页页面,有的是静态,有的的动态 基本语法: 1. <li><a href="{:U('User/searchlist')}">返回列表& ...
- ubuntu安装mysql-python
1.首先你要确定ubuntu更新源能用.以下的源适合13.X和14.X,低版本号的ubuntu没试过.毕竟劳资不是測试人员. 为了安全起见 cp /etc/apt/source.list /etc/a ...
- Struts2_day02--Action获取表单提交数据
Action获取表单提交数据 1 之前web阶段,提交表单到servlet里面,在servlet里面使用request对象里面的方法获取,getParameter,getParameterMap 2 ...
- Linux命令之乐--find
find是命令行工具箱中最棒的命令之一. 列出当前目录及其子目录中的文件和文件夹. [root@LAMP WebRoot]# find . -print../index.jsp./upload.jsp ...
- 《C++ Primer Plus》第3章 处理数据 学习笔记
C++的基本类型分为两组:一组由存储为证书的值组成,另一组由存储为浮点格式的值组成.整型之间通过存储键值时使用的呢存及有无符号来区分.整型从最小到最大依次是:bool,char,signed char ...
- java基础---->java中nio的使用(一)
JDK 1.4 中引入的新输入输出 (NIO) 库在标准 Java 代码中提供了高速的.面向块的 I/O.今天我们就简单的学习一下nio的知识.我笑,便面如春花,定是能感动人的,任他是谁. nio的简 ...
- 【BZOJ2616】SPOJ PERIODNI 笛卡尔树+树形DP
[BZOJ2616]SPOJ PERIODNI Description Input 第1行包括两个正整数N,K,表示了棋盘的列数和放的车数. 第2行包含N个正整数,表示了棋盘每列的高度. Output ...