Spring

Spring 设计是很好的,但Spring用起来是极为简单的。


---工厂模式---


23种设计模式之一。
简单工厂  不是23设计模式之一。
工厂方法  才是
抽象工厂  也是。






Spring的作者研究发现:
Java项目中,对象与对象经常形成调用栈。
A对象,调用B对象的方法,此时就成为 A 依赖 B。


对于初级编程来说,当A依赖B时,程序总是先创建B对象,再去调用B对象的方法。


这种做种的问题在于:
当被依赖的对象升级时,依赖于该对象的所有对象都需要修改、升级!


为了解决该问题,提出了工厂模式:
(1) 面向接口编程。
(2) 引入一个工厂类,它负责产生被依赖对象。
(3) 依赖对象调用工厂类的方法来获取被依赖对象,
      这样就把依赖对象与被依赖对象的实现类分离了,


好处就是:
当被依赖的对象升级之后,依赖于该对象的所有对象都无需修改,只要修改工厂类即可。


工厂模式的坏处是什么?


虽然改得少了,但是工厂类还是需要修改!


Spring框架的核心:


1. Martine Fowler :DI(IoC:控制反转:Johnson)
2. AOP
3. Spring与ORM框架、MVC框架的整合。


Spring的用法更简单,因为它不仅可以在Web应用中使用,也可以在Java SE项目使用。


Spring的安装只要一步:复制JAR包。


Spring框架的用法:
1. 写一个Java类。(任意的Java类)。
2. 在Spring的配置文件中配置它。




为了获得Spring所创建的对象,也需要两步:
1. 创建Spring容器。 ApplicationContext代表,在Java SE项目中,有两个最常用实现类:
    FileSystemXmlApplicationContext , ClassPathXmlApplicationContext
2. 调用Spring容器的getBean()方法。


用Spring与不用Spring的区别:
如果不用Spring,也不用工厂模式,所有对象都是通过new 来创建的。
用Spring之后,对象交给Spring去创建、管理,应用程序只要调用Spring容器的getBean()


IoC名词
不用IoC以前,程序自己去调用setter方法来获得被依赖的对象。
现在程序不调用了,而是让Spring框架以反射的方式去调用setter方法。


********************************
IoC容器就是工厂模式的演化,


所以Spring也需要面向接口编程,这样才能维持较好的可扩展性。


Spring:通过XML代码来控制执行Java代码。
********************************


依赖注入/控制反转


    原来是由程序自己调用setter方法,为属性设置值。
    用Spring之后,只要在spring文件中配置即可,由Spring负责为属性设置值。


设值注入:通过<property .../>元素来控制调用setter方法,由setter方法为属性注入值,
          这就是设值注入。
构造注入:通过<constructor-arg .../>元素来控制调用有参数的构造器,由构造器方法为属性注入值,
          这就是构造注入。

 

Spring容器中的Bean—— 所有的Java实例都可以是Bean!任何Java实例都可以。

 

 

Spring框架:用XML配置去驱动Java代码。


IoC/DI - 设值注入与构造注入。


bean - 调用构造器。
constructor-arg,设置构造参数。
property : 调用setter方法。


Spring的开发:
A。 写Java类。
B。 配置Java类。




Spring容器Bean的作用域:


通过bean元素的scope属性(默认为singleton)来指定:
-singleton  - 保证Spring容器只会产生一个该Bean的实例。
-prototype  - 相当于new
-request   - Web应用才有效。同一次请求,Bean实例只有一个。
-session   - Web应用才有效。同一次session,Bean实例只有一个。
-global session


对象的产生、销毁需要较大的系统开销,
经常地创建对象、销毁对象,必然造成系统性能的降低。
一般将scope设置singleton能保证较好的性能。


---调用setter方法---
   <property .../>控制调用setter方法。
   
   setter方法的形参类型
    - 如果标量类型,为<property.../>指定value属性即可。


    - 如果自定义类
            A. 可为<property.../>指定ref属性,引用容器中已有的Bean。
            B. 为 <property.../>指定嵌套Bean。
   
    - Set/List/Map/Properties/数组
         set/list/map/props/list子元素来配置参数值。


自动装配
   autowire属性(默认是no)指定:
   -no
   -byName  ,根据setter方法的名字来查找。
   -byType
   -constructor
   -autodetect
    


