Spring 应用扩展

1. 多种方式配置数据源

1.1 properties 文件方式

  Spring 支持从属性文件中获取信息来进行数据源配置。使用 Spring 提供的 PropertyPlaceHolderConfigurer 类可以加载属性文件。在Spring 配置文件中采用 ${…} 的方式引用属性文件中的键值对。如下示例:

<!--引入properties文件-->
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="location" value="classpath:database.properties"/>
</bean>

<!--配置 DataSource-->
<bean id="dataSource2" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
    <property name="driverClassName" value="${driver}"/>
    <property name="url" value="${url}"/>
    <property name="username" value="${username}"/>
    <property name="password" value="${password}"/>
</bean>
</beans>

database.properties属性文件中的内容:

driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/smbms?useUnicode=true&characterEncoding=UTF-8
username=root
password=121127

1.2 Spring 对 JNDI 数据源的支持

  Spring 提供了专门引用 JNDI 资源的 JndiObjectFactory Bean类,以便开发者能够通过 JNDI 方式使用应用服务器(Tomcat、WebLogic等)本身提供的数据源。
 使用 JNDI 的方式配置数据源,前提是必须在应用服务器上配置好数据源。以Tomcat为例,配置数据源需要把数据库驱动文件放到 Tomcat 的lib目录下,并修改 Tomcat 的conf 目录下的context.xml 文件,配置数据源代码如下所示:

<Context>
<Resource  name="jdbc/news"
         auth="Container" 
         type="javax.sql.DataSource"
         maxActive="100" 
         maxIdle="30" 
         maxWait="10000"
         username="root" 
         password="121127"
         driverClassName="com.mysql.jdbc.Driver"
         url="jdbc:mysql://locathost:3306/kgcnews?characterEncoding=utf-8"/>
</Context>

<Resource>标签的 name 属性指定了数据源的名称,要与Spring 配置文件中的jndiName 值java:comp/env/ 后的名称保持一致。Spring 配置文件内容如下所示:

 <!--通过 JNDI 配置 DataSource-->
    <bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
    <!--通过 jndiName 指定引用的JNDI数据源名称-->
     <property name="jndiName" value="java:comp/env/jdbc/smbms" />
    </bean>

2. 深入理解和配置 Bean 的作用域

2.1 Spring 中的 Bean 的 5 个作用域
  在 Spring 中定义Bean,除了可以创建 Bean 实例并对 Bean 的属性进行注入外,还可以为定义的Bean 指定一个作用域。这个作用域的取值决定了 Spring 创建该组件实例的策略,进而影响程序的运行效率和数据安全。在Spring2.0 版本以及之后的版本中,Bean的作用域被分为如下5种:

作用域说明
singleton默认值。一单例模式创建Bean的实例,即容器中该Bean的实例只有一个
prototype每次从容器中获取Bean时,都会创建一个新的实例
request用于Web应用环境,针对每次HTTP请求都会创建 一个实例
session用于Web应用环境,同一个会话共享同一个实例,不同的会话使用不同的实例
globe session仅在Portlet的Web应用中使用,同一个全局会话共享一个实例。对于非Protlet 环境,等同于 session

  single 是默认的作用域, 即默认情况下 Spring 为每个Bean 仅创建一个实例。对于不存在线程安全问题的组件,采用这种方式可以大大减少创建对象的开销,提高运行效率。而对于存在线程安全问题的组件,可以使用 prototype 作用域,设置 scope 属性。

示例如下:

<!--指定 Bean 的作用域为 prototype-->
<bean id="..." class="..." scope="prototype">
...
</bean>

  Spring 在每次获取该组件时,都会创建一个新的实例,避免因为共用同一个实例而产生线程问题。

2.2 使用注解指定 Bean 的作用域

  对于使用注解声明的 Bean 组件,如需修改其作用域,可以使用 @Scop 注解实现。

