日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

Spring【依赖注入】就是这么简单

發布時間:2025/7/14 javascript 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Spring【依赖注入】就是这么简单 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前言

在Spring的第二篇中主要講解了Spring Core模塊的使用IOC容器創建對象的問題,Spring Core模塊主要是解決對象的創建和對象之間的依賴關系,因此本博文主要講解如何使用IOC容器來解決對象之間的依賴關系

回顧以前對象依賴

我們來看一下我們以前關于對象依賴,是怎么的歷程

直接new對象

  • 在最開始,我們是直接new對象給serice的userDao屬性賦值...
class UserService{UserDao userDao = new UserDao(); }

寫DaoFactory,用字符串來維護依賴關系

  • 后來,我們發現service層緊緊耦合了dao層。我們就寫了DaoFactory,在service層只要通過字符串就能夠創建對應的dao層的對象了。

  • DaoFactory

public class DaoFactory {private static final DaoFactory factory = new DaoFactory();private DaoFactory(){}public static DaoFactory getInstance(){return factory;}public <T> T createDao(String className,Class<T> clazz){try{T t = (T) Class.forName(className).newInstance();return t;}catch (Exception e) {throw new RuntimeException(e);}}}
  • serivce
private CategoryDao categoryDao = DaoFactory.getInstance().createDao("zhongfucheng.dao.impl.CategoryDAOImpl", CategoryDao.class);private BookDao bookDao = DaoFactory.getInstance().createDao("zhongfucheng.dao.impl.BookDaoImpl", BookDao.class);private UserDao userDao = DaoFactory.getInstance().createDao("zhongfucheng.dao.impl.UserDaoImpl", UserDao.class);private OrderDao orderDao = DaoFactory.getInstance().createDao("zhongfucheng.dao.impl.OrderDaoImpl", OrderDao.class);

DaoFactory讀取配置文件

  • 再后來,我們發現要修改Dao的實現類,還是得修改service層的源代碼呀..于是我們就在DaoFactory中讀取關于daoImpl的配置文件,根據配置文件來創建對象,這樣一來,創建的是哪個daoImpl對service層就是透明的

  • DaoFactory
    ```java

public class DaoFactory {

private UserDao userdao = null;private DaoFactory(){try{InputStream in = DaoFactory.class.getClassLoader().getResourceAsStream("dao.properties");Properties prop = new Properties();prop.load(in);String daoClassName = prop.getProperty("userdao");userdao = (UserDao)Class.forName(daoClassName).newInstance();}catch (Exception e) {throw new RuntimeException(e);} }private static final DaoFactory instance = new DaoFactory();public static DaoFactory getInstance(){return instance; }public UserDao createUserDao(){return userdao; }

}

```

  • service
UserDao dao = DaoFactory.getInstance().createUserDao();

Spring依賴注入

通過上面的歷程,我們可以清晰地發現:對象之間的依賴關系,其實就是給對象上的屬性賦值!因為對象上有其他對象的變量,因此存在了依賴...

Spring提供了好幾種的方式來給屬性賦值

  • 1) 通過構造函數
  • 2) 通過set方法給屬性注入值
  • 3) p名稱空間
  • 4)自動裝配(了解)
  • 5) 注解

搭建測試環境

  • UserService中使用userDao變量來維護與Dao層之間的依賴關系
  • UserAction中使用userService變量來維護與Service層之間的依賴關系

  • userDao

public class UserDao {public void save() {System.out.println("DB:保存用戶");} }
  • userService
public class UserService {private UserDao userDao; public void save() {userDao.save();} }
  • userAnction
public class UserAction {private UserService userService;public String execute() {userService.save();return null;} }

構造函數給屬性賦值

其實我們在講解創建帶參數的構造函數的時候已經講過了...我們還是來回顧一下唄..

我們測試service和dao的依賴關系就好了....在serice中加入一個構造函數,參數就是userDao

