spring Bean的依赖检查的4种模式

依赖检查与自动装配结合使用,因为依赖检查能够分别对每个bean应用或取消应用,而自动装配完全是自动的,

用依赖检查来对自动装配bean进行显示配置,没有自动装配就没有依赖检查。

spring默认情况下是不检查依赖的,如果要使用依赖检查需要手动的在配置文件中设置。

依赖检查有四种模式:simple,objects,all,none

都通过bean的dependency-check属性进行模式设置。

一,simple模式

使用simple模式是对基本类型、字符串和集合进行依赖检查,理解这句话不太好理解,看看实例解释就知道是怎么依赖检查的。

实例:

HelloWorld类:

  1. package com.lanhuigu.spring.action;  
  2.   
  3.   
  4. public class HelloWorld{  
  5.     private String msg;  
  6.     private RefTest refTest;  
  7.     //有参构造器  
  8.     /*public HelloWorld(RefTest refTest){ 
  9.         this.refTest = refTest; 
  10.     }*/  
  11.     //通过set方法注入属性值  
  12.     public void setMsg(String msg) {  
  13.         this.msg = msg;  
  14.     }  
  15.       
  16.     public String getMsg() {  
  17.         return msg;  
  18.     }  
  19.   
  20.     public RefTest getRefTest() {  
  21.         return refTest;  
  22.     }  
  23.   
  24.     public void setRefTest(RefTest refTest) {  
  25.         this.refTest = refTest;  
  26.     }  
  27.       
  28. }  
spring对simple的配置:
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2.   
  3. <!--  
  4.   - Application context definition for JPetStore's business layer.  
  5.   - Contains bean references to the transaction manager and to the DAOs in  
  6.   - dataAccessContext-local/jta.xml (see web.xml's "contextConfigLocation").  
  7.   -->  
  8. <beans xmlns="http://www.springframework.org/schema/beans"  
  9.         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  10.         xmlns:aop="http://www.springframework.org/schema/aop"  
  11.         xmlns:tx="http://www.springframework.org/schema/tx"  
  12.         xsi:schemaLocation="  
  13.             http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd  
  14.             http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd  
  15.             http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">  
  16.     <!-- 定义一个id为sayHello的bean,  
  17.     通过spring配置文件变换实现类,实现不同的功能,无需修改别的程序 -->  
  18.     <bean id="sayHello" class="com.lanhuigu.spring.action.HelloWorld"   
  19.         autowire="autodetect" dependency-check="simple">  
  20.         <!-- 将变量msg值依赖注入 -->  
  21.         <property name="msg">  
  22.             <value>测试</value>  
  23.         </property>    
  24.         <!-- refTest为HelloWorld的一个属性,通过ref指定依赖关系,  
  25.             也就是说你依赖于哪个类,或者接口,直接把这个类通过set方式注入 ,  
  26.             看看HelloWorld的属性定义就明白了-->  
  27.         <!-- <property name="refTest">  
  28.             <ref bean="refTest"/>  
  29.         </property> -->   
  30.     </bean>  
  31.     <!-- RefTest类 -->  
  32.     <bean id="refTest" class="com.lanhuigu.spring.action.RefTest">  
  33.         <!-- myRef为RefTest类的一个属性 -->  
  34.         <property name="myRef">  
  35.             <value>依赖关系测试</value>  
  36.         </property>  
  37.     </bean>  
  38. </beans>  
对实例进行说明:

所为的依赖检查就是HelloWorld类根据定义的属性private String msg;去spring里面寻找msg这样的属性设置,

这就是依赖检查的含义,依赖于HelloWorld的msg属性,去spring配置文件中进行检查。

simple模式对private String msg;进行检索,如果在spring配置文件中,将

<property name="msg">
            <value>测试</value>
</property>

的配置去掉,报错如下:

  1. org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'sayHello' defined in class path resource [applicationContext.xml]: Unsatisfied dependency expressed through bean property 'msg': Set this property value or disable dependency checking for this bean.  
  2.     at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.checkDependencies(AbstractAutowireCapableBeanFactory.java:1184)  
  3.     at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1006)  
  4.     at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:472)  
  5.     at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory$1.run(AbstractAutowireCapableBeanFactory.java:409)  
  6.     at java.security.AccessController.doPrivileged(Native Method)  
  7.     at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:380)  
  8.     at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:264)  
  9.     at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)  
  10.     at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:261)  
  11.     at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:185)  
  12.     at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:164)  
  13.     at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:429)  
  14.     at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:728)  
  15.     at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:380)  
  16.     at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139)  
  17.     at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:83)  
  18.     at com.lanhuigu.spring.test.TestHelloWorld.testMyHelloWorld(TestHelloWorld.java:14)  
  19.     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)  
  20.     at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)  
  21.     at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)  
  22.     at java.lang.reflect.Method.invoke(Method.java:597)  
  23.     at org.junit.internal.runners.TestMethod.invoke(TestMethod.java:59)  
  24.     at org.junit.internal.runners.MethodRoadie.runTestMethod(MethodRoadie.java:98)  
  25.     at org.junit.internal.runners.MethodRoadie$2.run(MethodRoadie.java:79)  
  26.     at org.junit.internal.runners.MethodRoadie.runBeforesThenTestThenAfters(MethodRoadie.java:87)  
  27.     at org.junit.internal.runners.MethodRoadie.runTest(MethodRoadie.java:77)  
  28.     at org.junit.internal.runners.MethodRoadie.run(MethodRoadie.java:42)  
  29.     at org.junit.internal.runners.JUnit4ClassRunner.invokeTestMethod(JUnit4ClassRunner.java:88)  
  30.     at org.junit.internal.runners.JUnit4ClassRunner.runMethods(JUnit4ClassRunner.java:51)  
  31.     at org.junit.internal.runners.JUnit4ClassRunner$1.run(JUnit4ClassRunner.java:44)  
  32.     at org.junit.internal.runners.ClassRoadie.runUnprotected(ClassRoadie.java:27)  
  33.     at org.junit.internal.runners.ClassRoadie.runProtected(ClassRoadie.java:37)  
  34.     at org.junit.internal.runners.JUnit4ClassRunner.run(JUnit4ClassRunner.java:42)  
  35.     at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)  
  36.     at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)  
  37.     at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)  
  38.     at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)  
  39.     at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)  
  40.     at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)  
