Core模块主要的功能是实现了反向控制IOC(Inversion of Control)与依赖注入DI(Dependency Injection)、Bean配置以及加载。Core模块中有Beans、BeanFactory、BeanDefinitions、ApplicationContext等几个重要概念。

  Beans为Spring里的各种对象,一般要配置在Spring配置文件中:BeanFactory为创建Beans的Factory,Spring通过BeanFactory加载各种Beans;BeanDefinition为Bean在配置文件中的定义,一般要定义id与class:ApplicationContext代表配置文件。

  这些类都位于org.springframework.beans和org.springframework.context中。这是Spring最核心的包。Core模块依赖于Spring的Core类库。

  BeanFactory工厂

  BeanFactory是实例化、配置、管理众多Bean的容器。这些Bean类一般是离散的,但在Spring中被配置为相互依赖。BeanFactory根据配置实例化Bean对象,并设置相互的依赖性。

  BeanFactory可用接口org.springframework.beans.factory.BeanFactory表示。BeanFactory有多种实现,最常用的为org.springframework.beans.factory.xml.XmlBeanFactory。XmlBeanFactory能加载XML格式的配置文件。

  实例化BeanFactory

  在Web程序中用户不需要实例化BeanFactory,Web程序加载的时候会自动实例化BeanFactory,并加载所有的Beans,将各种Bean设置到各个Servlet中、Struts的Action中、或者Hibernate资源中。开发者直接编写Servlet、Action、Hibernate相关的代码即可,无须操作 BeanFactory。

  在Java桌面程序中,需要从BeanFactory中获取Bean,因此需要实例化BeanFactory,构造函数的参数为配置文件的路径。例如加载ClassPath下的配置文件可以用ClassPathResource加载,然后传递给XmlBeanFactory构造函数。代码如下:

ClassPathResource res = new ClassPathResource("applicationContext.xml"); // 获取配置资源
XmlBeanFactory factory = new XmlBeanFactory(res); // 获取对象工厂
IService hello = (IService)factory.getBean("service"); // 获取对象
...// 其他代码略
factory.destorySingletons(); // 销毁对象

  参数applicationContext.xml为ClassPath根目录下的文件。applicationContext.xml为Spring默认的配置文件名称,默认存储在ClassPath根目录下。或者使用文件流加载任意位置的配置文件,并传递给XmlBeanFactory构造函数,例如:

InputStream is = new FileInputStream("C:\\ApplicationContext.xml");  // 获取配置资源
XmlBeanFactory factory = new XmlBeanFactory(is); // 获取对象工厂
IService hello = (IService)factory.getBean("service"); // 获取对象

  或者用ClassPathXmlApplicationContext加载多个配置文件(多个配置文件以字符串数组形式传入),并传递给XmlBeanFactory构造函数:

ClassPathXmlApplicationContext appContext = new ClassPathXmlApplicationContext(new String[]{"applicationContext.xml", "applicationContext-part2.xml"}); // 多个配置
BeanFactory factory = (BeanFactory)appContext; // ApplicationContext继承自BeanFactory接口

  XmlBeanFactory配置格式

  一个BeanFactory中配置了多个Bean。在XmlBeanFactory中,配置文件的根节点为<beans>,里面定义了几个<bean>子节点,每个<bean>定义一个Bean。格式如下:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans> <!-- Beans根节点 -->
<bean id="..." class="..."> <!--Bean节点,定义Bean-->
...
</bean>
<bean id="..." class="..."> <!--Bean节点,定义Bean-->
<property name="..." value="..."></property> <!-- Property定义属性 -->
<property name="..." ref="..."></property> <!-- Property定义属性 -->
</bean>
</beans>

  配置Java Bean

  一个BeanDefinition定义一个Bean,在XML中对应一个<bean>标记。Spring通过<bean>配置来实例化Bean,设置Bean的属性,以及设置Bean之间相互的依赖性。

  基本配置<bean>

  一个<bean>通常需要定义id与class属性。class属性是必须的,如果有其它Bean引用了该Bean,则id属性是必须的。Bean之间通过id属性相互访问,如:

<bean id="exampleBean" class="example.ExampleBean"></bean>

  上面代码等价于

