首页 > 程序开发 > 软件开发 > Java >

Spring(3)--Spring示例再演示

2017-08-02

Spring(3)--Spring示例再演示。

一:Spring 安装包介绍:
1>docs:该文件夹下存放Spring的相关文档,包含开发指南,API参考文档;
2>libs:该目录下的JAR包分为三类:
1>>Spring框架class文件的JAR包;
2>>Spring框架源文件的压缩包,文件名以-source结尾;
3>>Spring框架API文档的压缩包,文件名以-javadoc结尾;
整个Spring框架由21个模块组成,该目录下将看到Spring为每个模块都提供了三个他所包;
3>schemas:该目录下包含了Spring各种配置文件的XML Schema文档;
4>readme.txt,notice.txt,license.txt等说明性文档;
注意:Spring框架依赖于commons-logging.jar这个包,如果需要发布使用了Spring框架的JavaWeb项目,还需要将Spring框架的JAR包(21个JAR包)和commons-logging.jar添加到Web应用的WEB-INF路径下;
二:使用Spring管理Bean(第一个示例)
发现一个小问题:java引用同一个包下的类不用import,其他包下的类需要import;


package com.anlw.service;

public class Axe {
    public String chop(){
        return "使用斧头砍柴";
    }
}

package com.anlw.service;

public class Person {
    private Axe axe;
    //设值注入需要的setter方法
    public void setAxe(Axe axe) {
        this.axe = axe;
    }
    public void useAxe(){
        System.out.println("我打算去砍点柴火!");
        //调用axe的chop()方法
        //表明Person对象依赖axe对象
        System.out.println(axe.chop());
    }
}

配置XML文件(也可以使用注解,XML文件名字可以随便拟定,默认使用applicationContext.xml)



    
    
    
    
    
        
    

实际上,配置文件中的元素默认以反射方式来调用该类的无参构造器(元素的作用就是默认驱动Spring在底层调用无参构造器创建对象),所以再以设值注入的方式时,该类必须保证有无参构造(如果显式的存在有n个有参构造器,说明没有无参,必须手动的创建无参构造器);
Spring框架解析该元素后(例如),可以得到两个字符串,idStr和classStr,其中idStr的值为axe,(解析元素的id属性得到的值),classStr的值为com.anlw.service.Axe(解析元素的class属性得到的值);
也就是说,Spring底层会执行形如以下个格式的代码:


String idStr = "axe";//解析元素的id属性得到该字符串值为axe
String classStr = "com.anlw.service.Axe" //解析元素的class属性得到该字符串的值为com.anlw.service.Axe
Class clazz = Class.forName(classStr);
Object obj = clazz.newInstance();
container.put(idStr,obj);

上面代码就是最基本的反射代码,实际上Spring底层代码会更完善一些,Spring框架通过反射,根据元素的class属性指定的类名创建了一个java对象,并以元素的id属性的值为key,将该对象放入Spring容器中。这个java对象就成为了Spring容器中的bean;
通过上面的反射代码还可以得到一个结论:在Spring配置文件中配置Bean时,class属性的值必须是Bean实现类的完整类名,必须是实现类以及带包名的完整类名,不能是接口,不能是抽象类,除非有特殊配置,否则Spring无法使用反射创建该类的实例;
上面的配置文件中还包括一个子元素,该子元素通常用于作为元素的子元素,他驱动Spring在底层以反射执行一次set方法,其中的name属性值决定执行哪个setter方法,而value或ref决定执行setter方法传入的参数,是配置文件中的哪个bean(根据id指定);
>如果传入的参数是基本类型及其包装类,String等类型,则使用value属性指定传入参数;
>如果以容器中其他bean作为传入参数,则使用ref属性指定传入参数;
Spring框架只要看到子元素,Spring框架就会在底层以反射方式执行一次setter方法,何时执行这个setter方法呢?该Bean一旦创建处理,Spring框架会立即根据子元素来执行setter方法,也就是说,元素驱动Spring调用构造器创建对象,子元素驱动Spring执行setter方法,这两步是先后执行的,中间几乎没有任何间隔;




这个为例:
这个配置中,的name属性值是axe,该元素将驱动Spring以反射方式执行PersonBean的setAxe方法,ref属性值是axe,该属性指定以容器中id为axe的Bean作为执行setter方法时的传入参数;
也就是说,Spring底层会执行形如以下格式的代码:


String nameStr = "axe";//解析元素的name属性得到该字符串值为axe
String refStr = "axe";//解析元素的ref属性得到该字符串的值为axe
String setterName = "set" + nameStr.substring(0,1).toUpperCase() + nameStr.substring(1);//生成将要调用的setter方法
Object paramBean = conatiner.get("refStr");//获取Spring容器中名为refStr的bean,该bean将会作为传入参数
Method setter = clazz.getMethod(setterName, paramBean.getClass);//此处的clazz是前一段反射代码通过元素的class属性的得到的class对象
setter.invoke(obj,paramBean);//此处的obj参数是前一段代码元素创建的对象

上面的代码就是最基本的反射代码,实际上Spring底层代码会更完善一些,Spring框架通过反射根据元素的name属性决定调用哪个setter方法,并根据value或ref决定调用setter方法的传入参数;

ApplicationContext是Spring容器最常用的接口,该接口有如下两个实现类;
>ClassPathXmlApplicationContext:从类加载路径下搜索配置文件,并根据配置文件来创建Spring容器;
>FileSystemXmlApplicationContext:从文件系统的相对路径或者绝对路径下去搜索配置文件,并根据配置文件来创建Spring容器;
测试类:


package com.anlw.test;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.anlw.service.Person;

public class Test {
    public static void main(String[] args) {
        //创建Spring容器
        ApplicationContext  ctx = new ClassPathXmlApplicationContext("applicationContext-test.xml");
        //下面两个是重载方法,获取id为person的Bean
        //Person p = (Person) ctx.getBean("person");
        Person p = ctx.getBean("person", Person.class);
        //调用方法
        p.useAxe();
    }
}

Spring容器获取bean对象的主要两个方法:
>Object getBean(String id):根据容器中bean的id来获取指定bean,获取bean之后需要进行强制类型红转化;

>T getBean(String name,Class requiredType):根据容器中的bean的id来获取指定的bean,但该方法带一个泛型参数,因此获取bean之后无需进行强制类型转换;

相关文章
最新文章
热点推荐