该错误告诉我们,sayHello这个bean在使用时不满足依赖检查设置的模式,也就是说HelloWorld类根据msg去spring配置文件

检查关于msg的配置,发现是一场空,狠得报错了!

二,objects模式

objects模式顾名思义就是对依赖对象进行依赖检查。

实例:

HelloWorld类:

  1. package com.lanhuigu.spring.action;  
  2.   
  3.   
  4. public class HelloWorld{  
  5.     private String msg;  
  6.     private RefTest refTest;  
  7.     //有参构造器  
  8.     /*public HelloWorld(RefTest refTest){ 
  9.         this.refTest = refTest; 
  10.     }*/  
  11.     //通过set方法注入属性值  
  12.     public void setMsg(String msg) {  
  13.         this.msg = msg;  
  14.     }  
  15.       
  16.     public String getMsg() {  
  17.         return msg;  
  18.     }  
  19.   
  20.     public RefTest getRefTest() {  
  21.         return refTest;  
  22.     }  
  23.   
  24.     public void setRefTest(RefTest refTest) {  
  25.         this.refTest = refTest;  
  26.     }  
  27.       
  28. }  
spring配置文件:
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2.   
  3. <!--  
  4.   - Application context definition for JPetStore's business layer.  
  5.   - Contains bean references to the transaction manager and to the DAOs in  
  6.   - dataAccessContext-local/jta.xml (see web.xml's "contextConfigLocation").  
  7.   -->  
  8. <beans xmlns="http://www.springframework.org/schema/beans"  
  9.         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  10.         xmlns:aop="http://www.springframework.org/schema/aop"  
  11.         xmlns:tx="http://www.springframework.org/schema/tx"  
  12.         xsi:schemaLocation="  
  13.             http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd  
  14.             http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd  
  15.             http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">  
  16.     <!-- 定义一个id为sayHello的bean,  
  17.     通过spring配置文件变换实现类,实现不同的功能,无需修改别的程序 -->  
  18.     <bean id="sayHello" class="com.lanhuigu.spring.action.HelloWorld"   
  19.         autowire="autodetect" dependency-check="objects">  
  20.         <!-- 将变量msg值依赖注入 -->  
  21.         <!-- <property name="msg">  
  22.             <value>测试</value>  
  23.         </property> -->    
  24.         <!-- refTest为HelloWorld的一个属性,通过ref指定依赖关系,  
  25.             也就是说你依赖于哪个类,或者接口,直接把这个类通过set方式注入 ,  
  26.             看看HelloWorld的属性定义就明白了-->  
  27.         <!-- <property name="refTest">  
  28.             <ref bean="refTest"/>  
  29.         </property> -->   
  30.     </bean>  
  31.     <!-- RefTest类 -->  
  32.     <bean id="refTest" class="com.lanhuigu.spring.action.RefTest">  
  33.         <!-- myRef为RefTest类的一个属性 -->  
  34.         <property name="myRef">  
  35.             <value>依赖关系测试</value>  
  36.         </property>  
  37.     </bean>  
  38. </beans>  
测试程序:
  1. package com.lanhuigu.spring.test;  
  2.   
  3. import org.junit.Test;  
  4. import org.springframework.context.ApplicationContext;  
  5. import org.springframework.context.support.ClassPathXmlApplicationContext;  
  6.   
  7. import com.lanhuigu.spring.action.HelloWorld;  
  8.   
  9. public class TestHelloWorld {  
  10.     @Test  
  11.     public void testMyHelloWorld(){  
  12.         //1.读取spring初始化的配置文件  
  13.         ApplicationContext acxt =   
  14.                 new ClassPathXmlApplicationContext("/applicationContext.xml");  
  15.         //2.根据bean获取ISayHello实现类对象  
  16.         HelloWorld hello = (HelloWorld) acxt.getBean("sayHello");  
  17.         //3.调用接口方法  
  18.         System.out.println(hello.getMsg());  
  19.         //先获取依赖的类RefTest,在从依赖类中获取依赖类的属性  
  20.         System.out.println(hello.getRefTest().getMyRef());  
  21.     }  
  22. }  
关于objects的实例跟simple的实例除了配置文件中依赖检查模式不一样,其他的都一样,为什么不报错?

因为我们设置的依赖检查模式是依赖于对象检查bean,也就是说在HelloWorld类中,依赖属性private RefTest refTest,

在spring中寻找bean,而msg就是有就设置,没有就是null ,因为我们设置的是依赖检查模式,至于别的不是必须的。

如果我们将spring中关于对象RefTest配置部分去掉,也就是去掉:

<bean id="refTest" class="com.lanhuigu.spring.action.RefTest">
        <!-- myRef为RefTest类的一个属性 -->
        <property name="myRef">
            <value>依赖关系测试</value>
        </property>
    </bean>

运行测试程序报错,因为你让HelloWorld类依赖对象private RefTest refTest去检查bean,而这个时候没有找到,就报错,

感情被欺骗了!

三,all模式

对全部属性进行依赖检查。

实例:

将spring中配置依赖检查部分换成all

四,none模式

不进行依赖检查。

实例:

将spring中配置依赖检查部分换成none,这个时候任意去掉msg或refTest配置都不会报错,因为没有强制去检查,

一旦使用依赖检查模式,就会根据设定模式去spring配置文件中寻找目标,找不到就报错。


关于四大依赖检查的总结:

(1)一定要清楚依赖检查的概念,也就是什么依赖于什么去什么地方检查。比如:

在上面的实例中,都是HelloWorld的属性根据设定的检查模式去spring配置文件中检查需要的东西。

重复用objects模式的实例说一下依赖检查的含义:

HelloWorld类中依赖于private RefTest refTest属性,根据设定的对象检索模式去spring配置文件中

检索refTest对象,这就是依赖检索的含义。

(2)依赖检索的意义在于跟自动装配一起使用,方能显出其能耐。开头说过,自动装配是根据设定的

自动装配模式不分青红皂白的去装配,而依赖检索则根据设定的检索模式选择装配对象。

一言以蔽之,自动只要满足自动装配模式,都装;依赖检索是根据检索模式把自动装配的对象进行选择性装配,

这就是两者配合的地方。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值