3.基于XML 配置 Spring 的自动装配

  基于 XML 配置的 Spring 自动装配代码示例如下:

 <!--配置 DAO , 根据属性名称自动装配-->
    <bean id="userMapper" class="dao.impl.UserMapperImpl" 
          autowire="byName"/>
    
    <!--配置 service,根据属性明自动装配-->
    <bean id="userService" class="service.impl.UserServiceImpl"
          autowire="byName"/>

  上述示例中通过 <bean> 元素的 autowire 属性指定自动装配,代替了通过<property> 标签显示指定 Bean 的依赖关系。有 BeanFactory 检查 XML 配置文件的内容,为Bean 自动注入依赖关系,大大简化了维护 Bean 注入的配置。
   Spring 提供了多种自动装配方式, autowire 属性常用的取值如下:

autowire属性值说明
no不使用自动装配。 Bean依赖关系必须通过 property 元素定义
byType  根据属性类型自动装配。 BeanFactory 查找容器中的全部 Bean, 如果正好有一个与依赖属性类型相同的Bean,就会自动装配这个属性;如果有多个这样的Bean ,Spring 无法决定注入哪个 Bean,就会抛出一个致命异常;如果没有匹配的Bean,就什么都不会发生,属性不会被设置
byName  根据属性名自动装配。BeanFactory 查找容器中全部 Bean ,找出 id 与属性的setter 方法匹配的Bean 。找到即自动注入,否则什么也不会做
constructor  与byType 的方式类似,不同之处在于它应用于构造器参数。如果在容器中没有找到与构造器参数类型一致的 Bean ,那么将会抛出异常

  可以通过<beans>元素的 default-autowire 属性影响全局,减少维护单个 Bean 的注入方式。如果在 <beans>节点上设置 default-autowire 时,依然可以为<bean>节点设置 autowire 属性。这是该<bean> 节点上的自动装配设置将覆盖全局设置,成为该 Bean 的自动装配策略。

4. Spring 配置文件的查分策略和拆分方法

4.1拆分的策略

  拆分的两种方式:

、如果一个开发人员负责一个模块,可以采用公用配置(包含数据源、事务等)+每个系统模块一个单独配置文件(包含Dao 、 Service 及 Web 控制器)的形式。
 二、如果开发是按照分层进行的分工,我们采用公用配置(包含数据源、事务等)+ DAO Bean 配置+ 业务逻辑 Bean 配置 + Web控制情配置的形式。
  两种拆分策略各有特色,拆分 Spring 配置文件,不仅可以分散配置文件,降低修改配置文件的难度和冲突的风险,而且更符合“分而治之”的软件工程原理。

4.2 拆分的方法

  完成 Spring 配置文件的拆分以后,Spring 如何找到拆分后的配置文件?
1、通过 ClassPathXmlApplicationContext 类的构造方法的几种重载形式,通过传入参数的方式将配置文件加载进Spring:

       ClassPathXmlApplicationContext() 
       ClassPathXmlApplicationContext(ApplicationContext parent)  
       ClassPathXmlApplicationContext(String configLocation)  
       ClassPathXmlApplicationContext(String... configLocations)  
       ClassPathXmlApplicationContext(String[] configLocations, ApplicationContext parent)   
       ClassPathXmlApplicationContext(String[] configLocations, boolean refresh)   
       ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent)   		   
       ClassPathXmlApplicationContext(String path, Class<?> clazz)   
       ClassPathXmlApplicationContext(String[] paths, Class<?> clazz)   
       ClassPathXmlApplicationContext(String[] paths, Class<?> clazz, ApplicationContext parent) 

2、或者可以通过通配符(*) 来加载多个具有一定命名规则的配置文件,代码如下:

ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext *.xml");

3、Spring 配置文件本身也可以通过 import 子元素导入其他配置文件,将多个配置文件整合到一起,形成一个完整的 Spring 配置文件。用法示例如下:

<import resource="applicationContext-dao.xml"/>

<import resource="applicationContext-service.xml"/>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值