Spring基本配置

Spring 最基本的的功能是提供通过配置管理任意类,提供了Bean管理容器。

这也是Spring最基础,最核心的功能,在Spring框架中,一切皆为Bean,实际上在我们的日常开发中,往往更多的是和Bean相关的开发,并且都是短生命周期,除了一些缓存功能,其他很多重要的功能都是由开源框架完成。

实现方式也是框架常用的反射机制,因此使用Spring前提在JVM启动参数中不能加安全管理配置。Spring中所有的Bean相关配置均为一个文件,非常集中,个人感觉这有利有弊,利大于弊。

统一配置比较方便集中,我最近的项目就是有很多子系统,除了一些公用的配置文件,还有很多子系统的配置文件,每次迁移环境是非常累的事,如果只有一个配置文件,那工作就会轻松多了。

缺点也就在于很集中,如果配置有误,整个系统不可用,这种情况往往发生在系统升级阶段,也比较少,即使出现问题也比较好定位。
Spring提供了Bean管理容器,这个功能可以大大简化业务系统的配置开发工作。

个人感觉将来的开发工作更多的是配置,编写业务相关的Bean以及业务方法,其他功能均会有很多优秀的开源框架实现,重要的工作是选择符合项目的框架、熟悉框架,最重要的还是苦修内功,深入学习java,因为万变不如其中,再说开源不是万能的,有时候还是要靠自己的。

Spring提供三种创建类实例方法:
a、通过构造函数,访问属性可以是任意
b、通过对应类的静态工厂方法,注意不能是私有的
c、通过工厂类的实例工厂方法,是非静态的方法

1、bean节点相关主要属性:
id/name 实例名/别名
class 必须、类全名
singleton 是否为单实例,默认为true
init-method 初始化方法
depends-on 指定依赖Bean,实现在被依赖Bean实例创建前,对依赖的一个或多个Bean的实例化,
init-method在对应Bean实例已经创建后调用
destroy-method 释放回调方法,常用于资源释放
dependency-check 依赖检查
parent 指定父Bean实例,减少因继承关系的重复配置
说明除配置init-method,destory以外,可以在对应Bean中实现InitializingBean,DisposableBean两个接口方法
Spring容器不负责管理非单实例的Bean
配置bean事项:
1)、注意在通过构造器参数匹配时,必须指定参数的序号,同时建议明确说明类型,
<constructor-arg index=”0″><value>128</value></constructor-arg>
<constructor-arg index=”1″><value>teststring</value></constructor-arg>
最好说明相关参数类型类型
<constructor-arg index=”0″ type=”int”><value>128</value></constructor-arg>
<constructor-arg index=”1″ type=”java.lang.String”><value>teststring</value></constructor-arg>
可以使用简化配置
<constructor-arg index=”0″ type=”int” value=”128″/>
<constructor-arg index=”1″ type=”java.lang.String” value=”testString”/>

2)、属性为空
<property name=”pro1><null/></property>
3)、空串
<property name=”pro1><value></value></property>
2、常用elements
bean | ref | idref | value | null | list | set | map | props
说明:
bean 创建一个新的bean实例
ref 引用已经创建的bean实例
value 简单数据类型
null 空指针
list 创建java.util.ArrayList对象实例
set 创建java.util.LinkedHashSet对象实例
map 创建java.util.LinkedHashMap对象实例
props 创建java.util.Properties实例
list,set,map可以多层嵌套配置

遗留问题:
idref 配置没有起作用,类似value配置,测试输出为字符串对象,是否配置不正确?

上述配置范围基本覆盖了我们开发时的bean使用情况,详见配置可以参考dtd
http://www.springframework.org/dtd/spring-beans.dtd

ApplicationContext 继承于BeanFactory相关接口,针对企业应用级的,占有内存较多
BeanFactory 提供配置框架和基本功能,适用于对内存有限制的相关应用
功能:
1)、提供消息访问,ApplicationContext 本身继承于MessageSource接口,
ApplicationContext 加载时查找对应的MessageSource Bean, bean id 必须为messageSource
Spring框架提供两个MessageResource实现:
org.springframework.context.support.ResourceBundleMessageSource
org.springframework.context.support.StaticMessageSource
2)、事件传递
3)、使用资源

