• 【Java】 Spring依赖注入小试牛刀:编写第一个Spring ApplicationContext Demo


    0  Spring的依赖注入大致是这样工作的:

        将对象如何构造(ID是什么?是什么类型?给属性设置什么值?给构造函数传入什么值?)写入外部XML文件里。在调用者需要调用某个类时,不自行构造该类的对象,而是从Spring容器里拿。Spring容器会根据XML文件构造好。这样,如果需要替换类或更改对象的属性值,只需修改XML而不需要重编译,实现组件级别的低耦合,而不是类级别的低耦合。

        依赖注入是Spring的基础,DAI等许多上层模块都依赖于它。当接触到Spring JDBC的时候我们会深刻体会到它的Easy-to-use。

    1  Spring关键字:

    DI:Dependency Injection,依赖注入。依赖指的是调用关系。A调用B则A依赖于B。注入指的是A不再new B对象,而是由Spring容器来注入B对象。

    IoC:控制反转,对象不再由调用者来new,而是把new对象的任务交给Spring容器,Spring从XML中读取对象的属性值。

    AOP:面向切面变成(区别于面向对象编程OOP)。so,切面是什么?一些公共行为?

    DAI:Spring整合了针对多种数据库的访问方式(含JDBC、OXM等)

    框架融合:可以融合Hibernate和Struts框架

    解藕:为什么用了依赖注入就解藕了?

    “神说:要有光。于是就有了光”

    2  Spring下载:

    源文件:springframework-4.1.6.zip

               虽然下载到的压缩包并未以src命名,但源文件确实不包含可以直接使用的jar包,而是包含各个Spring模块的java类源代码。也许是需要将那些源代码加入到用户的项目中?活着自己编译出JAR?。方便用户修改Spring框架本身。目录中提供了import-into-eclipse.sh来引导我们将那些源代码构建城eclipse的项目,完成这一步之后才能导入到eclipse中。

               移步 https://github.com/spring-projects/spring-framework

    JAR包(RELEASE发行版):springframework-4.1.6-RELEASE

               Spring官网改版后,不再直接提供JAR的下载链接。因为Spring自此只建议用MAVEN等依赖管理工具,而不是手动地复制JAR包到用户的项目目录,然后手动地将JAR导入为LIBRARY。

               移步 repo.spring.io/libs-release-local/org/springframework/spring/ (这个站点除了由spring地发行版,还各个模块单独的RELEASE,还有许多其他资源)

    3  用Demo说明如何使用Spring

        a  对于像我这样对MAVEN不甚了解的菜鸟,最简单的办法还是把相关的JAR复制到项目里,然后添加为lib。Spring还需要commons-logging的库,否则会报ClassNotFoundException。下载,解压缩,把里面的jar包复制到项目里。

        b  该写的类写好。比如:

        

     1 package com.bean;
     2 
     3 public abstract class Person {
     4 
     5     String name;
     6     int age;
     7     
     8     public String getName() {
     9         return name;
    10     }
    11     
    12     public int getAge() {
    13         return age;
    14     }
    15     
    16     public void setAge(int age)
    17     {
    18         if(age>=0) this.age = age;
    19     }
    20     
    21     public void setName(String name)
    22     {
    23         if(name!=null) this.name=name;
    24     }
    25     
    26     public void show()
    27     {
    28         
    29     }
    30 }
     1 package com.bean;
     2 
     3 public class French extends Person{
     4 
     5     public French()
     6     {
     7     }
     8     public French(String name, int age)
     9     {
    10         setName(name);
    11         setAge(age);
    12     }
    13     
    14     public void show()
    15     {
    16         System.out.println("French - " + name + " " + age);
    17     }
    18 }
     1 package com.bean;
     2 
     3 public class Chinese extends Person{
     4 
     5     public Chinese()
     6     {
     7     }
     8     public Chinese(String name, int age)
     9     {
    10         setName(name);
    11         setAge(age);
    12     }
    13     
    14     public void show()
    15     {
    16         System.out.println("Chinese - " + name + " " + age);
    17     }
    18 }

        要写无参数的构造函数;

        要写set方法和get方法;

        要写public的set和get方法;

        当然也可以写一些其他方法,因为对象创建出来是拿来用的不是拿来保存属性值的。

        c  在src目录下面新建一个XML文件,例如appContext.xml。这个文件用于指导Spring容器构建什么样的对象。对于要用Spring容器构建对象的类,需要提供无参数的构造函数,否则报org.springframework.beans.BeanCreationException和org.springframework.beans.BeanInstantiationException等异常

        d  appContext.xml的写法:

            1 要写上xmlns,也就是XML namespace(命名空间),命名空间有唯一的URI。Java和XML都不会检查该URI是否有效,但是Spring会检查。因此要写上正确的URL。如果xmlns的URI是什么奇怪的东西而不是http://www.springframework.org/schema/beans,将报错提示找不到<beans>.

            2 也要写上xmlns:xsi属性,这个是XML的规范,同样不能写其他奇怪的东西,必须写真正的XML规范的URL。浏览器可以访问到这个URL。

            3 xmlns:aop之类的,爱写什么写什么。。。(Spring只是选择性强迫症,不检查这个)

            4 xsi:schemaLocation要写正确的路径(Spring至少会先检查这里面的URL个数是不是偶数个 = =)

            5 剩下就是告诉spring如何new对象了。

            <bean id="变量名" name="包.类">    //一定要加双引号

               <property name="属性的变量名">  //要双引号

             <value>XXX<value>                //要写正确的属性值,否则报类型错误异常

               </property>   

        </bean>

     1 <?xml version="1.0" encoding="UTF-8"?>
     2 <!-- ApplicationContext Objects Configuration -->
     3 <beans 
     4         xmlns="http://www.springframework.org/schema/beans"
     5         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
     6         
     7         xmlns:aop="what the fuck...here...a =3=oooooops!"  
     8         xmlns:tx="so what the fuck...here..tx"  
     9         
    10         xsi:schemaLocation="http://www.springframework.org/schema/beans 
    11         http://www.springframework.org/schema/beans/spring-beans-3.0.xsd 
    12         http://www.springframework.org/schema/aop 
    13         http://www.springframework.org/schema/aop/spring-aop-3.0.xsd 
    14         http://www.springframework.org/schema/tx 
    15         http://www.springframework.org/schema/tx/spring-tx-3.0.xsd"
    16         > 
    17                
    18     <bean id="chinese" class="com.bean.Chinese">
    19         <property name="name">
    20             <value>"小明"</value>
    21         </property>
    22         <property name="age">
    23             <value>10</value>
    24         </property>
    25     </bean>
    26 
    27     <bean id="french" class="com.bean.French">
    28         <property name="name">
    29             <value>"Von"</value>
    30         </property>
    31         <property name="age">
    32             <value>11</value>
    33         </property>
    34     </bean>    
    35 </beans>
    36 
    37 <!--    
    38         xmlns="http://www.springframework.org/schema/beans"
    39         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
    40         xmlns:aop="http://www.springframework.org/schema/aop"  
    41         xmlns:tx="http://www.springframework.org/schema/tx"  
    42         xsi:schemaLocation="http://www.springframework.org/schema/beans 
    43         http://www.springframework.org/schema/beans/spring-beans-2.0.xsd 
    44         http://www.springframework.org/schema/aop 
    45         http://www.springframework.org/schema/aop/spring-aop-2.0.xsd 
    46         http://www.springframework.org/schema/tx 
    47         http://www.springframework.org/schema/tx/spring-tx-2.0.xsd"
    48         > 
    49  -->

            6 写个main函数:

            使用ApplicationContext类来创建对象。这个方法是阻塞的,会等Spring搞完了再继续运行。实际上,用这一方式来创建对象相对与直接new,需要比较长的时间。ApplicationContext是个抽象类,他有三个子类,用来分别从不同的地方读取XML文件:

      ClassPathXmlApplicationContext在src目录下找

      FileSystemXmlApplicationContext从文件系统里找

      XmlWebApplicationContext去Web项目里找

            可以通过get方法得到构建好的对象的引用。这些代码都是不需要try的,前提是用户确保XML是正确的(否则代码不是抛异常这么简单,而是完全不能用)

     1 package com.bean;
     2 
     3 import org.springframework.context.*;
     4 import org.springframework.context.support.ClassPathXmlApplicationContext;
     5 
     6 public class Main {
     7 
     8     public static void main(String[] args)
     9     {
    10         Person p = null;
    11         try{
    12             @SuppressWarnings("resource")
    13             ApplicationContext context = new ClassPathXmlApplicationContext("appContext.xml");
    14             p = (Person) context.getBean("chinese");
    15             p.show();
    16             p = (French) context.getBean("french");
    17             p.show();
    18         }
    19         catch(Exception ex)
    20         {
    21             ex.printStackTrace();
    22         }
    23     }
    24 }

        第一个Spring Demo到此结束。

           7 为什么这样就解藕了?

           在传统的模式中,new什么对象是代码里说了算的。如果将类的构建挪出来,并允许在外部的XML中定义如何构建他,就可以通过修改外部的XML文件来更改程序的行为,而不需要重新编译。

           在传统的模式下,“神说,要有光”,然后神要去发明光,才会有。下一次我们想要黑色的光呢(当然没有光是黑色的),需要在“创世纪”这个程序的代码里修改new语句,在初始化阶段修改对象的属性,或者把new Light()改称new DarkLight(),但这最好保证两个类是同一个父类的多态类或来自同一个接口,并且没有不一致的其他方法。

           在Spring中,“神说要有光,于是就有了光”,光是根据XML的配置来注入给神的。下一次我们想要黑色的光了呢,改一下XML里光对象的属性值,或者,把bean的class属性由Light改成DarkLight,重新运行“创世纪”程序,光就变黑了!

    其他链接:

    依赖注入与JSR-300的参考实现-Guice

    百度百科:Guice和Spring的对比

  • 相关阅读:
    [ 黑盒测试方法 ] 错误猜测法
    [ 黑盒测试方法 ] 边界值分析法
    [ 黑盒测试方法 ] 等价类划分法
    [ Python入门教程 ] Python面向对象编程(下)
    [ Python入门教程 ] Python面向对象编程(上)
    [ Python入门教程 ] Python模块定义和使用
    [ Python入门教程 ] Python常用内置函数介绍
    [ Python入门教程 ] Python函数定义和使用
    MyBatis的缓存分析
    微机原理与接口技术总计
  • 原文地址:https://www.cnblogs.com/zhchngzng/p/4485059.html
Copyright © 2020-2023  润新知