spring_ioc,DI
什么是IOC呢?
IOC(Inversion of Control),中文意思就是控制反轉,ioc并不是一種特定的編程語言,指的是一種編程思想,指的是將創建對象的操作權限交給容器(這里指的是spring容器),通過容器來創建對象和管理對象,簡單來說就是將原先的控制權由程序本身轉給容器(本篇主要指的是spring)
依賴注入依賴注入(Dependency Injection):依賴注入指的是在程序的運行過程中,當程序需要調用另一個對象協助時,不用在代碼中創建對象并進行調用,而是將創建過程與調用過程交給外部的容器來管理(spring),由外部容器創建后傳遞給層序
為什么會有依賴注入的存在?
一個稍微復雜一點的程序,其組成的類基本都是兩個或兩個以上了,這些類組成應用程序完成相關的業務邏輯。每個對象負責管理與自己相互協作的對象的引用,一個對象可能會引用多個對象,這就會導致高度的耦合和代碼的難以測試,編碼的基本準則是“低耦合,高內聚”
耦合具有兩面性:
1:緊密的耦合會導致代碼難以測試,難以復用,難以理解
2:一個程序要想完成特定的功能,一定程度的耦合又是必須的,不同的類之間必須進行一定的交互
依賴注入:通過依賴注入,對象的依賴關系將由負責協調系統中各個對象的第三方組件在創建對象時設定,對象無需自行創建或管理它們之間的依賴關系,也就是依賴關系將被注入到它們的依賴關系中去
實現依賴注入的兩種方式# 基于xml配置文件的依賴注入
setter方法
以下的例子相當于在一個類中使用另一個類中的方法
1:創建一個UserDao接口
package com.doaoao.dao; public interface UserDao {void addUser(); }2:創建UserDao接口的實現類
package com.doaoao.impl; import com.doaoao.dao.UserDao; public class UserDaoImpl implements UserDao {@Overridepublic void addUser() {System.out.println("添加用戶");} }3:創建UserService接口
package com.doaoao.dao; public interface UserService {void addUser(); }4:創建UserService的實現類(在Service中使用UserDao)
package com.doaoao.impl;import com.doaoao.dao.UserDao; import com.doaoao.dao.UserService;public class UserServiceImpl implements UserService {private UserDao userDao;@Overridepublic void addUser() {// 注:之前如果想使用UserDao的對象時,必須先創建該對象,如下 // UserDao userDao = new UserDaoImpl()// 使用spring 由spring為我們創建對象userDao.addUser(); // 調用UserDaoImpl中的實現方法 }// 要給UserDao添加getter和setter方法public UserDao getUserDao() {return userDao;}// spring容器在實現依賴注入時會調用set方法,將userDao對象注入給當前對象,也就是UserServiceImpl類的對象
public void setUserDao(UserDao userDao) { this.userDao = userDao; } }
5:修改配置文件中的內容(當Spring讀取配置文件時,會將userDao注入到對應的類中)
<bean id="userService" class="com.doaoao.impl.UserServiceImpl"><property name="userDao" ref="userDaoId" /><!-- ref的值為下方bean的id值 userDao與 private UserDao userDao中的userDao命名得一致-->
</bean> <bean id="userDaoId" class="com.doaoao.impl.UserDaoImpl" />
6:添加測試類
@Testpublic void Test02(){// 讀取spring配置文件ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");// 從配置文件中獲取對應id所對應的對象UserService userService = (UserService) context.getBean("userService");userService.addUser();}# 使用spring的依賴注入之后,spring容器會幫我們創建UserDaoImpl的對象,并通過setter方法注入到UserService中的userDao屬性上面
## 構造注入(容器通過構造方法將實例化的對象進行注入)
1:修改之前的UserServiceImpl,添加有參構造方法
package com.doaoao.impl; import com.doaoao.dao.UserDao; import com.doaoao.dao.UserService; public class UserServiceImpl implements UserService {private UserDao userDao;@Overridepublic void addUser() {// 注:之前如果想使用UserDao的對象時,必須先創建該對象,如下 // UserDao userDao = new UserDaoImpl()// 使用spring 由spring為我們創建對象userDao.addUser(); // 調用UserDaoImpl中的實現方法 }// 構造注入public UserServiceImpl(UserDao userDao) {this.userDao = userDao;} }?2:修改配置文件
<bean id="userService" class="com.doaoao.impl.UserServiceImpl"><constructor-arg name="userDao" ref="userDaoId" /> </bean> <bean id="userDaoId" class="com.doaoao.impl.UserDaoImpl" /><!-- userDao要與構造方法中的參數一致 UserDao userDao
userDaoId與下方的bean id要一致 -->
?
?
## 基于注解的依賴注入
@Controller -----> springmvc中的controller
@Repository ----> dao層
@Service ---------> service層
@Component --->可以代替上方三個
使用依賴注入,我們九不必再applicationContext.xml中注冊bean
1:在配置文件中添加文件掃描器(使用注解就得先加上文件掃描器,掃描對應的類)
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:aop="http://www.springframework.org/schema/aop"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsd"><!-- 注冊文件掃描器 --><context:component-scan base-package="com.doaoao" /> </beans>2:在類上使用注解 @Component,該注解中的參數用于指定該類的id
package com.doaoao.impl; import com.doaoao.dao.UserDao; import org.springframework.stereotype.Repository; @Component("userDao") public class UserDaoImpl implements UserDao {@Overridepublic void addUser() {System.out.println("執行了addUser");} }?在spring中提供類與@Component等效的注解
@Repository 用于對 DAO 實現類進行注解
@Service 用于對 Service 實現類進行注解
@Controller 用于對 Controller 實現類進行注解
?例如在dao層的 UserDaoImpl 中使用 @Repository 注解
package com.doaoao.impl; import com.doaoao.dao.UserDao; import org.springframework.stereotype.Repository; @Repository("userDao") public class UserDaoImpl implements UserDao {@Overridepublic void addUser() {System.out.println("執行了addUser");} }3:在service層的 UserServiceImpl 上使用 @Service
package com.doaoao.impl; import com.doaoao.dao.UserDao; import com.doaoao.dao.UserService; import org.springframework.stereotype.Service; @Service("userService") public class UserServiceImpl implements UserService {private UserDao userDao;@Overridepublic void addUser() {// 使用spring 由spring為我們創建對象userDao.addUser(); }// 構造注入public UserServiceImpl(UserDao userDao) {this.userDao = userDao;} }4:創建測試方法(與之前相同)
@Testpublic void Test02(){// 讀取spring配置文件ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");// 從配置文件中獲取對應id所對應的對象UserService userService = (UserService) context.getBean("userService");userService.addUser();}@Autowrite注解
加上該注解后,會按照類型進行裝配,上面的示例中通過UserServiceImpl的構造方法對UserDao的注入,我們可以將這個構造方法省略,我們可以在private UserDao userDao上添加@Autowired注解,該注解默認使用按類型自動裝配,即容器會查找UserDao類型的實例將其注入,spring容器會自動查找該對象
當使用@AUtowrite注解時,@Repository("userDao") 可以改寫成 @Repository,因為默認是根據類型進行注入的,會自動找到該類型所對應的對象
我么可以對其進行修改,讓其根據名稱進行注入,還可以使用 @Qualifier注解讓@Autowrite根據名稱自動裝配,
@Qualifier中的名稱要跟UserDaoImpl類中@Repository("userDao")的名稱一致,spring在查找對象時就會根據 userDao這個名字去查找
package com.doaoao.impl;import com.doaoao.dao.UserDao; import com.doaoao.dao.UserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Service;@Service("userService") public class UserServiceImpl implements UserService { @Autowired@Qualifier("userDao")private UserDao userDao;@Overridepublic void addUser() {userDao.addUser(); }// 無需構造方法 // public UserServiceImpl(UserDao userDao) { // this.userDao = userDao; // } }@Resource注解(該注解不是spring提供的,是java提供的注解)
該注解默認使用名字進行注解(來完成裝配的/注入的)當我們下方沒有寫名字時,就是使用類型進行裝配的(和 @Autowired)
可以按照名字進行裝配 @Resource(name = “userDao”),當指定名字時,名字得和@Repository("userDao") 一樣
@Service("userService") public class UserServiceImpl implements UserService {@Resourceprivate UserDao userDao;@Overridepublic void addUser() {userDao.addUser();} }下面另一種寫法利用類型進行bean的注入
@Service("userService") public class UserServiceImpl implements UserService {@Resource(type = "userDao")private UserDao userDao;@Overridepublic void addUser() {userDao.addUser();} }兩個區別:@Autowired是spring提供的,@Resource是java提供的,這兩種注解在實際開發中二選一即可
@Autowired默認根據類型進行裝配,@Resource默認使用名字進行裝配
?// 使用注解實現初始化和銷毀操作
@PostConstruct public void before() {System.out.println("開始"); }@PreDestroy public void after() {System.out.println("結束"); }?利用注解@Scope指定bean的作用域,默認的作用域為 singleton 單例模式
@Scope("prototype") @Repository("userDao") public class UserDaoImpl implements UserDao {@Overridepublic void addUser() {System.out.println("執行了方法 UserDaoImpl");} }## 注解和xml配置的利弊
注解的好處是,配置方便,直觀。但其弊端也顯而易見:以硬編碼的方式寫入到了 Java代碼中,其修改是需要重新編譯代碼的。
XML 配置方式的最大好處是,對其所做修改,無需編譯代碼,只需重啟服務器即可將新的配置加載。
若注解與 XML 同用,XML 的優先級要高于注解。這樣做的好處是,需要對某個 Bean 做修改,只需修改配置文件即可。當然,此時,Bean 類要有 setter 或構造器。
## 如何添加多個配置文件
隨著系統中的Bean的數量增加,會導致配置溫江變得及其的臃腫,會導致可維護性的降低,為了避免這種事情的發生,可以將Spring配置文件分解成多個配置文件
# 添加多個配置文件-方式1
// 在resource目錄下創建多個配置文件 spring-app.xml spring-bean.xml// 在測試方法中:將配置文件的文件名寫道數組中,然后將該數組作為參數傳入 ClassPathXmlApplicationContex String[] files = {"spring-aop.xml","spring-bean.xml","applicationContext.xml"}; ApplicationContext context = new ClassPathXmlApplicationContext(files);# 添加多個配置文件-方式2
選取一個主配置文件,例如選取 applicationContext.xml
在applicationContext.xml配置文件中加入如下的內容,這時就好比將 applicationContext.xml 配置文件變成一個父配置文件
<import resource="spring-aop.xml"/> <import resource="spring-bean.xml"/><!-- 另一種寫法,使用通配符的方式 --><!-- 當用通配符的方式寫的時候,主配置文件不以 "spring作為開頭" -->
<import rescorce="spring-*.xml">
?然后再測試代碼中使用即可
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");...
本筆記參考自:小猴子老師教程 http://www.monkey1024.com
轉載于:https://www.cnblogs.com/Doaoao/p/10740366.html
總結
以上是生活随笔為你收集整理的spring_ioc,DI的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 浅谈:Wi-Fi 6的优势及应用前景
- 下一篇: 手把手教你在Mac OS下载、编译及导入