Spring之IOC篇

Spring是Rod Johnson提出的

Spring之所以与struts,Hibernate等单层框架不同,是因为Spring致力于提供一个统一的、高效的方式构造整个应用,并且可以将单层框架以最佳的组合揉合在一起建立一个连贯的体系。可以说Spring是一个提供了更完善开发环境的一个框架,可以为POJO(Plain Old Java Object)对象提供企业级的服务。
Spring是一个轻量级的控制反转(IoC)和面向切面(AOP)的容器框架

Spring框架的优点:
 1)Spring是分层结构,你可以选择使用你需要的层而不用管不需要的部分
        2)Spring是POJO编程,POJO编程使得可持续构建和可测试能力提高
        3)依赖注入和IoC使得JDBC操作简单化
        4)Spring是开源的免费的
        5)Spring使得对象集中简单化

Spring之IOC篇:

  1、如何使用IOC来创建Bean?
 1)配置Bean(定义bean):
  在Spring Bean Definition文件中配置Bean的相关信息:
   id(名字)
   class:要配实现类
   属性:对象类型的属性
    例:
    <bean id="userDao" class="">
    </bean>
    <bean id="userService" class="...UserServiceImp">
    </bean>

 2)ApplicationContext是Spring的核心接口.
  如何引用配置文件:ApplicationContext ac =
  new ClassPathXmlApplicationContext("base.xml");
   如果是多个配置文件,可以这样写:
  ApplicationContext ac =
 new ClassPathXmlApplicationContext(new String[]{"base.xml","order.xml",.....});

读取配置文件中的内容:
    Book book =(Book)ac.getBean("book1");

  DI(Dependency Injection--依赖注入)
  什么是依赖?对象A调用对象B,则A依赖于B
  什么是依赖注入?将对象A所依赖的对象B通过setter方式注入
 
  其实DI是IoC的别名,实现依赖注入的容器就是IoC
 2、属性的注入方式:
   有两种,我们需要掌握的是set方式的注入
   1)setter方式   属性设置器  【掌握】
  形式 —— <property name="属性名" value="值">
  注意:用“value=xxx”只限于基本类型的属性——
    String、int等

   2)构造器方式    【了解】
   Spring调用合适的构造器来创建实例
   
    <constructor-arg value="2" />能智能判断,有几个就调用几个参数的构造器
       优先处理字符串
    <constructor-arg type="int" index="0" value="2" /> 
    <constructor-arg type="java.lang.String" index="1" value="book3" />
  3、属性的数据类型
    1)基本类型
      int,string,class等等
    2)集合类型:List,Set,Map
  <list>
    <value>1234</value>(list中有几个值就写几个value)
  </list>
  
  <util:list name="versionlist">
                 里面放value的值
                </util:list>(这个要写在bean的外面,用ref="versionlist"的方式注入)
    3)对象属性--关联属性(最重要的)
       案例:BookService -- BookDAO
  
  写法:
   <bean id="bookDao"....... />
   <property name="bookDao" ref="bookDao">
  
          <ref bean=""/>的作用就是引用一个以定义好的bean
  关联属性注入的几种写法
  i、<property name="" ref="" />
  
  ii、<property name="">
         <ref bean="全局的bean--即从所有的文件中找bean"/>
     </property>  
    
    <ref local="本文件的bean" />

4、依赖检查(Dependecy check):
   问题:如何确保UserService中的userDao
   被注入了呢?
   有两种方式:
     I.在Bean定义文件中指定(xml方式):
       <bean id="" class="" dependecy-check="objects"/>
      dependecy-check的取值:
        i.none  ii.simple 基本类型(只对基本类型进行检查)
        iii.objects 只对所有的对象类型进行检查
        iv.all 对所有的属性进行检查
    II.@Required注解方式
      在需要检查的属性上加上注解
      注意两点:i.在set方法上面加注解
              ii.在bean定义文件中其中这个注解,让注解生效
               <context:annotation-config/>
   两种方式的对比:检查的范围不同
      dependecy-check对整个Bean文件进行查找
      @Required针对某个属性

5、自动注入(Autowire--自动装配)
   有两种方式:
      i.xml方式<bean .... byType"/>
       byName:按照属性名,到Bean定义文件中查找相应的对象
       byType:按照属性的类型进行查找,只能有且仅有一个匹配的bean(推荐使用)
      ii.@Autowired
      在需要检查的属性上加上注解
      注意两点:i.在set方法上面加注解
              ii.在bean定义文件中其中这个注解,让注解生效
               <context:annotation-config/>
 @Autowired使用的是byType方式,
          默认是Required的,如不需要则@Autowired(required=false)
       @Resource(name="bookDao")  
    即可用ByName的方式


