Spring 自動裝配AutoWire

樑天超發表於2014-05-26


 引用:

在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>





相關文章