public UserService(UserDao userDao) {this.userDao = userDao;//看看有沒有拿到userDaoSystem.out.println(userDao);}

applicationContext.xml配置文件

<!--創建userDao對象--><bean id="userDao" class="UserDao"/><!--創建userService對象--><bean id="userService" class="UserService"><!--要想在userService層中能夠引用到userDao,就必須先創建userDao對象--><constructor-arg index="0" name="userDao" type="UserDao" ref="userDao"></constructor-arg></bean>
  • 測試:可以成功獲取到userDao對象
// 創建容器對象ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");//得到service對象UserService userService = (UserService) ac.getBean("userService");


通過set方法給屬性注入值

我們這里也是測試service和dao層的依賴關系就好了...在service層通過set方法來把userDao注入到UserService中

  • 為UserService添加set方法
public class UserService {private UserDao userDao;public void setUserDao(UserDao userDao) {this.userDao = userDao;//看看有沒有拿到userDaoSystem.out.println(userDao);}public void save() {userDao.save();} }

applicationContext.xml配置文件:通過property節點來給屬性賦值

  • 引用類型使用ref屬性
  • 基本類型使用value屬性
<!--創建userDao對象--><bean id="userDao" class="UserDao"/><!--創建userService對象--><bean id="userService" class="UserService"><property name="userDao" ref="userDao"/></bean>
  • 測試:


內部Bean

我們剛才是先創建userDao對象,再由userService對userDao對象進行引用...我們還有另一種思維:先創建userService,發現userService需要userDao的屬性,再創建userDao...我們來看看這種思維方式是怎么配置的:

applicationContext.xml配置文件:property節點內置bean節點

<!-- 1.創建userService,看到有userDao這個屬性 2.而userDao這個屬性又是一個對象 3.在property屬性下又內置了一個bean 4.創建userDao --><bean id="userService" class="UserService"><property name="userDao"><bean id="userDao" class="UserDao"/></property></bean>
  • 測試

我們發現這種思維方式和服務器訪問的執行順序是一樣的,但是如果userDao要多次被其他service使用的話,就要多次配置了...

p 名稱空間注入屬性值

p名稱控件這種方式其實就是set方法的一種優化,優化了配置而已...p名稱空間這個內容需要在Spring3版本以上才能使用...我們來看看:

applicationContext.xml配置文件:使用p名稱空間

<bean id="userDao" class="UserDao"/><!--不用寫property節點了,直接使用p名稱空間--><bean id="userService" class="UserService" p:userDao-ref="userDao"/>
  • 測試


自動裝配

Spring還提供了自動裝配的功能,能夠非常簡化我們的配置

自動裝載默認是不打開的,自動裝配常用的可分為兩種:

  • 根據名字來裝配
  • 根據類型類裝配

XML配置根據名字

applicationContext.xml配置文件:使用自動裝配,根據名字

<bean id="userDao" class="UserDao"/><!-- 1.通過名字來自動裝配 2.發現userService中有個叫userDao的屬性 3.看看IOC容器中沒有叫userDao的對象 4.如果有,就裝配進去 --><bean id="userService" class="UserService" autowire="byName"/>
  • 測試


XML配置根據類型

applicationContext.xml配置文件:使用自動裝配,根據類型

值得注意的是:如果使用了根據類型來自動裝配,那么在IOC容器中只能有一個這樣的類型,否則就會報錯!

<bean id="userDao" class="UserDao"/><!-- 1.通過名字來自動裝配 2.發現userService中有個叫userDao的屬性 3.看看IOC容器UserDao類型的對象 4.如果有,就裝配進去 --><bean id="userService" class="UserService" autowire="byType"/>
  • 測試:


我們這只是測試兩個對象之間的依賴關系,如果我們有很多對象,我們也可以使用默認自動分配


使用注解來實現自動裝配

@Autowired注解來實現自動裝配:

  • 可以在構造器上修飾
  • 也可以在setter方法上修飾
  • **來自java的@Inject的和@AutoWired有相同的功能**

如果沒有匹配到bean,又為了避免異常的出現,我們可以使用required屬性上設置為false。【謹慎對待】

  • 測試代碼

    @Component public class UserService {private UserDao userDao ;@Autowired public void setUserDao(UserDao userDao) {this.userDao = userDao; } }

順利拿到userDao的引用

使用JavaConfig配置類實現對象依賴

  • 第一種(測試不出來)
import org.springframework.context.annotation.Bean;@org.springframework.context.annotation.Configuration public class Configuration {@Bean()public UserDao userDao() {return new UserDao();}@Beanpublic UserService userService() {//直接調用@bean的方法return new UserService(userDao());}}
  • 第二種(測試不出來)
import org.springframework.context.annotation.Bean;@org.springframework.context.annotation.Configuration public class Configuration {@Bean()public UserDao userDao() {return new UserDao();}@Beanpublic UserService userService(UserDao userDao) {//通過構造函數依賴注入return new UserService(userDao);}}


  • 如果我直接通過構造器傳入的話,那么報錯了
import org.springframework.beans.factory.annotation.Autowire; import org.springframework.context.annotation.Bean;@org.springframework.context.annotation.Configuration public class Configuration {@Bean()public UserDao userDao() {return new UserDao();}@Bean(autowire = Autowire.BY_TYPE)public UserService userService(UserDao userDao) {return new UserService(userDao);}}


  • 我測試中只有通過這種方法才能拿到userDao的引用。
public class Configuration {@Bean()public UserDao userDao() {return new UserDao();}@Bean(autowire = Autowire.BY_TYPE)public UserService userService() {return new UserService(userDao());}}


當然了,最簡單直觀的方法還有一種:在UserService中加入setUser()方法,那么只要set進去就行了..

  • UserService
public class UserService {private UserDao userDao ;public UserService() {}public UserService(UserDao userDao) {}public void setUserDao(UserDao userDao) {this.userDao = userDao;} }
  • Config
import org.springframework.context.annotation.Bean;@org.springframework.context.annotation.Configuration public class Config1 {@Bean(name = "userDao")public UserDao userDao() {return new UserDao();}@Bean(name="userService")public UserService userService() {UserService userService = new UserService();userService.setUserDao(userDao());return userService;}}


最后

擴展閱讀:

  • https://zhuanlan.zhihu.com/p/29426019

如果文章有錯的地方歡迎指正,大家互相交流。習慣在微信看技術文章,想要獲取更多的Java資源的同學,可以關注微信公眾號:Java3y

更多的文章可往:文章的目錄導航

總結

以上是生活随笔為你收集整理的Spring【依赖注入】就是这么简单的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。