如果每个属性都使用<ref>设置,一个大项目的Spring配置文件会十分庞大。为此Spring提供了自动装配机制,不用配置<ref>而根据某种规则自动配置属性。 1. 配置autowire自动装配 可以通过<bean>的autowire属性设置自动装配规则。使用autowire后,不需要再用<property name=”” value=”” />显式地设置该Bean的属性,依赖关系。Spring会根据反射,自动寻找符合条件的属性,设置到该Bean属性上。如果aotowire设置为byType,将会按照属性的类型自动匹配。例如: <bean id=”d” class=”examples.D” autowire=”byType”></bean> <!—autowire属性 à 2. autowire取值范围 autowire属性定义的不是需要自动装配的属性名,而是自动装配的规则。一旦配置,所有的属性都将遵循autowire定义的规则。Autowire所有的取值以及意义见表: No或者default :默认值,不自动装配任何属性。所有属性都要使用<ref>或者<idref>配置。在大的部署环境中推荐使用默认值,使用<ref>与<idref>显示配置属性会使依赖性更加明确。 byName :根据名称自动装配。如果Bean中有个名为dataSource的属性,Spring会把id为dataSource的属性设置到该Bean中。 byType :根据类型自动装配。如果Bean中有个DataSource类型的属性,Spring会把DataSource类型的Bean设置到该Bean中。注意如果有多个DataSource类型Bean,会抛出异常。 Constructor : 根据类型自动装配构造函数。如果没有或者有多个类型匹配的Bean,都会抛出异常。 Autodetect :自动探测。如果构造函数带有参数,则同constructor,否则同byType。 如果显式式定义了<property>或者<constructor-arg>,会覆盖默认装配。自动装配一般与下面的依赖检查连用。 注:在大型的部署环境中,Spring不推荐使用自动装配。因为自动装配会隐藏依赖装配的细节,降低可读性与可维护性,并可能带来意想不到的麻烦。 依赖检查dependency 有时候某些Bean的属性配置有错误,比如某个属性没有设置。这种错误在程序启动的时候不会有任何异常表现,会一直潜伏到Spring调用该Bean时才会被发现。为了防止这种情况,Spring提供依赖检查,在程序启动的时候检查依赖配置。如果有错误,启动时就会抛出异常,以便发现配置错误。 1. 配置dependency依赖检查 依赖检查能够检查属性是否被设置。如果配置依赖检查,程序启动时会进行配置校验,以便及时地发现配置错误。通过设置<bean>的dependency-check设置依赖检查规则,例如: <bean id=”bean” class=”examples.Bean” dependency-check=”all”></bean> 2. dependency属性取值范围 dependency属性有多种取值,分别应付不同的情况。但是需要注意,dependency依赖检查室很生硬的,例如配置为object,将会检查所有的java对象属性。只要有一个属性没有设置就是抛出异常,即某属性明明不需要设置,但是没法避免dependency检查,容易造成“一竿子全打死”的现象。Dependency的取值以及意义见表: no或者default : 不做任何检查 simple : 仅检查基本类型,集合属性。如果有属性没有设置,会抛出异常。 Object : 仅检查Java对象属性。如果有属性没有设置,会抛出异常。 All : 检查所有属性,等同于simple与object的并集。 Bean的高级特性 Spring程序中,Java Bean一般与Spring 是非耦合的,不会依赖于Spring类库。这也是Spring的优点。但有时候Java Bean需要知道自己在Spring框架中的一些属性。Spring提供了一些接口,实例化Java Bean对象后Spring会调用接口的方法。 1 BeanNameAware接口获取Bean的id BeanNameAware接口帮助Java Bean知道自己在配置文件中的id。实现BeanNameAware接口,实现方法名为setBeanName()方法,初始化该对象后Spring就会执行该回调方法,将id设置进来。Bean中设置一个编码,接受id名称即可。例如: Package com.zhangjie.spring.example; Import org.springframework.beans.factory.BeanNameAware; Public class WhatsTheNameBean implements BeanNameAware{ //感知Bean的名字 Private String beanName; //保存名字 Public void setBeanName(String beanName){ This.beanName = beanName; //Spring会调用该方法 } } 提示:setBeanName()方法的回调发生在所有参数被设置完之后,初始化方法(init-method属性)被执行之前。 1 BeanFactoryAware接口获取BeanFactory BeanFactoryAware接口帮助Java Bean知道哪个BeanFactory实例化了自己。BeanFactoryAware接口中有setBeanFactory的回调方法,初始化该对象后,会回调该方法,将BeanFactory传递进来。BeanFactoryAware接口的代码如下: Public interface BeanFactoryAware{ Void setBeanFactory(BeanFactory beanFactory) throws BeansException; //会调用该方法; } 用法同BeanNameAware。实现了BeanFactoryAware接口的Java Bean能够获取到BeanFactory,从BeanFactory中能够获取到该BeanFactory中配置的其他Java Bean。Spring不推荐这样做,因为这样会与Spring耦合。获取其他Java Bean一般通过设置setter,gettter方法,用依赖注入实现。 1 InitializingBean接口执行初始化方法 实现了InitializingBean接口的Java Bean会在实例化后,所有属性被设置后调用初始化方法。但使用该接口会与Spring代码发生耦合,因此不推荐使用。InitailizingBean接口代码如下: Public interface InitializingBean{ //初始化Bean Public void afterPropertysSet(); //初始化时调用该方法; } Spring 推荐使用init-method配置,效果等价: <bean id=”d” class=”examples.D” init-method=” afterPropertiesSet”></bean> //配置初始化方法 1 DisposableBean接口执行销毁方法 实现了DisposableBean接口的Java Bean会在对象丢弃的时候调用销毁方法。但使用该接口会与Spring代码发生耦合,因此不推荐使用。DisposableBean接口代码如下: Public interface DisposableBean{ //可销毁Bean Void destroy() throws Exception; //销毁时调用该方法 } Spring推荐调用使用destroy-method配置,效果等价: <bean id=”dataSource” class=”org.apache.commons.dbcp.BasicDataSource” destroy-method=”close”></bean> BeanFactory高级特性 如果Java Bean实现了BeanFactoryAware接口,就能够获得BeanFactory对象。BeanFactory有下面几个常用的方法: ü Boolean containsBean(String):判断指定名称的Bean是否存在。 ü Object getBean(String):返回指定名称得的Bean。如果没有改Bean,会抛出异常。 ü Object getBean(String,Class):返回指定名称的Bean,并转化为指定的类对象。如果没有该Bean,会抛出异常。如果类型转化错误,也会抛出异常。 ü Boolean isSingleton(String):判断指定名称的Bean是否被配置为singleton。如果没有该Bean,会抛出异常。 ü String[] getAliases(String) :返回指定名称的Bean的别名。 属性覆盖器 对于一些参数,更实用更简单的方法是使用properties配置,而不是配置在Spring的配置文件中。Spring提供属性替代配置,允许把某些属性配置在properties文件中。 1 配置PropertyOverrideConfigurer属性覆盖器 PropertyOverrideConfigurer允许把XML配置里的某些参数配置到properties文件中。这在数据库配置中很常用。配置时需要配置一个PropertyOverrideConfigurer对象,指定properties文件的位置,然后把替换的属性用形如${jdbc.url}的字符串替代,例如: <bean id=”dataSource” class=”org.apache.commons.dbcp.BasicDataSource” destory-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.PropertyPlaceholderConfigrer”> <property name=”location” value=”classpath:jdbc.properties”/> </bean> 提示:PropertyOverrideConfigurer对象会到指定名称的properties文件(例如jdbc.properties)中,寻找属性名为${}变量的配置。${}中最好不要有空格。 1, properties配置 具体的数据库配置是写在jdbc.properties里面的。Properties中的配置比applicationContext.xml中更便于阅读,修改于维护。代码如下: Jdbc.driverClassNamer=com.mysql.jdbc.Driver #配置驱动 Jdbc.url=jdbc.mysql://localhost:3306/training?characterEncoding=UTF-8 #连接URL Jdbc.username=root #用户名 Jdbc.password=admin #密码 |