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中文網其他相關文章!