ExampleBean exampleBean = new ExampleBean();

  其中,对象名exampleBean相当于配置中的id属性。

  工厂模式factory-method

  如果一个Bean不能通过new直接实例化,而是通过工厂类的某个方法建的,可以把class设为工厂类,用factory-method指向创建对象的法:

<!-- createInstance()是静态方法 -->
<bean id="exampleBean"
class="example.MyFactoryBean"
factory-method="createInstance" /> <!-- createInstance()是非静态方法 -->
<bean id="exampleBean2"
factory-bean="myFactoryBean"
factory-method="createInstance" />

  构造函数<constructor-arg>

  如果Bean的构造函数带参数,那就需指定参数,用<constructor-arg>指定

<bean id="exampleBean" class="examples.ExampleBean"><!-- 定义Bean -->
<constructor-arg><ref bean="anotherExampleBean" /></constructor-arg><!-- 构造函数参数 -->
<constructor-arg><ref bean="yetAnotherBean" /></constructor-arg><!-- 构造函数参数 -->
<constructor-arg><value>1</value></constructor-arg><!-- 构造函数参数 -->
</bean>

  每个<constructor-arg>的参数的顺序要与构造函数相同。

public class ExampleBean {
private AnotherBean beanOne;
private YetAnotherBean beanTwo;
private int i;
public ExampleBean(AnotherBean beanOne, YetAnotherBean beanTwo, int i){
this.beanOne = beanOne;
this.beanTwo = beanTwo;
this.i = i;
}
}

  单态模式singleton

  Bean可以定义为单态模式(Singleton)。即在程序中只有一个实例,像数据源等一般设为单例。Spring默认是单态模式,如果想使用非单例模式(称为Prototype模式),需把singleton属性置为false:

<bean id="exampleBean" class="examples.ExampleBean" singleton="false" />

  非单例下,每次请求该Bean,都会生成一个新的对象。

  配置属性<property>

  Spring通过Bean的setter方法设置属性。因此,需要由Spring注射的属性一般都具有公共的setter,getter方法。例如下面的配置代码:

<bean id="dataSource"
class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url"
value="jdbc:mysql://localhost:3306/spring?characterEncoding=UTF-8" />
<property name="username" value="root" />
<property name="password" value="admin" />
</bean>

  destroy-method属性配置关闭方法。在销毁对象时会调用该方法。

  注意:

<!-- 将password设为空字符串 -->
<property name="password"><value></value></property>
<!-- 将password设为null,也可以不设置 -->
<property name="password"><null /></property>

  设置对象属性<ref>

  使用ref标签配置Bean的id属性使用。如:

<bean id="dao" class="com.helloweenvsfei.forum.dao.impl.DaoImpl">
<property name="sessionFactory" ref="sessionFactory"></property>
</bean>
<bean class="com.helloweenvsfei.forum.service.impl.ThreadServiceImpl">
<property name="dao" ref="dao"></property>
</bean>

  ref的内容为引用的Bean的id属性。

  也可使用内部配置(或者内联配置),类似于JAVA中的匿名类对象。因为内部配置一般不会被其他的Bean引用,因此不需要配置内部Bean的id。例如:

<property name="dao">
<bean class="example.DaoImpl"></bean>
</property>

  除了使用<ref>的bean属性,还可以使用local、parent,它们与bean属性的作用是一样的。不同的是,local只能使用本配置文件中的bean,而parent只能使用父配置文件中的bean,但bean则没有任何限制。

  配置List属性<list>

  <list>配置java.util.List类型的属性。list属性中可配置任意类型对象,如果为java对象,使用ref指定,或者<bean>定义新实例,如果是普通类型如String,int,double等,直接用字符串即可。<list>中的元素会按配置的先后顺序排序,例如:

<property name="someList">
<list>
<value>String,Integer,Double,Boolean等类型对象</value>
<ref bean="myDataSource" />
</list>
</property>

  配置Set属性<set>

  <set>配置java.util.Set类型的属性。Set属性中可配置任意类型对象。如果为java对象,则使用<ref>指定,或者使用<bean>重新定义新实例。如果是普通类型如String,int,double等,直接用字符串即可。例如:

<property name="someSet">
<set>
<value>String,Integer,Double,Boolean等类型对象</value>
<ref bean="myDataSource" />
<set>
</property>

  配置Map属性<map>

  <map>配置java.util.Map类型的属性。<entry>配置Map里的元素,key指定索引,value指定值。如果为java对象,则使用ref指定,或者使用<bean>重新定义新实例,如果key为对象,,使用key-ref属性,例如:

