首頁 >Java >java教程 >Spring 常用的三種注入方式

Spring 常用的三種注入方式

Guanhui
Guanhui原創
2020-06-02 11:08:155594瀏覽

Spring 常用的三種注入方式

Spring 常用的三種注入方式

#1、建構方法,採用反射的方式,透過建構方法來完成注入。

先簡單了解測試專案的結構,用maven建置的,四個套件:

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

  • dao:資料訪問,一個接口,兩個實作類別

  • service:服務層,一個接口,一個實作類,實作類別依賴IUserDao

  • test:測試包

在spring的設定檔中註冊UserService,將UserDaoJdbc透過constructor-arg標籤注入到UserService的某個有參數的建構方法

<!-- 注册userService -->
<bean id="userService" class="com.lyu.spring.service.impl.UserService">
  <constructor-arg ref="userDaoJdbc"></constructor-arg>
</bean>
<!-- 注册jdbc实现的dao -->
<bean id="userDaoJdbc" class="com.lyu.spring.dao.impl.UserDaoJdbc"></bean>

如果只有一個有參數的建構方法並且參數型別與注入的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實現的類別輸出的是:jdbc-登入成功,mybatis實現的類別輸出的是: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实现的dao -->
<bean id="userDaoMyBatis" class="com.lyu.spring.dao.impl.UserDaoMyBatis"></bean>

註:上面這兩種寫法都可以,spring會將name值的每個單字首字母轉換成大寫,然後再在前面拼接上"set"構成一個方法名稱,然後去對應的類別中查找該方法,透過反射呼叫,實現注入。

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

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

還有一點要注意:如果透過set方法注入屬性,那麼spring會透過預設的空參構造方法來實例化對象,所以如果在類別中寫了一個帶有參數的建構方法,一定要把空參數的建構方法寫上,否則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;
       }
   }
}

推薦教學:《Java教學

#

以上是Spring 常用的三種注入方式的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn