Spring--1.Spring容器

来源:互联网 发布:asp手机考试系统源码 编辑:程序博客网 时间:2024/06/05 18:41

1.Spring优点

  • Spring的IOC降低了业务对象替换的复杂性,提高了解耦;
  • Spring的AOP支持允许将通用的任务如安全、事务、日志等进行集中式处理,提高了复用。

2.Spring管理Bean-xml

    Spring IOC核心容器理论很简单:Spring容器就是一个大工厂,所有对象都会当成对象,Spring把一切对象统称为Bean。只要是一个java类,就当成javaBean处理。

A对象需要调用B对象的方法,称之为依赖。以下是一个Person类依赖Axe对象的例子。

public class Axe{public String chop(){return "使用斧头砍柴";}}
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());}}

Spring中是怎么管理这些Bean(即对象)的呢?
答案:.xml文件
<?xml version="1.0" encoding="GBK"?><beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns="http://www.springframework.org/schema/beans"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans-4.0.xsd"><!-- 配置名为person的Bean,其实现类是org.crazyit.app.service.Person类 --><bean id="person" class="codeEETest.Person"><!-- 控制调用setAxe()方法,将容器中axe Bean作为传入参数 --><property name="axe" ref="axe"/></bean><!-- 配置名为axe的Bean,其实现类是org.crazyit.app.service.Axe类 --><bean id="axe" class="codeEETest.Axe"/><!-- 配置名为win的Bean,其实现类是javax.swing.JFrame类 --><bean id="win" class="javax.swing.JFrame"/><!-- 配置名为date的Bean,其实现类是java.util.Date类 --><bean id="date" class="java.util.Date"/></beans>
事实上,配置文件中的<bean.../>元素默认以反射的方式调用该类的无参构造器。如:
<bean id="person" class="codeEETest.Person">
Spring底层会执行如下代码:
String idStr="...";      //即将"person"传入//解析classStr="codeEETest.Person"的字符串String classStr="...";Class clz=Class.forName(ClassStr);Object obj=clz.newInstance();//container代表Spring容器container.put(idStr, obj);
以id属性的值为key,将该对象放入到Spring容器中。
结论:
在Spring配置文件中配置bean时,class属性必须为类的全限定名,不能是接口,不能是抽象类(除非有特殊配置),否则Spring无法使用反射创建该类。

对于<property.../>子元素,Spring框架以反射的方式执行一次setter方法。
<bean id="person" class="codeEETest.Person">
<!-- 控制调用setAxe()方法,将容器中axe Bean作为传入参数 -->
<property name="axe" ref="axe"/>
</bean>
说明:Spring以反射方式执行personBean的setAxe()方法
String nameStr = "...";//name属性即"axe"String refStr="...";     //ref属性"axe"String setterName = "set"+nameStr.substring(0,1).toUpperCase()+nameStr.substring(1);//获得容器中ref指向的bean,该bean作为参数传入Object paramBean = container.get(refStr);//clz是之前获得的bean字节码Method setter = clz.getMethod(setterName,paramBean.getClass());//obj是之前获得的setter.invoke(obj,paramBean);
说明:property属性详解:
  • 如果传入参数是基本数据类型或其包装类、String类型,则使用value属性指定传入的参数
  • 如果是容器中其他的bean对象,则使用ref属性指定传入的参数。
-----------------------------------------------------------------------------------------------------

3.创建Spring容器并访问bean

接下来,就可以使用Spring容器来访问容器中的Bean,ApplicationContext是Spring容器中最常用的接口。有两个实现类:
  • ClassPathXmlApplicationContext:从类加载器路径下搜索配置文件,并根据配置文件创建Spring容器。(常用)
  • FileSystemXMLApplicationContext:从文件系统...(不常用)
代码如下:
package codeEETest;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;public class BeanTest{public static void main(String[] args)throws Exception{// 创建Spring容器ApplicationContext ctx = newClassPathXmlApplicationContext("codeEETest/beans.xml");// 获取id为person的BeanPerson p = ctx.getBean("person" , Person.class);// 调用useAxe()方法p.useAxe();}}

//文件结构codeEETest----Axe.java----Person.java----BeanTest.java----bean.xml//效果我打算去砍点柴火!使用斧头砍柴

说明:Spring容器获得Bean有两种方式
  • Object getBean(String id):                                    获得bean后需要强转
  • T getBean(String name,class<T> requiredType)     类似示例的,不需转换
说明:需要springlib的21个jar包和commons-logging.jar