Spring 自动安装AutoWire

Spring 自动装配AutoWire


 引用:

在xml配置文件中,autowire有5种类型,可以在<bean/>元素中使用autowire属性指定

 

  • 模式                        说明   
  •  no                       不使用自动装配,必须通过ref元素指定依赖,默认设置。   
  • byName                    根据属性名自动装配。此选项将检查容器并根据名字查找与                   
  •                           属性完全一致的bean,并将其与属性自动装配。   
  • byType                    如果容器中存在一个与指定属性类型相同的bean,那么将与   
  •                           该属性自动装配;如果存在多个该类型bean,那么抛出异   
  •                           常,并指出不能使用byType方式进行自动装配;如果没有找   
  •                           到相匹配的bean,则什么事都不发生,也可以通过设置   
  •                           dependency-check="objects"让Spring抛出异常。   
  • constructor               与byType方式类似,不同之处在于它应用于构造器参数。如   
  •                           果容器中没有找到与构造器参数类型一致的bean,那么抛出   
  •                           异常。   
  • autodetect                通过bean类的自省机制(introspection)来决定是使用   
  •                           constructor还是byType方式进行自动装配。如果发现默认的   
  •                           构造器,那么将使用byType方式。 

    可以设置bean使自动装配失效: 
    采用xml格式配置bean时,将<bean/>元素的autowire-candidate属性设置为false,这样容器在查找自动装配对象时,将不考虑该bean,即它不会被考虑作为其它bean自动装配的候选者,但是该bean本身还是可以使用自动装配来注入其它bean的。


    测试:

    test文件:

    package com.bjsxt.dao;
    
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    import com.bjsxt.model.User;
    import com.bjsxt.service.UserService;
    
    
     class Test {
    	public static void main(String[] args){
       ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");
    		
    		
    		UserService service = (UserService)ctx.getBean("userService");
    		
    		System.out.println(service.getUserDAO());
    	}
    
    }
    

    首先采用 "byName" 的方式.配置文件如下:

    <?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"
              >
    
      <bean name="userDAO2" class="com.bjsxt.dao.impl.UserDAOImpl">
      	<property name="daoId" value="1"></property>
      </bean>
      
      <bean name="userDAO" class="com.bjsxt.dao.impl.UserDAOImpl">
      	<property name="daoId" value="2"></property>
      </bean>
    	
      <bean id="userService" class="com.bjsxt.service.UserService" scope="prototype" autowire="byName">
      
       <!--  autowire="byType"
       <property name="userDAO" ref="userDAO" />-->
      </bean>
      
    
    </beans>

    因为service中存在 名为userDAO的成员:

    package com.bjsxt.service;
    import com.bjsxt.dao.UserDAO;
    import com.bjsxt.model.User;
    
    
    
    public class UserService {
    	
    	private UserDAO userDAO;  
    	public void add(User user) {
    		userDAO.save(user);
    	}
    	public UserDAO getUserDAO() {
    		return userDAO;
    	}
    	public void setUserDAO(UserDAO userDAO) {
    		this.userDAO = userDAO;
    	}
    	
    
    }
    

    所以采用byName方式匹配时, 选中的name为 userDAO的bean.

    Test输出如下:

    <span style="background-color: rgb(255, 255, 255);"><span style="color:#ff6666;">INFO: Loading XML bean definitions from class path resource [beans.xml]
    五月 26, 2014 10:42:23 上午 org.springframework.context.support.AbstractApplicationContext obtainFreshBeanFactory
    INFO: Bean factory for application context [org.springframework.context.support.ClassPathXmlApplicationContext@34b172ef]: org.springframework.beans.factory.support.DefaultListableBeanFactory@2ea8bf33
    五月 26, 2014 10:42:23 上午 org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons
    INFO: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@2ea8bf33: defining beans [userDAO2,userDAO,userService]; root of factory hierarchy</span></span><span style="color:#232323;">
    daoId=2</span>
    换成"byType"

    因为存在两个类型相同的bean. 程序报错

    五月 26, 2014 10:45:23 上午 org.springframework.context.support.AbstractApplicationContext prepareRefresh
    INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@2c4a1908: display name [org.springframework.context.support.ClassPathXmlApplicationContext@2c4a1908]; startup date [Mon May 26 10:45:23 CST 2014]; root of context hierarchy
    五月 26, 2014 10:45:23 上午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
    INFO: Loading XML bean definitions from class path resource [beans.xml]
    五月 26, 2014 10:45:24 上午 org.springframework.context.support.AbstractApplicationContext obtainFreshBeanFactory
    INFO: Bean factory for application context [org.springframework.context.support.ClassPathXmlApplicationContext@2c4a1908]: org.springframework.beans.factory.support.DefaultListableBeanFactory@73354684
    五月 26, 2014 10:45:24 上午 org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons
    INFO: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@73354684: defining beans [userDAO2,userDAO,userService]; root of factory hierarchy
    Exception in thread "main" org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'userService' defined in class path resource [beans.xml]: Unsatisfied dependency expressed through bean property 'userDAO': : No unique bean of type [com.bjsxt.dao.UserDAO] is defined: expected single matching bean but found 2: [userDAO2, userDAO]; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No unique bean of type [com.bjsxt.dao.UserDAO] is defined: expected single matching bean but found 2: [userDAO2, userDAO]
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireByType(AbstractAutowireCapableBeanFactory.java:1091)
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:982)
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:472)
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory$1.run(AbstractAutowireCapableBeanFactory.java:409)
    	at java.security.AccessController.doPrivileged(Native Method)
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:380)
    	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:283)
    	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:185)
    	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:164)
    	at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:880)
    	at com.bjsxt.dao.Test.main(Test.java:15)
    Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No unique bean of type [com.bjsxt.dao.UserDAO] is defined: expected single matching bean but found 2: [userDAO2, userDAO]
    	at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:621)
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireByType(AbstractAutowireCapableBeanFactory.java:1076)
    	... 10 more
    


    在此基础上,如果将第二个bean的autowire-candidate 属性设为false:

    <?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"
              >
    
      <bean name="userDAO2" class="com.bjsxt.dao.impl.UserDAOImpl">
      	<property name="daoId" value="1"></property>
      </bean>
      
      <bean name="userDAO" class="com.bjsxt.dao.impl.UserDAOImpl" autowire-candidate="false">
      	<property name="daoId" value="2"></property>
      </bean>
    	
      <bean id="userService" class="com.bjsxt.service.UserService" scope="prototype" autowire="byType">
      
       <!--  autowire="byType"
       <property name="userDAO" ref="userDAO" />-->
      </bean>
      
    
    </beans>

    则在匹配时只有第一个bean符合条件, 不发生冲突, 正常输出结果:

    <span style="color:#ff6666;">五月 26, 2014 10:46:46 上午 org.springframework.context.support.AbstractApplicationContext prepareRefresh
    INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@2c4a1908: display name [org.springframework.context.support.ClassPathXmlApplicationContext@2c4a1908]; startup date [Mon May 26 10:46:46 CST 2014]; root of context hierarchy
    五月 26, 2014 10:46:46 上午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
    INFO: Loading XML bean definitions from class path resource [beans.xml]
    五月 26, 2014 10:46:46 上午 org.springframework.context.support.AbstractApplicationContext obtainFreshBeanFactory
    INFO: Bean factory for application context [org.springframework.context.support.ClassPathXmlApplicationContext@2c4a1908]: org.springframework.beans.factory.support.DefaultListableBeanFactory@73354684
    五月 26, 2014 10:46:46 上午 org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons
    INFO: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@73354684: defining beans [userDAO2,userDAO,userService]; root of factory hierarchy</span><span style="color:#232323;">
    daoId=1</span>