我们是如何将我们自己的bean纳入了容器的管理范围内的呢?上节课的讲解过程中我们知道了通过一个例子进行相关的探究,这次我们针对于如何将自己的bean纳入到容器的管理中。通常情况下有两种方式:xml配置文件和spring特性也就是注解。
1. xml配置文件
Spring IoC容器将读取配置元数据;并通过它对应用中各个对象进行实例化、配置以及组装,通常情况下我们使用简单直观 的XML来作为配置元数据的描述格式。在XML配置元数据中我们可以对那些我们希望通过 Spring IoC容器管理的bean进行定义。
那么什么是bean呢?
在Spring中,那些组成你应用程序的主体(backbone)及由Spring IoC容器所管理的对象,被称之为bean。 简单地讲,bean就是由Spring容器初始化、装配及管理的对象,除此之外,bean就与应用程序中的其他对象没有什么区别了。而bean定义以及bean相互间的依赖关系将通过配置元数据来描述。
而Spring的IOC容器负责我们上述所描述的bean并且进行相应的管理,在Spring中,BeanFactory是IoC容器的核心接口。 它的职责包括:实例化、定位、配置应用程序中的对象及建立这些对象间的依赖。
基于XML的元数据是最常用到的配置元数据格式,下面我们来看看吧~
Xml配置元数据源
将XML配置文件分拆成多个部分是非常有用的。为了加载多个XML文件生成一个ApplicationContext实例,可以将文件路径作为字符串数组传给ApplicationContext构造器。而bean factory将通过调用bean defintion reader从多个文件中读取bean定义。
<span style="font-family:Microsoft YaHei;font-size:14px;"><strong><beans>
<import resource="services.xml"/>
<import resource="resources/messageSource.xml"/>
<import resource="/resources/themeSource.xml"/>
<bean id="bean1" class="..."/>
<bean id="bean2" class="..."/>
</beans></strong></span>
这样的好处是即使我们的配置文件包含着多个,但是我们在web.xml下只是需要配置一个即可。这样是不是很方便呢,并且如果需要其他的模块配置文件,只是需要修改配置文件即可,不用重新编译整个的工程。
在容器内部,这些bean定义由BeanDefinition 对象来表示,该定义将包含以下信息:
(1) 全限定类名:这通常就是已定义bean的实际实现类。
在上面的定义就是class之后的一串字符串。
<span style="font-family:Microsoft YaHei;font-size:14px;"><strong><bean id="usrDao4Oracle" class="com.bjpowernode.spring.dao.UserDao4OracleImpl"/></strong></span>
(2) bean行为的定义,这些定义将决定bean在容器中的行为(作用域、生命周期回调等等)
<span style="font-family:Microsoft YaHei;font-size:14px;"><strong><bean id="loginAction"class="cn.bjpower.action.LoginAction"scope="singleton">
<property name="user"ref="user"></property>
</bean> </strong></span>
(3) 对其他bean的引用,这些引用bean也可以称之为协作bean(collaborators)或依赖bean(dependencies).
<span style="font-family:Microsoft YaHei;font-size:14px;"><strong><bean id="usrDao4Oracle" class="com.bjpowernode.spring.dao.UserDao4OracleImpl"/>
<bean id="userManager" class="com.bjpowernode.spring.manager.UserManagerImpl">
<property name="userDao" ref="usrDao4Oracle"/>
</bean></strong></span>
Ref指向的就是引用。
(4) 创建bean实例时的其他配置设置。比如使用bean来定义连接池,可以通过属性或者构造参数指定连接数,以及连接池大小限制等。上述内容直接被翻译为每个bean定义包含的一组properties。
<span style="font-family:Microsoft YaHei;font-size:14px;"><strong><!-- 配置c3p0数据库连接池 -->
<property name="dataSource">
<bean class="com.mchange.v2.c3p0.ComboPooledDataSource">
<!-- 数据连接信息 -->
<property name="jdbcUrl" value="${jdbcUrl}"></property>
<property name="driverClass" value="${driverClass}"></property>
<property name="user" value="${user}"></property>
<property name="password" value="${password}"></property>
<!-- 其他配置 -->
<!--初始化时获取三个连接,取值应在minPoolSize与maxPoolSize之间。Default: 3 -->
<property name="initialPoolSize" value="3"></property>
<!--连接池中保留的最小连接数。Default: 3 -->
<property name="minPoolSize" value="3"></property>
<!--连接池中保留的最大连接数。Default: 15 -->
<property name="maxPoolSize" value="5"></property>
<!--当连接池中的连接耗尽的时候c3p0一次同时获取的连接数。Default: 3 -->
<property name="acquireIncrement" value="3"></property>
<!-- 控制数据源内加载的PreparedStatements数量。如果maxStatements与maxStatementsPerConnection均为0,则缓存被关闭。Default: 0 -->
<property name="maxStatements" value="8"></property>
<!--maxStatementsPerConnection定义了连接池内单个连接所拥有的最大缓存statements数。Default: 0 -->
<property name="maxStatementsPerConnection" value="5"></property>
<!--最大空闲时间,1800秒内未使用则连接被丢弃。若为0则永不丢弃。Default: 0 -->
<property name="maxIdleTime" value="1800"></property>
</bean>
</property></strong></span>
使用xml配置的好处
1. XML配置方式进一步降低了耦合,便于扩展,此外配置文件的修改是无需重新编译整个工程的。
2. 对于业务逻辑复杂的,我们可以将其直接的联系进行很好的配置,ref表示各个bean之间的依赖关系,并且一目了然,使得对象之间的调用十分清晰。
当业务过多的时候,我们也不用担心配置文件太大太臃肿,我们可以使用分解业务,从而使用import将相关的配置进行 导入即可。
当然美中也存在不足,那就是读取和解析需要一定的时间,并且配置文件出现错误是不容易进行调试的,故而使得调试的 难度增加了。
2. 基于注解的配置
引用和配置
Spring 2.0 对必须的属性引入了@Required注解。在 Spring2.5中已经可以用注解的方式去驱动 Spring的依赖注射了。
使用注解需要在配置文件中添加关于context命名空间。
<span style="font-family:Microsoft YaHei;font-size:14px;"><strong><?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd">
</beans></strong></span>
使用注解时,自动扫描我们装配或者说注入的bean,配置是:
<span style="font-family:Microsoft YaHei;font-size:14px;"><strong><!-- 自动扫描与装配bean -->
<!-- 打开配置 <context:component-scan base-package="包名(扫描本包及子包)"/>-->
<!--spring 会自动扫描cn.itcast.oa包下面有注解的类,完成Bean的装配。-->
<context:component-scan base-package="cn.itcast.oa"></context:component-scan></strong></span>
常用的注解
@Component、@Controller、@Service、@Repository,这是我们比较常用的注解,<context:component-scanbase-package="cn.itcast.oa"></context:component-scan>这句话的作用把cn.itcast.oa包及其所有子包下的所含有@Component、@Controller、@Service、@Repository等注解的类注入到Spring容器中。
那么每个注解的应用场合是什么呢?
@Controller
一般用于定义控制层Bean,如Action
<span style="font-family:Microsoft YaHei;font-size:14px;"><strong>@Controller
@Scope("prototype")
public class UserAction extends BaseAction<User> {}</strong></span>
@Service
一般用于定义业务层Bean
<span style="font-family:Microsoft YaHei;font-size:14px;"><strong>@Service
@Transactional
public class UserServiceImpl extends BaseDaoImpl<User> implements UserService {}
</strong></span>
@Repository
一般用于定义DAO层Bean
<span style="font-family:Microsoft YaHei;font-size:14px;"><strong>@Repository
public class RoleDaoImpl extends BaseDaoImpl<Role> implements RoleDao {
// @Repository表示注入到容器中去
}</strong></span>
@Component
无法确定属于那种类型时可以使用。这是具体的类的注解使用,关于方法,属性字段等相关的注解,将会在spring MVC讲解的过程中进行详细的讲解。
注解的好处
注解一眼就可以看到的好处就是没有大量的配置文件的书写,咱们来总结一下吧。
(1) 不用书写大量的配置信息,配置机制相比较xml更加的简单。
(2) 无需解析,使用java的反射机制就可以进行获取。
(3) 不同于xml配置,这个在编译期就可以进行相关的错误进行检查,更易调试。
不足之处就是修改,修改完后必须编译整个工程,此外,由于没有像xml那样进行对象间的配置,这样就使得对象的逻辑关系不是那么的清晰。
3. 总结
世界上没有完美无缺的事物,编程也是这样,编程来源于生活,故而与世间之事相同,我们在选用的时候根据自己的需要,合适就好~