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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

spring_ioc,DI

發(fā)布時間:2024/4/15 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 spring_ioc,DI 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
ioc簡介:

什么是IOC呢?

IOC(Inversion of Control),中文意思就是控制反轉(zhuǎn),ioc并不是一種特定的編程語言,指的是一種編程思想,指的是將創(chuàng)建對象的操作權(quán)限交給容器(這里指的是spring容器),通過容器來創(chuàng)建對象和管理對象,簡單來說就是將原先的控制權(quán)由程序本身轉(zhuǎn)給容器(本篇主要指的是spring)

依賴注入

依賴注入(Dependency Injection):依賴注入指的是在程序的運行過程中,當(dāng)程序需要調(diào)用另一個對象協(xié)助時,不用在代碼中創(chuàng)建對象并進行調(diào)用,而是將創(chuàng)建過程與調(diào)用過程交給外部的容器來管理(spring),由外部容器創(chuàng)建后傳遞給層序

為什么會有依賴注入的存在?

一個稍微復(fù)雜一點的程序,其組成的類基本都是兩個或兩個以上了,這些類組成應(yīng)用程序完成相關(guān)的業(yè)務(wù)邏輯。每個對象負責(zé)管理與自己相互協(xié)作的對象的引用,一個對象可能會引用多個對象,這就會導(dǎo)致高度的耦合和代碼的難以測試,編碼的基本準則是“低耦合,高內(nèi)聚”

耦合具有兩面性:

1:緊密的耦合會導(dǎo)致代碼難以測試,難以復(fù)用,難以理解

2:一個程序要想完成特定的功能,一定程度的耦合又是必須的,不同的類之間必須進行一定的交互

依賴注入:通過依賴注入,對象的依賴關(guān)系將由負責(zé)協(xié)調(diào)系統(tǒng)中各個對象的第三方組件在創(chuàng)建對象時設(shè)定,對象無需自行創(chuàng)建或管理它們之間的依賴關(guān)系,也就是依賴關(guān)系將被注入到它們的依賴關(guān)系中去

實現(xiàn)依賴注入的兩種方式

# 基于xml配置文件的依賴注入

setter方法

以下的例子相當(dāng)于在一個類中使用另一個類中的方法

1:創(chuàng)建一個UserDao接口

package com.doaoao.dao; public interface UserDao {void addUser(); }

2:創(chuàng)建UserDao接口的實現(xiàn)類

package com.doaoao.impl; import com.doaoao.dao.UserDao; public class UserDaoImpl implements UserDao {@Overridepublic void addUser() {System.out.println("添加用戶");} }

3:創(chuàng)建UserService接口

package com.doaoao.dao; public interface UserService {void addUser(); }

4:創(chuàng)建UserService的實現(xiàn)類(在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的對象時,必須先創(chuàng)建該對象,如下 // UserDao userDao = new UserDaoImpl()// 使用spring 由spring為我們創(chuàng)建對象userDao.addUser(); // 調(diào)用UserDaoImpl中的實現(xiàn)方法 }

  // 要給UserDao添加getter和setter方法
public UserDao getUserDao() {return userDao;}// spring容器在實現(xiàn)依賴注入時會調(diào)用set方法,將userDao對象注入給當(dāng)前對象,也就是UserServiceImpl類的對象
  public void setUserDao(UserDao userDao) { this.userDao = userDao; } }

5:修改配置文件中的內(nèi)容(當(dāng)Spring讀取配置文件時,會將userDao注入到對應(yīng)的類中)

<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");// 從配置文件中獲取對應(yīng)id所對應(yīng)的對象UserService userService = (UserService) context.getBean("userService");userService.addUser();}

# 使用spring的依賴注入之后,spring容器會幫我們創(chuàng)建UserDaoImpl的對象,并通過setter方法注入到UserService中的userDao屬性上面

## 構(gòu)造注入(容器通過構(gòu)造方法將實例化的對象進行注入)

1:修改之前的UserServiceImpl,添加有參構(gòu)造方法

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的對象時,必須先創(chuàng)建該對象,如下 // UserDao userDao = new UserDaoImpl()// 使用spring 由spring為我們創(chuàng)建對象userDao.addUser(); // 調(diào)用UserDaoImpl中的實現(xiàn)方法 }// 構(gòu)造注入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要與構(gòu)造方法中的參數(shù)一致 UserDao userDao
userDaoId與下方的bean id要一致 -->

?


?

## 基于注解的依賴注入

  @Controller -----> springmvc中的controller

  @Repository ----> dao層

  @Service ---------> service層

  @Component --->可以代替上方三個

使用依賴注入,我們九不必再applicationContext.xml中注冊bean

1:在配置文件中添加文件掃描器(使用注解就得先加上文件掃描器,掃描對應(yīng)的類)

<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,該注解中的參數(shù)用于指定該類的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("執(zhí)行了addUser");} }