Spring注释与简化配置

在Spring 2.5及以后的版本中,提供了注释和命名空间来简化Spring的配置。下面是一些常用配置分享。

1、@Autowired注释
以前给一个Bean配置属性时,Bean必须配置<property name=”propName” ref=”beanId”/>,然后在Java文件,还必须增加属性propname的getter和setter方法。
有了@Autowired注释后,我们可以简化配置文件和getters和setters方法。
1)注释属性
@Autowired
private BeanClassName propName;
当然,我们还必须告诉Spring容器,当它启动时,就去扫描所有的Bean,然后自动注入。
<!– 对具有@Autowired注释的Bean进行注入 –>
<bean class=”org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor”/>
我们也可以注释构造函数和方法。
2)注释构造函数
@Autowired
public MainBean(PropBeanA propBeanA, PropBeanB propBeanB){
this.propBeanA = propBeanA;
this.PropBeanB = PropBeanB ;
}
3)注释方法
@Autowired
public void setPropBean(PropBean propBean) {
this.propBean = propBean;
}
4)@Autowired的相关属性
在默认情况下使用@Autowired注释进行自动注入时,Spring容器中匹配的候选Bean数目必须有且仅有一个。当Springp容器找不到一个匹配的Bean时(可能是没有配置该Bean或是Bean的属性名写错了),Spring容器将抛出BeanCreationException异常,并指出必须至少拥有一个匹配的Bean。
(1)当Bean是可选的,或是不能确定Bean一定有,可以用@Autowired(required = false),这样在找不到匹配Bean 时也不报错,该属性默认为true。
(2)与上面的相反,当Bean有多个时,我们可以通过@Qualifier(“beanId”)还唯一确定一个所引用的Bean,与@Autowired配合使用,它也有三种使用的地方。

2、@Component注释
虽然我们可以通过@Autowired在Bean类中使用自动注入功能,但是Bean还是在XML文件中通过<bean>进行定义的,通过@Component注释可以实现无需在配置文件中配置Bean的目的。
import org.springframework.stereotype.Component;
@Component
public class BeanClassNameA {
// ……
}
使用@Autowired
@Component
public class BeanClassNameB {
@Autowired
private BeanClassNameA propBeanA;

// ……
}
因为没有配置,我们必须告诉Spring容器启用类扫描机制并自动注入了:
<context:annotation-config />
前面的AutowiredAnnotationBeanPostProcessor可以去掉了,这行的作用后面介绍。
1)@Component有个可选参数,指定Bean的名称@Component(“beanId”)
2)与@Component配合使用,可以通过@Scope指定Bean的作用范围,比如:@Scope(“prototype”)

3、其他注释
Spring除了提供@Component注释外,还定义了几个注释:@Repository、@Service 和 @Controller。
在目前的Spring 2.5中,这3个注释和@Component是等效的,但是从注释类的命名上,很容易看出这3个注释分别和持久层、业务层和控制层(Web 层)相对应。虽然目前这3个注释和@Component相比没有什么新意,但Spring将在以后的版本中为它们添加特殊的功能。所以,如果 Web 应用程序采用了经典的三层分层结构的话,最好在持久层、业务层和控制层分别采用@Repository、@Service和 @Controller对分层中的类进行注释,而用@Component对那些比较中立的类进行注释。

4、<context:annotation-config />
<context:annotation-config />将隐式地向Spring容器注册 AutowiredAnnotationBeanPostProcessor、CommonAnnotationBeanPostProcessor、PersistenceAnnotationBeanPostProcessor 以及 RequiredAnnotationBeanPostProcessor这4个BeanPostProcessor。

5、<context:component-scan base-package=”……” />
通过<context:component-scan base-package=”com.packname.common” />,Spring会递归扫描类注释。
具体的说明可以参考:http://springindepth.com/book/annotation-based-bean-config-ioc-container-configuration.html