创建Bean实例的方式:


 1. 调用构造器来创建。
    每个bean元素控制调用一次构造器。
 
 2. 调用静态工厂方法来创建。
    需要在<bean.../>元素增加factory-method属性。
    如果工厂方法需要参数,用<constructor-arg.../>元素传入。


 3. 调用实例工厂方法来创建。
    需要在<bean.../>元素增加factory-method属性,不需要class属性,需要使用factory-bean属性。
    如果工厂方法需要参数,用<constructor-arg.../>元素传入。




抽象Bean和Bean继承
(Spring每升级一次,配置文件就可以简化一次)  




在有些情况,配置文件中有一批Bean,它们的某些配置是相同的。
此时就可以把这些相同的配置,抽取成“配置模板”,此时“配置模板”并不需要创建实例
为了控制Spring框架不创建实例,可以将它配置抽象Bean
所谓“抽象Bean”,其实就是“Bean模板”

Spring框架的本质:以XML配置来驱动执行Java代码。


你们现在会的:
1. 创建对象。
   用无参数的构造器来创建。
   用有参数的构造器来创建——增加<constructor-arg.../>
   用工厂方法俩创建。
2. 调用setter方法。




工厂Bean(特殊的API)
   静态工厂方法创建Bean/实例工厂方法创建Bean——都需要配置一个factory-method属性。


   BeanFactory(ApplicationContext) 与  FactoryBean(工厂Bean)


   当程序去获取工厂Bean时,实际上Spring返回的工厂Bean的getObject方法的返回值。




容器中Bean的生命周期
********************************************************************
什么时候初始化Bean实例?


如果使用BeanFactory作为Spring容器,容器初始化时不会初始化任何实例。
如果使用ApplicationContext作为Spring容器,容器初始化时会初始化所有singleton Bean的实例。




什么时候调用Bean的setter方法?
Bean实例一旦被创建,立即就会根据配置文件中property元素来调用她的setter方法
********************************************************************




当Singleton Bean依赖于非Singleton Bean时,
singleton Bean会把非singleton Bean变成单例行为。


为了解决这个问题,解决思路为:
(1)放弃依赖注入。
     程序每次都主动去获取prototype Bean
     ——坏处是:每次都要先获取Spring容器,在调用容器的getBean方法。
(2)lookup注入。
     <lookup-method.../>元素来控制, 该元素告诉Spring要重写某个方法。
      重写的方法由name属性指定。


CGLIB - Code Generator lib 




Spring本质:通过XML配置去驱动调用Java代码。


1. 创建对象。
2. 调用setter方法。
3. 调用getter方法?  PropertyPathFactoryBean (哪个对象,哪个getter方法)
4. 访问Field值?  FieldRetrievingFactoryBean (哪个对象/哪个类,哪个field)
5. 调用普通方法? MethodInvokingFactoryBean(哪个对象/哪个类,哪个方法,传入参数)


SpEL —— 进一步简化IoC容器的配置。

AOP 


一个问题:
项目开发完成了,系统可能有1000个组件,每个组件包含10个方法...


客户端突然要求:权限控制——
   先定义一个方法:auth()


客户端又突然要求:加日志——
   先定义一个方法:log()




最后的解决方法就是:AOP,所谓AOP就是对原来的类,进行修改、增强。


第一种:在编译时就修改、增强:AspectJ
第二种:在运行时通过JDK动态代理,CGLIB这种动态地修改、增强:Spring AOP。


************************************************
编译型的语言?解释型语言?谁的速度快?
语言 → 翻译 → 机器指令。
源代码代码写好 → 编译 →  二进制的机器码。 直接执行二进制的机器码(编译型语言)
源代码代码写好 → 解释执行(编译 + 运行)。
************************************************


用合适的语法,提供足够的信息,驱使计算机为我们干活。




AspectJ更优秀~
     性能更好,而且更符合AOP规范。
     它的AOP关键:ajc命令,它在编译时进行增强——对目标类进行修改。




Spring AOP
     依赖XML配置文件,然后用CGLIB在运行时进行增强——生成目标类的子类。


    --AOP概念--
    AOP:  面向切面编程。
    Aspect - 切面。
    Pointcut - 切入点。 
    Advice - 增强处理 / 通知(建议) 
    AOP代理 - AOP框架所生成新的类的实例。
    目标对象 - 未增强的类的对象。
    织入


对于AOP的使用者来说,只要指定2个信息:
- 在哪里切入
- 切入的增强处理是什么?
一旦指定了这两个信息,AOP框架会帮我们完成实际的织入。


