关闭

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

505人阅读 评论(0) 收藏 举报
分类:
一: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;

<strong><span style="font-size:18px;">package com.anlw.service;

public class Axe {
    public String chop(){
        return "使用斧头砍柴";
    }
}</span></strong>

<strong><span style="font-size:18px;">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());
    }
}</span></strong>

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

<strong><span style="font-size:18px;"><?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans.xsd">
    <!--配置名为axe的Bean,其实现类是com.anlw.service.Axe -->
    <bean id="axe" class="com.anlw.service.Axe"></bean>
    <!--配置名为person的Bean,其实现类是com.anlw.service.Person类 -->
    <bean id="person" class="com.anlw.service.Person">
    <!--控制调用setAxe()方法,将容器中的axe Bean作为传入参数  -->
        <property name="axe" ref="axe"></property>
    </bean>
</beans></span></strong>

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

<strong><span style="font-size:18px;">String idStr = "axe";//解析<bean>元素的id属性得到该字符串值为axe
String classStr = "com.anlw.service.Axe" //解析<bean>元素的class属性得到该字符串的值为com.anlw.service.Axe
Class clazz = Class.forName(classStr);
Object obj = clazz.newInstance();
container.put(idStr,obj);</span></strong>

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

<strong><span style="font-size:18px;">String nameStr = "axe";//解析<property>元素的name属性得到该字符串值为axe
String refStr = "axe";//解析<property>元素的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是前一段反射代码通过<bean>元素的class属性的得到的class对象
setter.invoke(obj,paramBean);//此处的obj参数是前一段代码<bean>元素创建的对象</span></strong>

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

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

<strong><span style="font-size:18px;">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();
    }
}</span></strong>

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

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



0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:46715次
    • 积分:657
    • 等级:
    • 排名:千里之外
    • 原创:25篇
    • 转载:0篇
    • 译文:0篇
    • 评论:6条
    文章分类
    最新评论