<property name="someMap">
<map>
<entry key="yup an entry">
<value>just some string</value>
</entry>
<entry key-ref="myDataSource">
<ref bean="serviceImpl" />
</entry>
</map>
</property>

  配置Properties属性<props>

  使用<props>与<prop>配置Properties属性。<props/>配置一个Properties对象,<prop/>配置一条属性,属性key配置索引,例如:

<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.format_sql">false</prop>
<prop key="hibernate.hbm2ddl.auto">create</prop>
</props>

  <idref>与<ref>的区别

  <idref>与<ref>的作用是一样的,都是配置java对象的。<idref>的用法也与<ref>基本相同。不同的是,<idref>只有bean与local属性,没有parent属性,如

<idref local="dataSource" />

  Spring加载XML配置文件时,会检查<idref>配置的Bean存在不存在。而<ref>只会在第一次调用时才会检查。换句话说,如果Bean不存在,<idref>能在启动程序的时候就抛出错误,而<ref>只会在运行中抛出错误。

  设置destory-method销毁方法

  有的对象(例如数据源,JDBC连接,输入输出流等)在使用完毕后需要执行close()方法释放资源。可以使用destory-method配置。Spring在注销这些资源时会调用destory-method里配置的方法。例如:

<bean id="dataSource"
class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
.....
</bean>

  设置depends-on依赖对象

  Spring默认按照配置文件里Bean配置的先后顺序实例化Bean,但有时候在实例化A对象之前需要先实例化后面的B对象。这时候可以使用depends-on,强制先实例化B对象。如:

<bean id="a" class="examples.A" depends-on="b"></bean>
<bean id="b" class="examples.B"></bean>

  在实例化A的时候会检查B的实例是否存在,如果不存在,先实例化B

  初始化方法init-method

  与destory-method相反,有的对象在实例化后需要执行某些初始化代码,但这些初始化代码不能写在构造函数中。这时候可以把这部分初始化代码写在一个方法中,如init(),使用init-method属性,强制Spring执行该方法进行初始化,如:

<bean id="c" class="example.C" init-method="init"></bean>

  属性自动装配autowire

  为了防止配置文件过大,可以使用autowire属性

  配置autowire自动装配

  使用<bean>的autowire属性后,不需要再用<property name="" value="" />显示地设置该Bean的属性、依赖关系。Spring会根据反射,自动寻找符合条件的属性,设置到该Bean属性上。如果autowire设置为byType,将会按照属性的类型自动匹配。如:

<bean id="d" class="examples.D" autowire="byType"></bean>

  autowire取值范围

autowire属性定义的不是需要自动装配的属性名,而是自动装配的规则。一但配置,所有的属性都将遵循autowire定义的规则。autowire所有的取值以及意义见下表

  如果显示定义了<property>或者<constructor-arg>,会覆盖默认装配。自动装配一般与下面的依赖检查连用。

  注意:在大型项目中不推荐使用,因为自动装配会隐藏依赖装配的细节。降低可读性与可维护性,并可能带来意想不到的麻烦。

  依赖检查dependency

  有时候某些Bean的属性配置有错误,比如某个属性没有设置。这种错误在程序启动的时候不会有任何异常表现,会一直潜伏到Spring调用该Bean时才会被发现。为了防止这种情况,Spring提供依赖检查,在程序启动的时候检查依赖配置。如果有错误,启动时就会抛出异常,以便发现配置错误。

  配置dependency依赖检查

  依赖检查能够检查属性是否被设置。如果配置了依赖检查,程序启动时会进行配置校验,以便及时地发现配置错误。通过设置<bean>的dependency-check设置依赖检查规则,如:

