第一章Spring简介目标•理解什么是Spring•理解Spring的用途Spring简介•Spring是一个开源框架,它的目的是为了简化企业级系统开发而诞生的•Spring从小里说,是个容器,往大里说,就是个框架•Spring是轻量级的,它的Jar包只有1M多一点,而且,它是非侵入式的:你一般不需要在你的类里import它的包理解容器与框架•什么是容器,请回忆ServletWeb容器ServletAServletB理解容器与框架•什么是容器,请回忆ServletWeb容器ServletAServletBServletA容器外部的Servlet无法使用只有这个Servlet由容器管理,它才能被客户端调用,然后由容器负责实例化、初始化、销毁这个Servlet那么什么是框架Web容器ServletA客户端每次请求和响应,都有些重复的事情要做,比如:国际化、日志、事务处理、异常处理、验证、自动处理请求参数等等那么什么是框架Web容器ServletA客户端除此之外,应用程序里还需要经常访问一些服务,每种服务的访问方式、方法是不一样的消息服务DBWebServiceLDAPWeb容器ServletASpring框架这就是框架业务逻辑实现A客户端消息服务DBWebServiceLDAP日志事务处理异常处理国际化验证处理请求参数Framework的定义•框架不仅要负责管理某些Bean的生命周期(容器的功能),还需要负责搭建某些基础设施(那些通用的部分)•例如:Struts能够称之为一个框架,是因为它负责管理ActionActionFormActionForward这些对象的生命周期;另外它提供了国际化、异常处理、自动包装表单请求、验证等通用的功能•Hibernate也可以称之为一个框架,因为它维护持久化对象的生命周期,持久化对象的通用增删改查方法Spring既是容器也是框架•由Spring负责业务逻辑A对象的实例化、初始化、服务(被调用)等,这是Spring作为容器的职责•Spring将大多数可重用、与业务逻辑无关的功能能够自行或交由其他组件完成、这是它作为一个框架的职责Spring与其它容器的不同Spring框架业务逻辑实现A日志事务处理异常处理国际化验证处理请求参数业务逻辑类A是POJO,不需要实现特殊接口,也不需要继承基类。因此在容器外也是可用的Spring与其它框架的不同•比如将Spring与我们刚学习的Struts框架,Hibernate框架相对比,他们的不同之处在于:–Spring还可以集成其它框架,它是一个“大”框架–Spring是专注于企业应用的框架,它所涉及的领域非常之广泛–Struts只是专注于实现Web应用程序开发的MVC部分–Hibernate只是专注于数据持久层的部分Web容器ServletASpring框架Spring可以集成Struts业务逻辑实现A客户端消息服务DBWebServiceLDAP日志事务处理异常处理Struts框架国际化验证处理请求参数Web容器ServletASpring框架Spring可以集成Hibernate业务逻辑实现A客户端消息服务DBWebServiceLDAP日志事务处理异常处理Struts框架国际化验证处理请求参数Hibernat框架Hello,Spring•创建Spring工程的步骤1.添加spring.jarcommons-logging.jarlog4j.jarlog4j.properties2.编写接口3.编写实现类1,实现类24.编写配置文件5.测试Log4j配置简介•log4j.properties的位置•log4j的日志级别:DEBUG,INFO,WARN,ERROR•程序代码中指定日志信息的级别,根据配置文件,将不同级别的日志信息输出到文件或是控制台上Log4j配置简介•log4j.rootLogger=WARN,CONSOLE,FILE•log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppenderlog4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayoutlog4j.appender.CONSOLE.layout.ConversionPattern=%d%p[%c]-%m%n•log4j.appender.FILE=org.apache.log4j.FileAppenderlog4j.appender.FILE.File=file.loglog4j.appender.FILE.Append=falselog4j.appender.FILE.layout=org.apache.log4j.PatternLayoutlog4j.appender.FILE.layout.ConversionPattern=%d%p[%c]-%m%n布局布局格式默认日志级别Appender负责指定输出位置Log4j配置简介•log4j.appender.ROLLING_FILE=org.apache.log4j.RollingFileAppenderlog4j.appender.ROLLING_FILE.Threshold=ERRORlog4j.appender.ROLLING_FILE.File=rolling.loglog4j.appender.ROLLING_FILE.Append=truelog4j.appender.ROLLING_FILE.MaxFileSize=10KBlog4j.appender.ROLLING_FILE.MaxBackupIndex=1log4j.appender.ROLLING_FILE.layout=org.apache.log4j.PatternLayoutlog4j.appender.ROLLING_FILE.layout.ConversionPattern=%d%p[%c]-%m%n•log4j.logger.org.springframework=INFOlog4j.logger.org.hibernate=INFOlog4j.logger.org.yihang=INFO针对某个包的日志级别设置针对某个Appender的日志级别设置Log4j使用注意事项•Log4j在用在JBoss环境中使用方法需要注意:由于JBoss本身也使用了Log4j,因此为了避免冲突,你需要提供自己的log4j.properties和log4j.jar•Log4j.properties需要放置在WEB-INF/classes目录下,与你的顶层包平级•Log4j.jar需要放置在WEB-INF/lib下作业•亚瑟王手下有一批圆桌骑士(knight),他们的接受亚瑟王的直接委派(order)。亚瑟王布置给圆桌骑士的任务(task)有很多,比如:屠杀恶龙(killdragon)、拯救美女(rescuebeauty)等任务。每个任务都需要前期的准备工作(prepare)、执行(execute)、汇报几个步骤。另外,虽然圆桌骑士都都向亚瑟王宣誓忠诚、正直,但亚瑟王仍然不太放心。秘密派出间谍监视骑士们完成任务的过程,并要求间谍在任务完成时汇报(report)。•请用面向对象的方法来描述上述需求第二章SpringIOC什么是接口•这个一个老问题,也是个新问题,取决你的认识•抛开你以前对接口的理解,请记住一句话:考虑以下对象publicclassPerson{privateStringname;privateintage;publicvoideat(Stringfood){System.out.println(name+正在吃+food);}publicvoidsleep(){System.out.println(name+正在睡大觉);}}Person是一个普通对象,不具有任何特征考虑以下接口publicinterfaceSalesman{publicvoidsell(Stringgoods);}publicinterfaceHousework{publicvoiddoIt(Stringwork);}Salesman是一个销售人员接口,具有这个接口的类都会推销的技能Housework是一个家务人员接口,具有这个接口的类都必须会做家务publicclassPersonimplementsHousework,Salesman{privateStringname;privateintage;。。。publicvoiddoIt(Stringwork){System.out.println(name+正在做+work);}publicvoidsell(Stringgoods){System.out.println(name+正在销售+goods);}}当一个类实现了一个接口,那么它就具有了一种新的身份如果它实行了多个接口,它就具有了多重身份那么实现接口的意义是?•在商店,就(可以)把你当做销售人员用•在家,就(可以)把你当劳力用举一些实际的例子•现在person1和person2都可以胜任销售人员用,但是只有一个职位,商场可以先雇佣一个销售人员,以后遇到好的再换。SalesmanPerson1Person2商场人才市场不好的选择•如果变成商场招聘的不是一个“职位”,而是一个具体的人(可以想象商场老板任人唯亲),那么即使人才市场有更优秀的李四、王五,那么替换掉张三是很难的张三李四商场人才市场王五它们不是老板的亲戚用在实际设计中业务逻辑接口实现类A实现类BAction业务实现包但还有一点没有考虑到•由谁去筛选人才?SalesmanPerson1Person2商场人才市场商场市场部人事部SalesmanPerson2人才市场Person1Person2选拔任命•这里人事部的职责就是负责产生销售人员•再次提醒大家,不是产生具体对象,而是产生一个身份(某种职务)•在编程技术里,称人事部为:对象工厂•在Spring里,就对应着各种BeanFactory什么是IoC•IoC即控制反转,有时候也叫做DI(依赖注入)•举报纸的例子•举商场的例子考虑下列情形•是自己到报摊买报纸好•还是在邮局订阅,让人给送来好?考虑下列情形•商场的例子里,是老板亲自去选拔、任命销售人员•还是老板下一个命令,让手下的人把这件事办妥了?对于下面的例子publicclassHelloImpl4implementsHello{privateMessagemsg;publicMessagegetMsg(){returnmsg;}publicvoidsetMsg(Messagemsg){this.msg=msg;}publicStringsayHello(Stringname){returnthis.msg.getMsg()++name;}}HelloImpl4这个类需要用到Message类那么,是由HelloImpl4自己实例化Message类呢还是最好有人把Message类实例化好了,给它送过来呢实现注入的步骤•A.在配置文件中声明好要注入的类beanid=messageclass=org.yihang.spring.Messagepropertyname=msgvalue=haha/property/bean要注入的类定义B.选择注入的方式•常用的注入的方式有两种–构造方法注入–Setter方法注入对于构造注入publicclassHelloImpl4implementsHello{privateMessagemsg;publicHelloImpl4(Messagemsg){this.msg=msg;}beanid=hello4class=org.yihang.spring.HelloImpl4constructor-argindex=0ref=message//bean被注入的属性由Spring注入对于Setter方法注入publicclassHelloImpl4impleme