6、JavaEE应用@Controller
在使用SpringMVC中,可以通过@Controller简化配置
@Controller
@RequestMapping(“/welcome.htm”)
public class SomeNameController {
@RequestMapping(method = RequestMethod.GET)
public void doGet(ModelMap model, WebRequest request) {
// …
}
}
关于@Controller,在以后的文章中介绍,敬请关注。

7、简化配置文件
对于属性,我们一般都是通过以下配置的:
<bean id=”transactionManager”
class=”org.springframework.jdbc.datasource.DataSourceTransactionManager”>
<property name=”dataSource” ref=”dataSource” />
</bean>
简化之后为:
<bean id=”transactionManager”
class=”org.springframework.jdbc.datasource.DataSourceTransactionManager”
p:dataSource-ref=”dataSource” />
使用方法介绍,我相信就没必要了,注意这两种方式可以一起使用的。

8、命名空间
在以上的<context:…. />和<bean id=”..” p:name-ref=”” />中,我们用到了context和p命名空间,因此必须在配置文件中申明,我的如下:
<?xml version=”1.0″ encoding=”GBK”?>
<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”
xmlns:osgi=”http://www.springframework.org/schema/osgi” xmlns:context=”http://www.springframework.org/schema/context”
xsi:schemaLocation=”http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/osgi http://www.springframework.org/schema/osgi/spring-osgi.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd”
default-autowire=”byName”>
XSD文件版本小技巧:不要增加版本(如直接使用spring-context.xsd),当然要加也是spring-context-2.5.xsd

由于介绍内容比较多,感觉都比较空,还有一些没有介绍具体:
(1)JavaEE的注释,主要是@Controller;
(2)JPA注释,@Entity,@Table;
(3)JSR-250的注释,@Resource、@PostConstruct、@PreDestroy等。

下面贴出我的Spring配置文件的内容。
<?xml version=”1.0″ encoding=”GBK”?>
<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”
xmlns:osgi=”http://www.springframework.org/schema/osgi” xmlns:context=”http://www.springframework.org/schema/context”
xsi:schemaLocation=”http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/osgi http://www.springframework.org/schema/osgi/spring-osgi.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd”
default-autowire=”byName”>

<!– Activates annotation-based bean configuration –>
<context:component-scan base-package=”com.alipay.common” />

<!– DataSource –>
<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/work_shop?useUnicode=true&amp;characterEncoding=UTF-8″ />
<property name=”username” value=”root” />
<property name=”password” value=”manager” />
</bean>

<!– SqlMapClient –>
<bean id=”sqlMapClient” class=”org.springframework.orm.ibatis.SqlMapClientFactoryBean”>
<property name=”configLocations”>
<list>
<value>classpath:sqlmap/sqlmap-config.xml</value>
</list>
</property>
</bean>

<!– SqlMapClientDAO –>
<bean id=”sqlMapClientDAO” abstract=”true” p:dataSource-ref=”dataSource”
p:sqlMapClient-ref=”sqlMapClient” />

<!– TransactionTemplate –>
<bean id=”transactionManager”
class=”org.springframework.jdbc.datasource.DataSourceTransactionManager”
p:dataSource-ref=”dataSource” />

<!– TransactionManager –>
<bean id=”mockTransactionTemplate”
class=”org.springframework.transaction.support.TransactionTemplate”
p:transactionManager-ref=”transactionManager” />

<!– DAO –>
<bean id=”siteUserDAO” class=”com.alipay.dal.ibatis.IbatisSiteUserDAO”
parent=”sqlMapClientDAO” />
<!– END OF DAO –>

<!– MANAGER –>
<bean id=”siteUserManager” class=”com.alipay.biz.manager.impl.SiteUserManagerImpl” />
<!– END OF MANAGER –>
<!– FACADE–>
<!– END OF FACADE–>
<!– OSGI SERVICE–>
<!– END OF OSGI SERVICE–>
</beans>