6、工厂方法分为三类:
    1,静态工厂方法
    <bean id="book1" class="myspring.bean.Book"/> 这是一种构造器方式  
 例如:
 要实现 UserService service = ServiceFactory.getUserService()
 方法:如下——
  <bean id="userService" class="工厂类"
      factory-method="静态方法名" />
    2,实例工厂方法
     例:
  Connection connection = dataSource.getConnection();

  工厂Bean  如dataSource
  <bean id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource">
  <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
  <property name="url" value="jdbc:mysql://localhost:3306/hibernate"/>
  <property name="username" value="root"/>
  <property name="password" value=""/>
  </bean>
           <bean id="myConnection" factory-bean="myDataSource"
                 factory-method="getConnection">
 
    3,工厂bean(自己创建的)   【掌握】
      概念:Factory Bean是负责创建Bean的Bean,
  该Bean必须实现Spring的FactoryBean接口

 FactoryBean(Spring定义的接口):
  getObject:创建并返回Bean实例
  getObjectType:返回Bean的Class。
    例:书打折
      <bean id="discountbook1"
            class="myspring.bean.DiscountBookFactoryBean">
         <property name="bookId" value="1"/>
         <property name="bookName" value="book1"/>
         <property name="bookPrice" value="30"/>
         <property name="discount" value="0.5"></property>
      </bean>
  7、Bean的作用域——Scope【特别注意】
    学习要点:定义Bean后,在获取这个Bean时,每次获取的Bean是否相同。
    i.singleton:单例 每次获取同一个bean,生命周期和Spring一样
    ii.prototype:原型(非单例) 每次getBean()时获取的不是同一个
    <bean id="" class="" scope="prototype"/>
   对象的分类
 1、数据对象:Book、User
 2、行为对象:UserService、ServiceFactory提供具体功能的对象
    业务对象(实现订单管理等业务功能)、
    服务对象(提供某些特定服务-事务、
      数据库服务 如Hibernate的Session)
     在bean文件中定义的一般为行为对象,没有状态的,(即没有数据的)
    结论:Bean文件中定义的Bean一般为单例模式,所以Spring默认把bean当成singleton的
    如何判断该用哪种scope?
 标准:看该Bean有无状态。有状态——Prototype
  8、Bean的生命周期
  1)创建:调用构造器生成实例
  2)Setter:给属性赋值
  3)init-method:初始化回调方法(会被
      Spring自动调用) 
  4)准备就绪: 在getBean()之前
  5)destroy-method:销毁前回调方法(善后工作)
  6)JVM回收bean  
   
   例 MyFileLogger
    打开文件——init method中处理
    关闭文件——destroy method中处理
  
  两种指定方式
  1)xml方式:
   <bean id="" class="" init-method=""
     destroy-method="" /> 
     
  2)注解——@PostConstruct(“创建后”)、
    @PreDestroy(“销毁前”) 
    
    注意:用“<context:annotation-config />”
      启用注解
   9、模板装配
  先定义一个模板Bean,然后再定义bean时
  引用这个模板Bean,这样就可以使用模板
  Bean中的配置信息;也可以在bean中覆盖
  掉模板Bean中的属性等配置信息。

  <bean id="" parent="模板Bean">
  </>

  子Bean不能从模板bean继承哪些信息:
   主要为autowire、dependency-check、
   lazy-init、scope。
 10、BeanPostProcessor —— 后置处理器

   在Bean创建并初始化完毕之后,
   对Bean进行进一步的初始化处理。
   特点:它可对所有的Bean进行处理。
   
   例子:目录的预先创建
  自己定义的后置处理器要实现implements BeanPostProcessor
   
  在Spring中有一些预定义的后置处理器:
  RequiedAnnotationBeanPostProcessor
  AutowiredAnnotationBeanPostProcessor
  CommonAnnotationBeanPostProcessor当这个后置处理器起作用时,
                                                自定义的后置处理器就会失效
  
 后置处理器执行顺序 让后置处理器实现Ordered接口, PriorityOrdered优先级接口
    里面包含setOrder/getOrder
   从0开始,数字越小就越靠前。  
  
  扩展机制    增加功能
   先写一个后置处理器实现这俩BeanPostProcessor,PriorityOrdered
BeanPostProcessor是为了实现初始化之前和初始化之后的工作,记住都需要修改返回值
,默认的是返回null,都要改成返回对象bean,分别在里面进行相应的操作
PriorityOrdered是修改后置处理器的优先级,order属性的值越小,优先级越高

 
   11、如何使用属性文件:
      引入属性文件:
 <context:property-placeholder location="sys-conf.properties"/> 
   
 使用属性文件:形如 “${propName}”
  <property name="filePath" value="${fileLogger.path}" />     
12、处理多语言的步骤
 i、创建语言文件 文件名的前缀自己决定,但是都得一样,最后再来一个无后缀的文件
   message_en.properties
   message_zh.properties
   message.properties    
  
 ii、实现MessageSourceAware   
  
 iii、调用MessageSource的getMessage()
  String msg = messageSource.getMessage("fileLogger.prompt",
    new Object[]{logInfo,new Date()},
    Locale.CHINA);
 iv、在Bean定义文件中定义MessageSource:
   名字固定为"messageSource"
            <bean id="messageSource"          class="org.springframework.context.support.ResourceBundleMessageSource">
          <property name="basename" value="message"/>  
      </bean>
  13、组件扫描——Component Scanning
  自动扫描
       扫描用@Component所标记的类
      
       @Component("userDao")
       class  UserDAO{
       }
  
   Spring会“自动加入”——
    <bean id="userDao" class="" />
  
   组件component:对象
   <context:component-scan base-package=""/>
   用来启动component组件,扫描base-package包及其子包的所有类
   @Component
    @Service:如 UserService
    @Repository:代表数据库 UserDAO
    @Controller:代表前端


Spring之web篇
   1.在web.xml中添加Spring的Listener,以启动Spring。
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:base.xml</param-value>
    </context-param>

    <listener>
        <listener-class>
            org.springframework.web.context.ContextLoaderListener
        </listener-class>
    </listener>

  2.在service方法中使用:
   WebApplicationContext ac = WebApplicationContextUtils.
                getRequiredWebApplicationContext(getServletContext());
  ac.getBean("");
  接下去就根据具体的业务逻辑来码代码

猜你喜欢

转载自zhangyq-qq.iteye.com/blog/1762784