溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

常見的Spring注入方式有幾種

發(fā)布時間:2020-06-02 11:40:35 來源:億速云 閱讀:857 作者:Leah 欄目:編程語言

常見的Spring注入方式有幾種?針對這個問題,今天小編總結這篇有關Spring注入方式的文章,可供感興趣的小伙伴們參考借鑒,希望對大家有所幫助。

Spring常用的注入方式有三種

1、構造方法,采用反射的方式,通過構造方法來完成注入。

先簡單了解一下測試項目的結構,用maven構建的,四個包:

  • entity:存儲實體,里面只有一個User類

  • dao:數(shù)據(jù)訪問,一個接口,兩個實現(xiàn)類

  • service:服務層,一個接口,一個實現(xiàn)類,實現(xiàn)類依賴于IUserDao

  • test:測試包

在spring的配置文件中注冊UserService,將UserDaoJdbc通過constructor-arg標簽注入到UserService的某個有參數(shù)的構造方法

<!-- 注冊userService -->
<bean id="userService" class="com.lyu.spring.service.impl.UserService">
  <constructor-arg ref="userDaoJdbc"></constructor-arg>
</bean>
<!-- 注冊jdbc實現(xiàn)的dao -->
<bean id="userDaoJdbc" class="com.lyu.spring.dao.impl.UserDaoJdbc"></bean>

如果只有一個有參數(shù)的構造方法并且參數(shù)類型與注入的bean的類型匹配,那就會注入到該構造方法中。

public class UserService implements IUserService {
  private IUserDao userDao;
  
  public UserService(IUserDao userDao) {
    this.userDao = userDao;
  }
  
  public void loginUser() {
    userDao.loginUser();
  }
}
@Test
public void testDI() {
  ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
  // 獲取bean對象
  UserService userService = ac.getBean(UserService.class, "userService");
  // 模擬用戶登錄
  userService.loginUser();
}

測試打印結果:jdbc-登錄成功

注:模擬用戶登錄的loginUser方法其實只是打印了一條輸出語句,jdbc實現(xiàn)的類輸出的是:jdbc-登錄成功,mybatis實現(xiàn)的類輸出的是:mybatis-登錄成功。

2、setter,也是采用反射的方式,不過是通過setter來完成注入。

配置文件如下:

<!-- 注冊userService -->
<bean id="userService" class="com.lyu.spring.service.impl.UserService">
  <!-- 寫法一 -->
  <!-- <property name="UserDao" ref="userDaoMyBatis"></property> -->
  <!-- 寫法二 -->
  <property name="userDao" ref="userDaoMyBatis"></property>
</bean>
<!-- 注冊mybatis實現(xiàn)的dao -->
<bean id="userDaoMyBatis" class="com.lyu.spring.dao.impl.UserDaoMyBatis"></bean>

注:上面這兩種寫法都可以,spring會將name值的每個單詞首字母轉換成大寫,然后再在前面拼接上"set"構成一個方法名,然后去對應的類中查找該方法,通過反射調用,實現(xiàn)注入。

切記:name屬性值與類中的成員變量名以及set方法的參數(shù)名都無關,只與對應的set方法名有關,下面的這種寫法是可以運行成功的

public class UserService implements IUserService {
  private IUserDao userDao1;
  
  public void setUserDao(IUserDao userDao1) {
    this.userDao1 = userDao1;
  }
  
  public void loginUser() {
    userDao1.loginUser();
  }
}

還有一點需要注意:如果通過set方法注入屬性,那么spring會通過默認的空參構造方法來實例化對象,所以如果在類中寫了一個帶有參數(shù)的構造方法,一定要把空參數(shù)的構造方法寫上,否則spring沒有辦法實例化對象,導致報錯。

3、基于注解,常用的有“@Autowried”和“@Resource”。

示例代碼

// candidateBeans 為上一步通過類型匹配到的多個bean,該 Map 中至少有兩個元素。
protected String determineAutowireCandidate(Map<String, Object> candidateBeans, DependencyDescriptor descriptor) {
    //  requiredType 為匹配到的接口的類型
   Class<?> requiredType = descriptor.getDependencyType();
   // 1. 先找 Bean 上有@Primary 注解的,有則直接返回
   String primaryCandidate = this.determinePrimaryCandidate(candidateBeans, requiredType);
   if (primaryCandidate != null) {
       return primaryCandidate;
   } else {
       // 2.再找 Bean 上有 @Order,@PriorityOrder 注解的,有則返回
       String priorityCandidate = this.determineHighestPriorityCandidate(candidateBeans, requiredType);
       if (priorityCandidate != null) {
           return priorityCandidate;
       } else {
           Iterator var6 = candidateBeans.entrySet().iterator();
           String candidateBeanName;
           Object beanInstance;
           do {
               if (!var6.hasNext()) {
                   return null;
               }
               // 3. 再找 bean 的名稱匹配的
               Entry<String, Object> entry = (Entry)var6.next();
               candidateBeanName = (String)entry.getKey();
               beanInstance = entry.getValue();
           } while(!this.resolvableDependencies.values().contains(beanInstance) && !this.matchesBeanName(candidateBeanName, descriptor.getDependencyName()));
           return candidateBeanName;
       }
   }
}

看完上述內容,你們掌握Spring注入的方法了嗎?如果還想學到更多技能或想了解更多相關內容,歡迎關注億速云行業(yè)資訊頻道,感謝各位的閱讀!

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經查實,將立刻刪除涉嫌侵權內容。

AI