?在spring中提供類與@Component等效的注解

  @Repository 用于對 DAO 實現(xiàn)類進行注解
  @Service 用于對 Service 實現(xiàn)類進行注解
  @Controller 用于對 Controller 實現(xiàn)類進行注解

?例如在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("執(zhí)行了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為我們創(chuàng)建對象userDao.addUser(); }// 構(gòu)造注入public UserServiceImpl(UserDao userDao) {this.userDao = userDao;} }

4:創(chuàng)建測試方法(與之前相同)

@Testpublic void Test02(){// 讀取spring配置文件ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");// 從配置文件中獲取對應(yīng)id所對應(yīng)的對象UserService userService = (UserService) context.getBean("userService");userService.addUser();}

@Autowrite注解

加上該注解后,會按照類型進行裝配,上面的示例中通過UserServiceImpl的構(gòu)造方法對UserDao的注入,我們可以將這個構(gòu)造方法省略,我們可以在private UserDao userDao上添加@Autowired注解,該注解默認使用按類型自動裝配,即容器會查找UserDao類型的實例將其注入,spring容器會自動查找該對象

當(dāng)使用@AUtowrite注解時,@Repository("userDao") 可以改寫成 @Repository,因為默認是根據(jù)類型進行注入的,會自動找到該類型所對應(yīng)的對象

我么可以對其進行修改,讓其根據(jù)名稱進行注入,還可以使用 @Qualifier注解讓@Autowrite根據(jù)名稱自動裝配,

@Qualifier中的名稱要跟UserDaoImpl類中@Repository("userDao")的名稱一致,spring在查找對象時就會根據(jù) 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(); }// 無需構(gòu)造方法 // public UserServiceImpl(UserDao userDao) { // this.userDao = userDao; // } }

@Resource注解(該注解不是spring提供的,是java提供的注解)

該注解默認使用名字進行注解(來完成裝配的/注入的)當(dāng)我們下方?jīng)]有寫名字時,就是使用類型進行裝配的(和 @Autowired)

可以按照名字進行裝配 @Resource(name = “userDao”),當(dāng)指定名字時,名字得和@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();} }

兩個區(qū)別:@Autowired是spring提供的,@Resource是java提供的,這兩種注解在實際開發(fā)中二選一即可

@Autowired默認根據(jù)類型進行裝配,@Resource默認使用名字進行裝配

?// 使用注解實現(xiàn)初始化和銷毀操作

@PostConstruct public void before() {System.out.println("開始"); }@PreDestroy public void after() {System.out.println("結(jié)束"); }

?利用注解@Scope指定bean的作用域,默認的作用域為 singleton 單例模式

@Scope("prototype") @Repository("userDao") public class UserDaoImpl implements UserDao {@Overridepublic void addUser() {System.out.println("執(zhí)行了方法 UserDaoImpl");} }

## 注解和xml配置的利弊

注解的好處是,配置方便,直觀。但其弊端也顯而易見:以硬編碼的方式寫入到了 Java代碼中,其修改是需要重新編譯代碼的。

XML 配置方式的最大好處是,對其所做修改,無需編譯代碼,只需重啟服務(wù)器即可將新的配置加載。

若注解與 XML 同用,XML 的優(yōu)先級要高于注解。這樣做的好處是,需要對某個 Bean 做修改,只需修改配置文件即可。當(dāng)然,此時,Bean 類要有 setter 或構(gòu)造器。

## 如何添加多個配置文件

隨著系統(tǒng)中的Bean的數(shù)量增加,會導(dǎo)致配置溫江變得及其的臃腫,會導(dǎo)致可維護性的降低,為了避免這種事情的發(fā)生,可以將Spring配置文件分解成多個配置文件

# 添加多個配置文件-方式1

// 在resource目錄下創(chuàng)建多個配置文件 spring-app.xml spring-bean.xml// 在測試方法中:將配置文件的文件名寫道數(shù)組中,然后將該數(shù)組作為參數(shù)傳入 ClassPathXmlApplicationContex String[] files = {"spring-aop.xml","spring-bean.xml","applicationContext.xml"}; ApplicationContext context = new ClassPathXmlApplicationContext(files);

# 添加多個配置文件-方式2

選取一個主配置文件,例如選取 applicationContext.xml

在applicationContext.xml配置文件中加入如下的內(nèi)容,這時就好比將 applicationContext.xml 配置文件變成一個父配置文件

<import resource="spring-aop.xml"/> <import resource="spring-bean.xml"/><!-- 另一種寫法,使用通配符的方式 -->
<!-- 當(dāng)用通配符的方式寫的時候,主配置文件不以 "spring作為開頭" -->
<import rescorce="spring-*.xml">

?然后再測試代碼中使用即可

ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");

...

本筆記參考自:小猴子老師教程 http://www.monkey1024.com

轉(zhuǎn)載于:https://www.cnblogs.com/Doaoao/p/10740366.html

總結(jié)

以上是生活随笔為你收集整理的spring_ioc,DI的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。