SpringMVC基本介绍

个人博客:www.letus179.com

对SpringMVC的了解来自实际项目以及在项目过程遇到问题时,查找相关资料,并没有系统地学习这些。很多会用,但是不太清楚具体原理,最新重新学习SpringMVC,开头一章系统的介绍,让我有所顿悟。对于这些知识的学习,让我对SpringMVC基本配置认识更加深刻,特此将重要的知识点摘录下来。

依赖注入


有两个组件A和B,A依赖于B。现在假定A是一个类,且A有方法methodA(),该方法中获取B,代码如下:

public class A {
    public void methodA() {
        B b = ...// get an instance of B
        b.methodB();
        ...
    }
    ...
}

要使用B,类A必须先获取组件B的实例引用。若B是一个具体的类,则可以通过new关键字直接创建B的实例。但是,如果B是接口,且有多个实现,则问题就复杂了。我们固然可以任意选择接口B的一个实现类,但这也意味着A的可重用性大大降低,因为无法采用B的其他实现。
依赖注入是这样处理此类情景:接管对象的创建工作,并将该对象的引用注入需要该对象的组件。对于上面的例子,依赖注入框架会分别创建对象A和对象B,并将对象B注入到对象A中
为了能让框架进行依赖注入,我们需要编写特定的setter方法构造方法
setter方法依赖注入实例

public class A {
    private B b;
    public void methodA() {
        b.methodB();
        ...
    }
    public void setB(B b) {
        this.b = b;
    }
}

修改后的类A新增了一个set方法,Spring会先创建B的实例,框架会调用该方法,并注入创建好的B的实例,因此在methodA()中调用B的methodB()方法前,不需要获取B的实例,
构造器方法依赖注入实例

public class A {
    private B b;

    public A(B b) {
        this.b = b;
    }
    public void methodA() {
        b.methodB();
        ...
    }
}

Sping会先创建B的实例,再创建A的实例,然后把B注入到实例A中。

注:Spring管理的对象称为beans。

从1.0版本开始,Spring同时支持上述两种方式依赖注入:setter方式构造器方式;从2.5版本开始,可以通过AutoWired注解,Spring支持基于field方式依赖注入。缺点是会引入org.springframework.beans.factory.annotation.Autowired,这对Spring产生了依赖,这样程序无法直接迁移到另一个依赖注入容器间。
以上是依赖注入的最后实现的两种方式。往前一点,Spring支持两种方式来支持这种依赖注入:XML配置方式注解配置方式。此外,需要创建一个ApplicationContext对象,代表一个Spring控制反转容器,org.springframework.context.ApplicationContext接口有多个实现,包括ClassPathXmlApplicationContextFileSystemXmlApplicationContext。这两个实现都需要至少包含一个beans信息的XML文件。ClassPathXmlApplicationContext尝试在类加载路径中加载配置文件,而FileSystemXmlApplicationContext从文件系统中加载。
下面为从类路径中加载config1.xmlconfig2.xml的ApplicationContext创建的一个代码示例。

ApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"config1.xml", "config2.xml"});

然后通过调用ApplicationContext的getBean方法获得对象。

Product product = context.getBean("product", Product.class);

getBean方法会查询id为product且类型为Product的bean对象。

注:理想情况下,我们仅需要在测试代码中创建一个ApplicationContext,应用程序本身无需处理。对于Spring MVC应用,可以通过一个Spring Servlet来处理ApplicationContext,而无需直接处理。

XML配置文件介绍

配置文件的根元素通常为:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:p="http://www.springframework.org/schema/p"
    xsi:schemaLocation="http://www.springframework.org/schema/beans      
    http://www.springframework.org/schema/beans/spring-beans.xsd">

    ...
</beans>

若需要更强的Spring配置能力,可以在schemaLocation属性中添加相应的schema。如:

xsi:schemaLocation="  
    http://www.springframework.org/schema/context  
    http://www.springframework.org/schema/context/spring-context.xsd  
    http://www.springframework.org/schema/beans  
    http://www.springframework.org/schema/beans/spring-beans.xsd  
    http://www.springframework.org/schema/tx  
    http://www.springframework.org/schema/tx/spring-tx.xsd  
    http://www.springframework.org/schema/jdbc  
    http://www.springframework.org/schema/jdbc/spring-jdbc-3.1.xsd  
    http://www.springframework.org/schema/cache  
    http://www.springframework.org/schema/cache/spring-cache-3.1.xsd  
    http://www.springframework.org/schema/aop  
    http://www.springframework.org/schema/aop/spring-aop.xsd  
    http://www.springframework.org/schema/util  
    http://www.springframework.org/schema/util/spring-util.xsd"

配置文件可以是一份也可以是多份,支持模块化配置。ApplicationContext的实现类支持读取多份配置文件,如上面例子中的:

ApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"config1.xml", "config2.xml"});

另一种选择是,通过一个主配置文件,将其他配置文件导入在主配置文件中,直接读取主配置文件,如:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:p="http://www.springframework.org/schema/p"
    xsi:schemaLocation="http://www.springframework.org/schema/beans      
    http://www.springframework.org/schema/beans/spring-beans.xsd">

    <import resource="config1.xml/>
    <import resource="module/config2.xml/>
    <import resource="resource/config2.xml/>
    ...
</beans>

Spring控制反转容器的使用

通过构造器创建一个bean实例

前面通过调用ApplicationContext的getBean方法来获取到一个bean的实例。下面的配置文件中定义了一个名为product的bean。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:p="http://www.springframework.org/schema/p"
    xsi:schemaLocation="http://www.springframework.org/schema/beans      
    http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean name="product" class="myspring.bean.Product"/>
</beans>

该bean的定义告诉Spring通过默认无参构造器来初始化Product类。如果不存在该构造器(若类作者重载了构造器,但是没有显示声明默认构造器),Spring将抛出异常。

注意:应采用id或者name属性标示一个bean。

为了让Spring创建一个Product实例,应将bean定义的name值“product”(具体实践中也可以是id值)和Product类型作为参数传递给ApplicationContext的getBean方法。

ApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"spring-contig.xml"});
Product product = context.getBean("product", Product.class);

通过工厂方法创建一个bean实例

Spring还支持通过调用一个工厂的方法来初始化类。下面的bean定义展示了通过工厂方法来实例化java.util.Calendar

<bean id="calendar" class="java.util.Calendar" factory-method="getInstance"/> 

该类中有方法:

public static Calendar getInstance() {
    Calendar localCalendar = createCalendar(TimeZone.getDefaultRef(), Locale.getDefault(Locale.Category.FORMAT));
    localCalendar.sharedZone = true;
    return localCalendar;
}

本例子采用了id属性,而非name属性来表示bean,采用getBean方法来获取Calendar实例。

ApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"spring-contig.xml"});
Calendar calendar = context.getBean("calendar", Calendar.class);

Destory Method 的使用

有时候我们希望在类被销毁前还做点什么,这次我们可以在bean定义中配置 destroy-method 属性,来指定在销毁前要被执行的方法。
下面的例子中,我们配置Spring通过 java.util.concurrent.Executors 的静态方法newCachedThreadPool 来创建一个 java.util.concurrent.ExecutorService 实例,并指定了 destroy-method 属性值为 shutdown 方法。这样,Spring会在销毁 ExecutorService 实例前,调用其 shutdown 方法。

<bean id="executorService" class=".util.concurrent.ExecutorService" 
    factory-method="newCachedThreadPool" destroy-method="shutdown"/>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值