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. “SQL Server does not exist or access denied.”

    Have resolved the problem, the Port was different and so the Connection String now reads: <connec ...

  2. 如何把前端用ajax发过来的图片传到node上,并且用node保存在oss图片服务器上?

    一:只上传一张图片 1.1:node需要安装的插件,先安好 npm install ali-oss uuid co --save A.ali-oss 用途:aliyun OSS(Object Stor ...

  3. mac上使用gitlab拉项目报错Permissions 0644 for ...

    解决办法:执行命令sudo chmod 0600 /Users/***(电脑名)/.ssh/id_rsa

  4. Oracle 11g 服务器结构

    Oracle 服务器主要又实例.数据库.程序全局区和前台进程组成. 实例可以进一步划分为系统全局区(SGA)和后台进程(PMON.SMON等)两部分,其中,SGA 使用操作系统的内存资源,而后台进程需 ...

  5. Qt 窗口相关的常用操作

    PS: 本文使用的是Qt 4.8.4版本,不同版本代码可能会有差异 设置窗口标题 setWindowTitle(QString::fromLocal8Bit("易语言")); 禁用 ...

  6. web项目中添加定时任务

    1.在web.xml中添加servlet <servlet> <servlet-name>StatisticInitServlet</servlet-name> & ...

  7. PM2 监控 Spring Boot 项目运行

    更多 PM2 的用法介绍请参考: PM2简易使用手册 - 掘金 由于 PM2 通常都用于 node 应用, 所以 exec_mode 应写为 fork, 其中最重要的是 args, -jar 和 ja ...

  8. Android笔记(五十一) 短信验证码集成——mob平台

    官方网站:www.mob.com 注册帐号,下载SDK,导入SDK就不说了,主要写一下简单集成如何使用,以后忘记了也可以翻着看看. 详细的可以参考官方文档: http://wiki.mob.com/a ...

  9. PHP标记风格,编码规范

    PHP标记风格PHP一共支持4种标记风格 <?php echo "这是XML风格的标记"; ?> 脚本风格 <script language="php& ...

  10. IDEA 使用教程(破解2019.1.1)

    2019-08-02更新 最新破解方法: ZKVVPH4MIO-eyJsaWNlbnNlSWQiOiJaS1ZWUEg0TUlPIiwibGljZW5zZWVOYW1lIjoi5o6I5p2D5Luj ...