<bean id="bean" class="examples.Bean" dependency-check="all"></bean>

  dependency属性取值范围

  dependency属性有多种取值,分别应对不同的情况。但是需要注意,dependency依赖检查是很生硬的,例如设置为object,将会检查所有的java对象属性,只要有一个属性没有设置,就会抛出异常,即某属性明明不需要设置,但是没法避免dependency检查,容易造成“一竿子全打死”的现象。dependency的取值以及意义见表

  Bean的高级特性

  Spring程序中,JAVA Bean一般与Spring是非耦合的,不会依赖于Spring类库。这也是Spring的优点。但有时候Java Bean需要知道自己在Spring框架中的一些属性。Spring提供了一些接口,实例化Java Bean对象后Spring会调用接口的方法。

  BeanNameAware接口获取Bean的id

  BeanNameAware接口帮助Java Bean知道自己在配置文件中的id,实现BeanNameAware,实现方法名为setBeanName()方法,初始化该对象后Spring就会执行该回调方法,将id设置进来。Bean中设置一个变量,接受id名称即可,例如:

package com.helloweenvsfei.spring.example;

import org.springframework.beans.factory.BeanNameAware;

public class WhatsTheNameBean implements BeanNameAware {

    private String beanName;

    public void setBeanName(String beanName) {
this.beanName = beanName;
} }

  提示:setBeanName()方法的回调发生在所有参数被设置完之后,初始化方法(init-method属性)被执行之前。

  BeanFactoryAware接口获取BeanFactory

  BeanFactoryAware接口帮助java Bean知道哪个BeanFactory实例化了自己,BeanFactoryAware接口中有setBeanFactory的回调方法,初始化该对象后,会回调该方法,将BeanFactory传递进来。BeanFactoryAware接口的代码如下:

public interface BeanFactoryAware{
void setBeanFactory(BeanFactory beanFactory) throws BeanException
}

  用法同BeanNameAware,实现了BeanFactoryAware接口的Java Bean能够获取到BeanFactory,从BeanFactory中能够获取到BeanFactory中配置的其他Java Bean。Spring不推荐这样做,因为这样会与Spring耦合。获取其它Java Bean一般通过设置getter、setter方法,用依赖注入实现

  InitializingBean接口执行初始化方法

  实现了InitializingBean接口的Java Bean会在实例后、所有属性被设置后调用初始化方法。但使用该接口会与Spring代码发生耦合,因此不推荐使用。InitializingBean接口代码如下:

public interface InitializingBean{
public void afterPropertiesSet();
}

  Spring推荐使用init-method配置,效果等价:

<bean id="d" class="examples.D" init-method="afterPropertiesSet"></bean>

  DisposableBean接口执行销毁方法

  实现了DisposableBean接口的Java Bean会在对象丢弃的时候调用销毁方法。但使用该接口会与Spring代码发生耦合,因此不推荐使用。DisposableBean接口代码如下:

public interface DisposableBean{
void destory() throws Exception;
}

  Spring推荐使用destory-method配置,效果等价:

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destory-method="close"></bean>

  BeanFactory高级特性

  如果Java Bean实现了BeanFactoryAware接口,就能够获得BeanFactory对象。BeanFactory有下面几个常用的方法:

  属性覆盖器

  对于一些参数,更实用更简单的方法是使用properties配置,而不是配置在Spring的配置文件中。Spring提供属性替代配置,允许把某些属性配置在properties文件中。

  配置PropertyOverrideConfigurer属性覆盖器

  PropertyOverrideConfigurer允许把XML配置里的某些参数配置到properties文件中。这在数据库配置中很常见。配置时需要配置一个PropertyOverrideConfigurer对象,指定properties文件的位置,然后把替换的属性用形如${jdbc.url}的字符串替代,如:

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${jdbc.driverClassName}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</bean> <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="classpath:jdbc.properties" />
</bean>

  PropertyOverrideConfigurer对象会到指定名称的properties文件(例如jdbc.properties)中,寻找属性名为变量的配置,变量的配置,{}中最好不要有空格

  properties配置

  具体的数据库配置是写在jdbc.properties里面的。properties中的配置比applicationContext.xml中更便于阅读、修改与维护。代码如下:

jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/forum?characterEncoding=UTF-8
jdbc.username=root
jdbc.password="admin