AOP


  AOP作用——不要加班。


  当应用程序需要进行一种“具有横切性质的”修改,
   这种修改又跨多个方法,需要改动的地方很多。  




一旦有了AOP框架,对于开发人员来讲,要干什么?


1. 在哪个“切面”插入增强处理。
2. 插入怎样的“增强处理”。


一旦开发人员提供了这两个信息,剩下事情交给AOP框架去完成。


Before Advice(前置增强处理)
After Advice(后置增强处理)
    1. 只要目标方法结束(不管A。成功返回;B。遇到异常),都会织入。
    2. 它也不能访问目标方法的返回值。
    3. 它不能阻止目标方法的执行。
   类似finally关键字:回收物理资源。
AfterReturning Advice(方法成功返回后的增强处理)
    1. 它不能阻止目标方法的执行。
    2. 它可以访问目标方法的返回值,它不能改变目标方法的返回值。
    3. 只有在目标方法成功返回后,它才会织入。
AfterThrowing Advice(对异常的增强处理)
    1. 它不能阻止目标方法的执行。
    2. 可以访问目标方法所抛出的异常。
   类似catch关键字:对未处理的异常进行修复。但异常依然会传播出去。
Around Advice(前、后增强处理)
    1. 它可以阻止目标方法的执行。
    2. 它可以访问目标方法的形参,甚至改变目标方法的形参。
    3. 它可以访问目标方法的返回值,甚至改变目标方法的返回值。


所有增强处理都可以访问目标方法的参数。


 1. 用args指示符。也可以对所匹配的目标方法的形参进行限制
 2. 在增强处理方法增加一个形参:


<aop:pointcut.../>元素,用于配置一个切入点。
本质:就是给切入点表达式起个名字,方便以后复用。、


and / or  / not


Spring 与前端框架的整合。


前端框架:Struts 1 / DWR  / Struts 2


Struts 1
               + Spring + Hibernate
DWR




Spring 本质:你用XML配置(Annotation)驱动Java代码。


所以,Spring框架与前端框架的整合的关键:


如何将Spring容器中的Service组件,注入前端组件。


ApplicationContext 与 BeanFactory


ApplicationContext 比 BeanFactory多一些功能:
        可以声明式的方式创建Spring容器。
实现思路:
  1. 创建ServletContextListener
  2. Web应用启动时,回调 监听器的contextInitial()方法,就可在该方法里
     调用new XxxApplicationContext("dddd") →  Spring 容器
     接着把Spring容器放到 application (ServletContext)里。




Spring 与Struts 1整合的步骤:
(1) 复制Spring ,Struts 的JAR包。
(2) 在web.xml文件中配置加载Spring容器。 提供Spring配置文件。
(3) 在web.xml文件中配置Struts 1的核心控制器,提供struts-config.xml文件。
(4) 在struts.xml文件,增加controller元素,该元素用于替换Struts 1的
       RequestProcessor
(5) 在struts.xml文件中配置action元素时,无需指定type属性。
      主要让该action的path属与Spring容器中某个Bean的name属性相同即可。


Spring 与DWR整合的步骤:
(1) 复制Spring ,DWR的JAR包。
(2) 在web.xml文件中配置加载Spring容器。 提供Spring配置文件。
(3) 在web.xml文件中配置DWR的核心控制器,提供struts-config.xml文件。
(4) 在dwr.xml文件, 使用spring创建器。






Spring与Hibernate的整合


Hibernate的开发步骤:
(1) 编写POJO
(2) 映射文件。
(3) 使用Hibernate API进行持久化操作。
      A。 得到Configuration
      B。 得到SessionFactory
      C。 得到Session
      D。打开事务。
         持久化操作。
      E。关闭事务。
      F。关闭session
      G。如果应用退出,关闭sessionFactory。


Spring对Hibernate进行了简化:


  1. 可以直接在配置文件配置SessionFactory,
      Spring容器将负责创建 SessionFactory。
      Spring容器还可以把SessionFactory注入应用组件中。
  2. Spring提供了一个HibernateTemplate。
      HibernateTemplate只要给它一个SessionFactory,
      接下来的绝对部分crud操作只要一行代码即可。
  3. Spring还提供了一个HibernateDaoSupport工具类——会作为DAO组件的基类。
      该工具类主要有两个方法:
      setSessionFactory() —— 可用于接受依赖注入,注入SessionFactory
      getHibernateTemplate() —— 可进行持久化操作。


Spring提供了声明式的事务管理的配置
(1)配置事务管理器。
(2)使用AOP配置
  

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值