Spring的Core模块的更多相关文章

  1. Spring之Core模块

    Core模块主要的功能是实现了控制反转与依赖注入.Bean配置以及加载.Core模块中有Beans.BeanFactory.BeanDefinitions.ApplicationContext等概念 ...

  2. Spring第二篇【Core模块之快速入门、bean创建细节、创建对象】

    前言 上篇Spring博文主要引出了为啥我们需要使用Spring框架,以及大致了解了Spring是分为六大模块的-.本博文主要讲解Spring的core模块! 搭建配置环境 引入jar包 本博文主要是 ...

  3. Spring【AOP模块】就是这么简单

    前言 到目前为止,已经简单学习了Spring的Core模块.....于是我们就开启了Spring的AOP模块了...在讲解AOP模块之前,首先我们来讲解一下cglib代理.以及怎么手动实现AOP编程 ...

  4. 移动商城第三篇【搭建Mybatis和Spring环境、编写Dao、Service在Core模块】

    Mybatis和Spring环境搭建 由于我们的所编写的dao层.service代码可能前台和后台都需要用到的,因此我们把环境搭建在core模块中 逆向工程 首先,我们要做的就是品牌管理,我们首先来看 ...

  5. Spring第三篇【Core模块之对象依赖】

    前言 在Spring的第二篇中主要讲解了Spring Core模块的使用IOC容器创建对象的问题,Spring Core模块主要是解决对象的创建和对象之间的依赖关系,因此本博文主要讲解如何使用IOC容 ...

  6. Spring第七篇【Spring的JDBC模块】

    前言 上一篇Spring博文主要讲解了如何使用Spring来实现AOP编程,本博文主要讲解Spring的对JDBC的支持- 对于JDBC而言,我们肯定不会陌生,我们在初学的时候肯定写过非常非常多的JD ...

  7. Spring【DAO模块】就是这么简单

    前言 上一篇Spring博文主要讲解了如何使用Spring来实现AOP编程,本博文主要讲解Spring的DAO模块对JDBC的支持,以及Spring对事务的控制... 对于JDBC而言,我们肯定不会陌 ...

  8. Spring之DAO模块

    Spring的DAO模块提供了对JDBC.Hibernate.JDO等DAO层支持 DAO模块依赖于commons-pool.jar.commons-collections.jar Spring完全抛 ...

  9. [02] Spring主要功能模块概述

    1.Spring主要功能模块   1.1 Core Container Spring的核心容器模块,其中包括: Beans Core Context SpEL Beans和Core模块,是框架的基础部 ...

随机推荐

  1. django-nginx与uwsgi项目部署

    uwsgi是提供动态服务的 nginx反向代理 在项目中创建一个settings.py的副本.我这里重命名为copy_settings.py,将配置文件中的DEBUG=False 修改项目下wsgi. ...

  2. jq + 面向对象实现拼图游戏

    jq + 面向对象实现拼图游戏 知识点 拖拽事件 es6面向对象 jquery事件 效果图 html: <div class="wraper"> <div cla ...

  3. JavaScript之运算符

    (1)赋值运算符 // c+=1; // 相当于c=c+1; // console.log(a++); // 先将a的值赋值给表达式,a再加1 // console.log(++a); // a先加1 ...

  4. idea 控制台允许输入

    打开idea配置文件添加 -Deditable.java.test.console=true

  5. 内存域水印值:min_free_kbytes

    1.内存域水印值:需要为关键性分配保留的内存空间的最小值:该值保存在全局变量min_free_kbytes中 2.内存域水印值的计算由函数init_per_zone_pages_min完成: /* * ...

  6. python(For/while循环语句)

    一.循环语句 1.while循环 当我们在python中需要重复执行一些动作的时候,这时我们就要用到循环 while循环的结构,当条件成立的时候,就会执行里面的代码 while循环不断的运行,直到指定 ...

  7. angularcli 第四篇(执行事件)

    目录: 1.按下按钮执行事件 2.按下键盘回车“Enter”执行事件 1.按下按钮执行事件:<button  (click) = 'setName()'>......</button ...

  8. 批处理引擎MapReduce应用案例

    批处理引擎MapReduce应用案例 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. MapReduce能够解决的问题有一个共同特点:任务可以被分解为多个子问题,且这些子问题相对独立 ...

  9. 2013.5.21 - KDD第三十三天

    实验室例会,上到一半之后发现今天下午第二节课是Android,上次两节Android都没跟中秋碰头,这次又不能碰头了,然 后就赶紧给中秋发了个短信,说我在开会,晚上约个时间再谈.正好也称这一下午加一晚 ...

  10. Ffmpeg常用转码命令

    H264视频转ts视频流 ffmpeg -i test.h264 -vcodec copy -f mpegts test.ts H264视频转mp4 ffmpeg -i test.h264 -vcod ...