摘要:構造函數方法進行依賴注入注入的效率最高新建方法電源供電中。。。。。無參數構造函數選創建有參的構造函數有參數構造函數多參數構造函數。。。。
一、Spring基礎 1.Spring簡介 1.1 核心概念
序號 | 概念 | 全稱 | 具體內容 |
---|---|---|---|
1 | IoC | Inversion of Control (控制反轉) | 對象創建和對象關系管理權限,由開發者轉為spring |
2 | DI | Dependency Injection(依賴注入) | 對象的依賴關系的創建過程 |
3 | AOP | Aspect Oriented Programming(面向切面編程) |
功能模塊組成:
模塊 | 功能 | 備注 |
---|---|---|
Core | IoC,DI 功能實現最基本實現 | 核心模塊 |
Beans | Bean工廠(創建對象的工廠) | 核心模塊 |
Context | IoC容器,上下文 | 核心模塊 |
SpEL | spring 表達式語言 | 核心模塊 |
JDBC | JDBC封裝 | 數據訪問集成模塊 |
ORM | 數據集成框架封裝,jpa jdo | 數據訪問集成模塊 |
OXM | 實現對象和xml轉換 | 數據訪問集成模塊 |
JMS | 生產消費實現 | 數據訪問集成模塊 |
Transactions | 事務管理 | 數據訪問集成模塊 |
web | web監聽,初始化ioc容器,上傳等 | web模塊 |
webSocket | webSocket開發 | web模塊 |
Servlet | spring MVC | web模塊 |
Portlet | 內容集成 聚合 | web模塊 |
AOP | AOP相關 | |
Aspects | Aspects面向切面編程 | |
Instrumentation | 設備相關 | |
Messaging | 消息相關 | |
Test | 測試模塊 |
spring 包含spring MVC
1.2 相關參數解析名稱 | 用途 | 備注 | 類型 |
---|---|---|---|
private | 聲明成員變量 | ||
有參的構造函數 | 關聯成員變量和無參構造函數的關系 | ||
public void play() | 構造一個方法play,執行具體邏輯 | ||
@Autowired | 自動滿足bean之間的依賴 | 自動裝配,自動注入注解 | 定義組件 |
@Transactional | @Transactional 可以作用于接口、接口方法、類以及類方法上。當作用于類上時,該類的所有 public 方法將都具有該類型的事務屬性,同時,我們也可以在方法級別使用該標注來覆蓋類級別的定義。 但是 Spring 建議不要在接口或者接口方法上使用該注解,因為這只有在使用基于接口的代理時它才會生效。另外, @Transactional 注解應該只被應用到 public 方法上 | 事務管理 | |
@Component | 表示這個累需要在應用程序中被創建,被掃描 | 被spring上下文發現,自動發現注解 | 定義組件 |
@ComponentScanTransactional | 自動發現應用程序中創建的類 | 自動掃描Component類 | 定義配置 |
@Configuration | 表示當前類是一個配置類 | 標注類為配置類 | 定義配置 |
@Test | 表示當前類是一個測試類 | ||
@RunWith(SpringJUnit4ClassRunner.class) | 引入Spring單元測試模塊 | 聲明使用SpringJUnit4ClassRunner.class 測試單元 | spring測試環境 |
@ContextConfiguration(classes = AppConfig.class) | 加載配置類 | spring測試環境 | |
@Primary | 首選bean | 設置實現類的首選 | 自動裝配歧義性 |
@Qualifier | 給bean做注解 | 調用的時候可以通過注解區分實現類 | 自動裝配歧義性 |
@Resource | @Resource 相當于@Autowired + @Qualifier("userServiceNormal") | java標準 | 自動裝配歧義性 |
@Repository | 標注數據dao實現類 | 本質和@Component沒有區別,只是更加明確 | 分層架構中定義組件 |
@Service | 標注Service實現類 | 本質和@Component沒有區別,只是更加明確 | 分層架構中定義組件 |
@Controller | 標注web、controller實現類, API接口 | 本質和@Component沒有區別,只是更加明確 | 分層架構中定義組件 |
@Bean | 當前配置類為默認配置類,自動調用 | ||
@Override | 重寫,重載 | 自雷重寫父類的方法 | |
@RequestMapping | 是一個用來處理請求地址映射的注解,可用于類或方法上。用于類上,表示類中的所有響應請求的方法都是以該地址作為父路徑。 | 配置url映射 | |
@RestController | 是@ResponseBody和@Controller的組合注解 | ||
Extends-繼承類 | 全盤繼承 | 在類的聲明中,通過關鍵字extends來創建一個類的子類。 | 對于class而言,Extends用于(單)繼承一個類(class) |
implements-實現接口 | 給這個類附加額外的功能 | 實現接口就是在接口中定義了方法,這個方法要你自己去實現,接口可以看作一個標準,比如定義了一個動物的接口,它里面有吃(eat())這個方法,你就可以實現這個方法implements,這個方法是自己寫,可以是吃蘋果,吃梨子,香蕉,或者其他的。implements就是具體實現這個接口 | implements用于實現一個接口(interface) |
DAO | DAO是傳統MVC中Model的關鍵角色,全稱是Data Access Object。DAO直接負責數據庫的存取工作,乍一看兩者非常類似,但從架構設計上講兩者有著本質的區別: | DAO則沒有擺脫數據的影子,仍然停留在數據操作的層面上,DAO則是相對數據庫而言 | |
Repository | Repository蘊含著真正的OO概念,即一個數據倉庫角色,負責所有對象的持久化管理。 | Repository是相對對象而言, | https://segmentfault.com/a/11... |
接口:
接口一般是只有方法聲明沒有定義的。
接口可以比作協議,比如我說一個協議是“殺人”那么這個接口你可以用 砍刀去實現,至于怎么殺砍刀可以去實現,當然你也可以用搶來實現殺人接口,但是你不能用殺人接口去殺人,因為殺人接口只不過是個功能說明,是個協議,具體怎么干,還要看他的實現類。那么一個包里面如果有接口,你可以不實現。這個不影響你使用其他類。
1.3 for 循環this.tracks.for + Enter 可以快速得到for循環
for (String track : this.tracks) { System.out.println("音樂:" + track); }2.Component對象
2.1 創建maven項目
2.2 創建基礎目錄
2.3 配置pom.xml
4.0.0 com.xfedu spring01 1.0-SNAPSHOT org.springframework spring-context 4.3.13.RELEASE
2.4 編寫純java版本代碼
編寫MessagesService
package hello; public class MessagesService { /** * 執行打印功能 * @return返回要打印的字符串 */ public String getMessage(){ return "hello world!"; } }
編寫MessagePrinter
package hello; public class MessagePrinter { /** * private 建立MessagePrinter 和 MessagesService 關聯關系 */ private MessagesService service; /** * service setter 方法 選擇service 按住alt+insert 選擇setter * 設置service的值 * @param service */ public void setService(MessagesService service) { this.service = service; } public void printMessage(){ System.out.println(this.service.getMessage()); } }
編寫Application
package hello; /** * 創建Application來調用MessagePrinter類 */ public class Application { public static void main(String[] args) { System.out.println("application"); //創建打印機對象 MessagePrinter printer = new MessagePrinter(); //創建消息服務對象 MessagesService service = new MessagesService(); //設置打印機的service屬性 printer.setService(service); //打印消息 printer.printMessage(); } }
2.5 編寫spring 框架版本代碼
編寫MessagesService
package hello; import org.springframework.stereotype.Component; /** * @Component通知spring容器, * 應用程序的對象(MessagesService)未來會通過spring容器自動創建出來 * 不需要程序員通過new關鍵字來創建 */ @Component public class MessagesService { /** * ctrl+o 創建無參構造的方法(object) * */ public MessagesService() { super(); System.out.println("MessageServer...."); } /** * 執行打印功能 * @return返回要打印的字符串 */ public String getMessage(){ return "hello world!"; } }
編寫MessagePrinter
package hello; import org.springframework.stereotype.Component; /** * @Component通知spring容器, * 應用程序的對象(MessagePrinter)未來會通過spring容器自動創建出來 * 不需要程序員通過new關鍵字來創建 */ @Component public class MessagePrinter { /** * ctrl+o 創建無參構造的方法(object) * */ public MessagePrinter() { super(); System.out.println("MessagePrinter"); } /** * private 建立MessagePrinter 和 MessagesService 關聯關系 */ private MessagesService service; /** * service setter 方法 選擇service 按住alt+insert 選擇setter * 設置service的值 * @param service */ public void setService(MessagesService service) { this.service = service; } public void printMessage(){ System.out.println(this.service.getMessage()); } }
編寫ApplicationSpring
package hello; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.ComponentScan; /** * 創建Application來調用MessagePrinter類 * @ComponentScan 掃描@Component注解的類 */ @ComponentScan public class ApplicationSpring { public static void main(String[] args) { System.out.println("application"); // // //創建打印機對象 // MessagePrinter printer = new MessagePrinter(); // //創建消息服務對象 // MessagesService service = new MessagesService(); // //設置打印機的service屬性 // printer.setService(service); // // //打印消息 // printer.printMessage(); //初始化Spring容器 ApplicationContext context = new AnnotationConfigApplicationContext(ApplicationSpring.class); } }
優點:通過 * @ComponentScan 掃描@Component注解的類,創建對象的時候就可以不用重新new
3.對象裝配注入Bean 3.1 Bena裝配(注入)的三種方式 3.1.1 隱式的bean發現機制和自動裝配(主流)package hello; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.ComponentScan; /** * 創建Application來調用MessagePrinter類 * @ComponentScan 掃描@Component注解的類 */ @ComponentScan public class ApplicationSpring { public static void main(String[] args) { System.out.println("application"); // // //創建打印機對象 // MessagePrinter printer = new MessagePrinter(); // //創建消息服務對象 // MessagesService service = new MessagesService(); // //設置打印機的service屬性 // printer.setService(service); // // //打印消息 // printer.printMessage(); //初始化Spring容器 ApplicationContext context = new AnnotationConfigApplicationContext(ApplicationSpring.class); //從容器中獲取MessagePrinter對象 MessagePrinter printer = context.getBean(MessagePrinter.class); //從容器中獲取MessagesService對象 MessagesService service = context.getBean(MessagesService.class); System.out.println(printer); System.out.println(service); //設置打印機的service屬性,printer和service 建立關聯關系 printer.setService(service); //打印消息調用printMessage打印 printer.printMessage(); } }
從Context中獲取class
ApplicationContext context = new AnnotationConfigApplicationContext(ApplicationSpring.class);
如何在對象中獲取對象
//從容器中獲取MessagePrinter對象,使用context.getBean方法 MessagePrinter printer = context.getBean(MessagePrinter.class);
如何建立對象的關聯關系
//設置打印機的service屬性,printer和service 建立關聯關系 printer.setService(service);
1.定義CompactDisc類,
內置CompactDisc無參構造函數
paly方法
用@Component包裝
2.定義CDPlayer
內置CDPlayer無參數構造函數
聲明CompactDisc
構建有參構造函數關聯CDPlayer和CompactDisc,利用@Autowired進行關聯自動管理
定義play方法
3.定義執行main函數
先通過AnnotationConfigApplicationContext 查出類
執行paly方法
利用@ComponentScan包裝,進行自動組件掃描
4.解耦組件掃描和主類
將注解和主類解耦,多帶帶新建配置類AppConfig
CompactDisc
package soundsystem; import org.springframework.stereotype.Component; @Component public class CompactDisc { public CompactDisc() { super(); System.out.println("CompactDisc無參構造函數"); } public void play(){ System.out.println("正在播放音樂......"); } }
CDPlayer
package soundsystem; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; /** * Component 讓他能被spring上下文發現 */ @Component public class CDPlayer { /** *private 成員變量 */ private CompactDisc cd; public CDPlayer() { super(); System.out.println("CDPlayer無參數構造函數"); } /** * Ctrl + Insert 選(Constructor)創建有參的構造函數 * @param */ @Autowired public CDPlayer(CompactDisc cd) { this.cd = cd; System.out.println("CDPlayer有參數構造函數"); } /** * 定義一個方法play,執行cd.play()播放工作 */ public void play(){ cd.play(); } }
App
package soundsystem; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.ComponentScan; @ComponentScan public class App { public static void main(String[] args) { ApplicationContext context = new AnnotationConfigApplicationContext(App.class); CDPlayer player = context.getBean(CDPlayer.class); player.play(); } }
將注解和主類解耦,多帶帶新建配置類AppConfig
AppConfig
這里就配置類掃描@ComponentScan 和@Configuration 注解
package soundsystem; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; /** * 這就是一個配置類 */ @Configuration @ComponentScan public class AppConfig { public AppConfig() { super(); System.out.println("配置類,用于將注解和主類解耦"); } }
App
這里就將@ComponentScan注解取消了
package soundsystem; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext; public class App { public static void main(String[] args) { ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class); CDPlayer player = context.getBean(CDPlayer.class); player.play(); } }3.1.2 在XML進行顯示
applicationContext.xml
MessagePrinter
package hello; /** * @Component通知spring容器, * 應用程序的對象(MessagePrinter)未來會通過spring容器自動創建出來 * 不需要程序員通過new關鍵字來創建 */ public class MessagePrinter { /** * ctrl+o 創建無參構造的方法(object) * */ public MessagePrinter() { super(); System.out.println("MessagePrinter"); } /** * private 建立MessagePrinter 和 MessagesService 關聯關系 */ private MessagesService service; /** * service setter 方法 選擇service 按住alt+insert 選擇setter * 設置service的值 * @param service */ public void setService(MessagesService service) { this.service = service; } public void printMessage(){ System.out.println(this.service.getMessage()); } }
MessagesService
package hello; /** * @Component通知spring容器, * 應用程序的對象(MessagesService)未來會通過spring容器自動創建出來 * 不需要程序員通過new關鍵字來創建 */ public class MessagesService { /** * ctrl+o 創建無參構造的方法(object) * */ public MessagesService() { super(); System.out.println("MessageServer...."); } /** * 執行打印功能 * @return返回要打印的字符串 */ public String getMessage(){ return "hello world!"; } }
ApplicationSpring
package hello; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; /** * 創建Application來調用MessagePrinter類 * @ComponentScan 掃描@Component注解的類 */ public class ApplicationSpring { public static void main(String[] args) { System.out.println("application"); //初始化Spring容器 ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); //從容器中獲取MessagePrinter對象 MessagePrinter printer = context.getBean(MessagePrinter.class); //打印消息調用printMessage打印 printer.printMessage(); } }
聲明使用xml文件
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
3.1.3 在java中進行顯示 3.2 Autowired 使用場景用于管理對象之間的關聯關系
3.2.1 簡單的依賴注入例子MessagePrinter
package hello; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; /** * @Component通知spring容器, * 應用程序的對象(MessagePrinter)未來會通過spring容器自動創建出來 * 不需要程序員通過new關鍵字來創建 */ @Component public class MessagePrinter { /** * ctrl+o 創建無參構造的方法(object) * */ public MessagePrinter() { super(); System.out.println("MessagePrinter"); } /** * private 建立MessagePrinter 和 MessagesService 關聯關系 */ private MessagesService service; /** * service setter 方法 選擇service 按住alt+insert 選擇setter * 設置service的值 * @param service * @Autowired 用于spring管理對象之間的關聯關系 */ @Autowired public void setService(MessagesService service) { this.service = service; } public void printMessage(){ System.out.println(this.service.getMessage()); } }
ApplicationSpring
package hello; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.ComponentScan; /** * 創建Application來調用MessagePrinter類 * @ComponentScan 掃描@Component注解的類 */ @ComponentScan public class ApplicationSpring { public static void main(String[] args) { System.out.println("application"); // // //創建打印機對象 // MessagePrinter printer = new MessagePrinter(); // //創建消息服務對象 // MessagesService service = new MessagesService(); // //設置打印機的service屬性 // printer.setService(service); // // //打印消息 // printer.printMessage(); //初始化Spring容器 ApplicationContext context = new AnnotationConfigApplicationContext(ApplicationSpring.class); //從容器中獲取MessagePrinter對象 MessagePrinter printer = context.getBean(MessagePrinter.class); //從容器中獲取MessagesService對象 //MessagesService service = context.getBean(MessagesService.class); //System.out.println(printer); //System.out.println(service); //設置打印機的service屬性,printer和service 建立關聯關系 //printer.setService(service); //打印消息調用printMessage打印 printer.printMessage(); } }
注解:使用@Autowired管理對象之間的關聯關系,這樣就可以自動處理關聯關系。
3.2.2 構造函數方法進行依賴注入注入的效率最高
Power 新建power方法
package soundsystem; import org.springframework.stereotype.Component; @Component public class Power { public Power() { super(); } public void supply(){ System.out.println("電源供電中。。。。。"); } }
CDPlayer 增加power注入
package soundsystem; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; /** * Component 讓他能被spring上下文發現 */ @Component public class CDPlayer { /** *private 成員變量 */ private CompactDisc cd; private Power power; public CDPlayer() { super(); System.out.println("CDPlayer無參數構造函數"); } /** * Ctrl + Insert 選(Constructor)創建有參的構造函數 * @param */ // @Autowired // public CDPlayer(CompactDisc cd, Power power) { // this.cd = cd; // this.power = power; // System.out.println("CDPlayer多參數構造函數"); // } @Autowired public CDPlayer(CompactDisc cd, Power power) { this.cd = cd; this.power = power; System.out.println("CDPlayer多參數構造函數。。。。"); } /** * 定義一個方法play,執行cd.play() power.supply();播放工作 */ public void play(){ power.supply(); cd.play(); } }
CompactDisc 無修改
package soundsystem; import org.springframework.stereotype.Component; @Component public class CompactDisc { public CompactDisc() { super(); System.out.println("CompactDisc無參構造函數"); } public void play(){ System.out.println("正在播放音樂......"); } }
AppConfig 無修改
package soundsystem; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; /** * 這就是一個配置類 */ @Configuration @ComponentScan public class AppConfig { public AppConfig() { super(); System.out.println("配置類,用于將注解和主類解耦"); } }
AppTest 無修改
package soundsystem; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = AppConfig.class) public class AppTest { @Autowired private CDPlayer player; @Test public void testPlay(){ player.play(); } }3.2.3 用成員變量的方式進行依賴注入
這個方式就是spring通過反射機制做的依賴注入
注入效率低,但是簡潔
package soundsystem; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; /** * Component 讓他能被spring上下文發現 */ @Component public class CDPlayer { /** *private 成員變量 */ @Autowired private CompactDisc cd; @Autowired private Power power; public CDPlayer() { super(); System.out.println("CDPlayer無參數構造函數"); } /** * Ctrl + Insert 選(Constructor)創建有參的構造函數 * @param */ // @Autowired // public CDPlayer(CompactDisc cd) { // this.cd = cd; // System.out.println("CDPlayer有參數構造函數"); // } // @Autowired // public CDPlayer(CompactDisc cd, Power power) { // this.cd = cd; // this.power = power; // System.out.println("CDPlayer多參數構造函數。。。。"); // } /** * 定義一個方法play,執行cd.play()播放工作 */ public void play(){ power.supply(); cd.play(); } }3.2.3 利用setter方法進行依賴注入
Alt+Insert 選setter進行setter對對象方法進行裝配
package soundsystem; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; /** * Component 讓他能被spring上下文發現 */ @Component public class CDPlayer { /** *private 成員變量 */ //@Autowired private CompactDisc cd; //@Autowired private Power power; @Autowired public void setCd(CompactDisc cd) { this.cd = cd; System.out.println("調用setCd。。。。"); } @Autowired public void setPower(Power power) { this.power = power; System.out.println("調用setPower。。。"); } public CDPlayer() { super(); System.out.println("CDPlayer無參數構造函數"); } /** * Ctrl + Insert 選(Constructor)創建有參的構造函數 * @param */ // @Autowired // public CDPlayer(CompactDisc cd) { // this.cd = cd; // System.out.println("CDPlayer有參數構造函數"); // } // @Autowired // public CDPlayer(CompactDisc cd, Power power) { // this.cd = cd; // this.power = power; // System.out.println("CDPlayer多參數構造函數。。。。"); // } /** * 定義一個方法play,執行cd.play()播放工作 */ public void play(){ power.supply(); cd.play(); } }3.2.4 用在任意方法上
package soundsystem; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; /** * Component 讓他能被spring上下文發現 */ @Component public class CDPlayer { /** *private 成員變量 */ //@Autowired private CompactDisc cd; //@Autowired private Power power; // @Autowired // public void setCd(CompactDisc cd) { // this.cd = cd; // System.out.println("調用setCd。。。。"); // } // // @Autowired // public void setPower(Power power) { // this.power = power; // System.out.println("調用setPower。。。"); // } @Autowired public void prepare(CompactDisc cd ,Power power){ this.cd = cd; this.power = power; System.out.println("調用prepare。。。"); } public CDPlayer() { super(); System.out.println("CDPlayer無參數構造函數"); } /** * Ctrl + Insert 選(Constructor)創建有參的構造函數 * @param */ // @Autowired // public CDPlayer(CompactDisc cd) { // this.cd = cd; // System.out.println("CDPlayer有參數構造函數"); // } // @Autowired // public CDPlayer(CompactDisc cd, Power power) { // this.cd = cd; // this.power = power; // System.out.println("CDPlayer多參數構造函數。。。。"); // } /** * 定義一個方法play,執行cd.play()播放工作 */ public void play(){ power.supply(); cd.play(); } }4.接口開發 interface 4.1 簡單的接口實現,單一實現類環境
創建com.cloud.demo.service 包
創建UserService 接口
package com.cloud.demo.service; /**
*/
public interface UserService {
void add();
}
- 創建接口實現方法(實現類),創建包com.cloud.demo.service.com.cloud.demo.service.impl,創建實現類UserServiceNormal
package com.cloud.demo.service.com.cloud.demo.service.impl;
import com.cloud.demo.service.UserService;
import org.springframework.stereotype.Component;
/**
UserServiceNormal 實現UserService 的方法
這里為實現類,@Component不寫在接口,寫在實現類上
*/
@Component
public class UserServiceNormal implements UserService {
public void add() { System.out.println("添加用戶"); }
}
- 創建配置類AppConfig
package com.cloud.demo.service;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@ComponentScan
public class AppConfig {
}
- 創建單元測試,新建包com.cloud.demo.service,userService的接口UserServiceTest
package com.cloud.demo.service;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
/**
1.要測試的是userService的接口
2.private UserService userService; 接口注入@Autowired
3.userService.add() 調用add()方法
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = AppConfig.class)
public class UserServiceTest {
//單一實現類環境下 @Autowired private UserService userService; @Test public void testAdd(){ userService.add(); }
}
***@Component不寫在接口,寫在實現類上*** ***調用userService,需要聲明接口 private UserService userService;*** ### 4.2 多實現類環境 #### 4.2.1 設置首選Bean - 配置@Primary,這樣系統默認就會使用UserServiceNormal實現類,但是有局限性 - 只能定義一個@Primary
@Component
@Primary
public class UserServiceNormal implements UserService {
public void add() { System.out.println("增加用戶"); } public void del() { System.out.println("刪除用戶"); }
}
#### 4.2.2 使用限定符@Qualifier UserServiceFestival
@Component
@Qualifier("Festival")
public class UserServiceFestival implements UserService {
@Override public void add() { System.out.println("注冊用戶并發送優惠券"); } @Override public void del() { }
}
UserServiceNormal
@Component
@Qualifier("Normal")
public class UserServiceNormal implements UserService {
public void add() { System.out.println("增加用戶"); } public void del() { System.out.println("刪除用戶"); }
}
UserServiceTest
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = AppConfig.class)
public class UserServiceTest {
@Autowired //這里通過@Qualifier 調用Festival 實現類 @Qualifier("Festival") private UserService userService; @Test public void testAdd(){ userService.add(); userService.del(); }
}
#### 4.2.3 通過設置ID和限定符實現 - 將參數配置在@Component中實現@Qualifier UserServiceFestival
@Component("fastival")
public class UserServiceFestival implements UserService {
@Override public void add() { System.out.println("注冊用戶并發送優惠券"); } @Override public void del() { }
}
UserServiceNormal
@Component("normal")
public class UserServiceNormal implements UserService {
public void add() { System.out.println("增加用戶"); } public void del() { System.out.println("刪除用戶"); }
}
UserServiceTest
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = AppConfig.class)
public class UserServiceTest {
@Autowired @Qualifier("fastival") private UserService userService; @Test public void testAdd(){ userService.add(); userService.del(); }
}
#### 4.2.4 使用系統默認ID和限定符 - spring中默認會給實現類分配一個ID ,為類名首寫字母小寫 UserServiceTest
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = AppConfig.class)
public class UserServiceTest {
@Autowired @Qualifier("userServiceNormal") private UserService userService; @Test public void testAdd(){ userService.add(); userService.del(); }
}
#### 4.2.5 使用@Resource - @Resource 相當于@Autowired + @Qualifier("userServiceNormal") - @Resource是jdk標準類,非spring標準類
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = AppConfig.class)
public class UserServiceTest {
//@Autowired //@Qualifier("userServiceNormal") @Resource(name="userServiceNormal") private UserService userService; @Test public void testAdd(){ userService.add(); userService.del(); }
}
## 5.配置類 ComponentScan組件掃描 ### 5.1 直接聲明 直接聲明單個目錄
@Configuration
@ComponentScan("com.cloud.demo")
直接聲明多個目錄
@Configuration
@ComponentScan(basePackages = {"com.cloud.demo.web","com.cloud.demo.service","com.cloud.demo.dao"})
- 有風險重構不會自動修改 直接聲明接口類
@Configuration
@ComponentScan(basePackageClasses = {UserController.class, UserService.class, UserDao.class})
### 5.2 XML聲明 ***applicationContext.xml 相當于@Configuration*** applicationContext.xml
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
***測試用列中修改UserControllerTest*** @ContextConfiguration("classpath:applicationContext.xml") 指定xml位置
@RunWith(SpringJUnit4ClassRunner.class)
//@ContextConfiguration(classes = AppConfig.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class UserControllerTest {
@Autowired private UserController userController; @Test public void testAdd(){ userController.add(); }
}
## 6 配置Java Configuration ### 6.1 如何配置@bean對象在java Config 接口:UserDao
public interface UserDao {
void add();
}
接口實現類:UserDaoNormal
public class UserDaoNormal implements UserDao {
@Override public void add() { System.out.println("添加用戶到數據庫中。。。。"); }
}
配置類:AppConfig - @Configuration 聲明為配置類 - @Bean標識spring默認啟動會自動加載改配置
@Configuration
public class AppConfig {
@Bean public UserDao UserDaoNormal(){ System.out.println("創建UserDao對象"); return new UserDaoNormal(); }
}
測試類:UserDaoTest
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = AppConfig.class)
public class UserDaoTest {
@Autowired private UserDao userDao; @Test public void testAdd(){ userDao.add(); }
}
### 6.2 構造函數注入場景- 普通方式 UserServiceNormal - 通過構造函數關聯依賴
public class UserServiceNormal implements UserService {
private UserDao userDao; //無參構造函數 public UserServiceNormal() { super(); } //有參構造函數 public UserServiceNormal(UserDao userDao) { this.userDao = userDao; } @Override public void add() { userDao.add(); }
}
UserService
public interface UserService {
void add();
}
UserDao
public interface UserDao {
void add();
}
UserDaoNormal
public class UserDaoNormal implements UserDao {
@Override public void add() { System.out.println("添加用戶到數據庫中。。。。"); }
}
AppConfig
@Configuration
public class AppConfig {
@Bean public UserDao userDaoNormal(){ System.out.println("創建UserDao對象"); return new UserDaoNormal(); } @Bean public UserService userServiceNormal(){ System.out.println("創建UserService對象"); UserDao userDao = userDaoNormal(); return new UserServiceNormal(userDao); }
}
UserServiceTest
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = AppConfig.class)
public class UserServiceTest {
@Autowired private UserService userService; @Test public void testAdd(){ userService.add(); }
}
### 6.3 構造函數注入場景- 優雅方式 AppConfig
@Configuration
public class AppConfig {
@Bean public UserDao userDaoNormal(){ System.out.println("創建UserDao對象"); return new UserDaoNormal(); } @Bean public UserService userServiceNormal(UserDao userDao){ System.out.println("創建UserService對象"); //UserDao userDao = userDaoNormal(); return new UserServiceNormal(userDao); }
}
- 實際編程中不會做函數的調用,而是在參數中取獲取UserDao ### 6.4 通過setter方法依賴注入 UserServiceNormal
public class UserServiceNormal implements UserService {
private UserDao userDao; //setter方法注入 public void setUserDao(UserDao userDao) { this.userDao = userDao; } @Override public void add() { userDao.add(); }
}
AppConfig
@Configuration
public class AppConfig {
@Bean public UserDao userDaoNormal(){ System.out.println("創建UserDao對象"); return new UserDaoNormal(); } @Bean public UserService userServiceNormal(UserDao userDao){ System.out.println("創建UserService對象"); //賦值給一個變量userService UserServiceNormal userService = new UserServiceNormal(); //調用userService的setter方法,將userDao注入 userService.setUserDao(userDao); //返回userService return userService; }
}
### 6.5 通過任意函數注入 UserServiceNormal
public class UserServiceNormal implements UserService {
private UserDao userDao; //任意函數注入 public void prepare(UserDao userDao){ this.userDao = userDao; } @Override public void add() { userDao.add(); }
}
AppConfig
@Configuration
public class AppConfig {
@Bean public UserDao userDaoNormal(){ System.out.println("創建UserDao對象"); return new UserDaoNormal(); } @Bean public UserService userServiceNormal(UserDao userDao){ System.out.println("創建UserService對象"); UserServiceNormal userService = new UserServiceNormal(); //任意函數注入 userService.prepare(userDao); return userService; }
}
### 6.6 XML裝配 #### 6.6.1 創建xml配置規范 applicationContext.xml
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
#### 6.6.2 xml定義第bean CompactDisc
public class CompactDisc {
public CompactDisc() { super(); System.out.println("CompacDisc構造函數。。。。" + this.toString()); } public void play(){ System.out.println("播放CD音樂。。。。。" + this.toString()); }
}
ApplicationSpring
public class ApplicationSpring {
public static void main(String[] args) { System.out.println("ApplicationSpring is running......"); ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); //初始化cd CompactDisc cd = context.getBean(CompactDisc.class); //調用play方法 cd.play(); }
}
applicationContext.xml - xml 定義bean
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
輸出結果
ApplicationSpring is running......
CompacDisc構造函數。。。。com.cloud.deam.soundsystem.CompactDisc@2669b199
播放CD音樂。。。。。com.cloud.deam.soundsystem.CompactDisc@2669b199
***多個重名bean設置id區分:***
- name可以通過分號、空格、逗號分隔,設置不同的別名 name="CompactDisc1 CompactDisc12 CompactDisc13 " - id只能通過傳字符進行傳遞 ApplicationSpring -- 主方法
public class ApplicationSpring {
public static void main(String[] args) { System.out.println("ApplicationSpring is running......"); ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); //CompactDisc cd = context.getBean(CompactDisc.class); CompactDisc cd1 = (CompactDisc) context.getBean("compactDisc1"); CompactDisc cd2 = (CompactDisc) context.getBean("compactDisc2"); cd1.play(); cd2.play(); }
}
AppTest -- 測試類
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class CompactDiscTest {
@Autowired private CompactDisc CompactDisc1; @Autowired private CompactDisc CompactDisc2; //過濾方式注入 @Autowired @Qualifier("CompactDisc2") private CompactDisc cd; @Test public void testPlay(){ CompactDisc1.play(); CompactDisc2.play(); cd.play(); }
}
#### 6.6.3 xml注入 - 通過構造函數 | 名稱 | 用途 | 備注 | | --------------------- | ------------------------------------------------------------ | ---- | |元素 | 依賴Bean,有參構造函數依賴注入 | | | c-名稱空間 | --c:c函數命令空間 :cd 構造函數的參數名字cd
public CDPlayer(CompactDisc cd),-ref:表示的是CompactDisc2名稱的引用
也可以寫成c:0-ref="CompactDisc2" c:1-ref="CompactDisc2" 表示第一個 第二個參數 | | | | | | ***元構造函數依賴注入*** applicationContext.xml
CDPlayerTest
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class CDPlayerTest {
@Autowired private CDPlayer cdPlayer; @Test public void Test01(){ cdPlayer.play(); }
}
***c-名稱空間依賴注入***
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:c="http://www.springframework.org/schema/c"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
CDPlayerTest
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class CDPlayerTest {
@Autowired private CDPlayer cdPlayer1; @Autowired private CDPlayer cdPlayer2; @Test public void Test01(){ cdPlayer1.play(); cdPlayer2.play(); }
}
#### 6.6.4 注入簡單類型 -通過構造函數 - 給CompactDisc1 對象注入title、artist
***-c方式注入簡單類型:***
CompactDisc
public class CompactDisc {
private String title; private String artist; public CompactDisc() { super(); System.out.println("CompacDisc構造函數。。。。" + this.toString()); } public CompactDisc(String title, String artist) { this.title = title; this.artist = artist; System.out.println("CompacDisc構造函數。。。。" + this.toString()); } public void play(){ System.out.println("播放CD音樂。。。。。" + this.toString() +" " +this.title+ " by " +this.artist); }
}
#### 6.6.5 注入list類型 -通過構造函數 applicationContext.xml
I Do 1 I Do 2 I Do 3
CompactDisc
public class CompactDisc {
private String title; private String artist; //聲明一個list private Listtracks; public CompactDisc() { super(); System.out.println("CompacDisc構造函數。。。。" + this.toString()); } public CompactDisc(String title, String artist) { this.title = title; this.artist = artist; System.out.println("CompacDisc有參構造函數。。。。" + this.toString()); } //創建包含三個函數的構造函數 public CompactDisc(String title, String artist, List tracks) { this.title = title; this.artist = artist; this.tracks = tracks; System.out.println("CompacDisc有三個參構造函數。。。。" + this.toString()); } public void play(){ System.out.println("播放CD音樂。。。。。" + this.toString() +" " +this.title+ " by " +this.artist); //循環打印tracks內容 for (String track : this.tracks) { System.out.println("音樂:" + track); } }
}
***創建一個復雜對象類型*** 創建類型 Music
package com.cloud.deam.soundsystem;
public class Music {
private String title; private Integer duration; //創建getter setter 方法 public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public Integer getDuration() { return duration; } public void setDuration(Integer duration) { this.duration = duration; } //創建無參構造方法 public Music() { super(); } //創建有參構造方法 public Music(String title, Integer duration) { this.title = title; this.duration = duration; }
}
CompactDisc
public class CompactDisc {
private String title; private String artist; //設置List為Music類型 private Listtracks; public CompactDisc() { super(); System.out.println("CompacDisc構造函數。。。。" + this.toString()); } public CompactDisc(String title, String artist) { this.title = title; this.artist = artist; System.out.println("CompacDisc有參構造函數。。。。" + this.toString()); } //設置List為Music類型 public CompactDisc(String title, String artist, List tracks) { this.title = title; this.artist = artist; this.tracks = tracks; System.out.println("CompacDisc有三個參構造函數。。。。" + this.toString()); } public void play(){ System.out.println("播放CD音樂。。。。。" + this.toString() +" " +this.title+ " by " +this.artist); for (Music track : this.tracks) { //通過get方法獲取屬性 System.out.println("音樂:" + track.getTitle() + ".時長:" + track.getDuration()); } }
}
applicationContext.xml - 復雜的對象依賴注入
#### 6.6.6 注入set類型 -通過構造函數 CompactDisc
public class CompactDisc {
private String title; private String artist; //設置set為Music類型 private Listtracks; public CompactDisc() { super(); System.out.println("CompacDisc構造函數。。。。" + this.toString()); } public CompactDisc(String title, String artist) { this.title = title; this.artist = artist; System.out.println("CompacDisc有參構造函數。。。。" + this.toString()); } //設置set為Music類型 public CompactDisc(String title, String artist, set tracks) { this.title = title; this.artist = artist; this.tracks = tracks; System.out.println("CompacDisc有三個參構造函數。。。。" + this.toString()); } public void play(){ System.out.println("播放CD音樂。。。。。" + this.toString() +" " +this.title+ " by " +this.artist); for (Music track : this.tracks) { //通過get方法獲取屬性 System.out.println("音樂:" + track.getTitle() + ".時長:" + track.getDuration()); } }
}
applicationContext.xml
- ***set和list區別在裝配的時候重復的值在set中會被過濾*** - ***set元素的順序能夠和插入一致。而list是無序的*** #### 6.6.7 注入MAP集合 -通過構造函數 CompactDisc
public class CompactDisc {
private String title; private String artist; private Maptracks; public CompactDisc() { super(); System.out.println("CompacDisc構造函數。。。。" + this.toString()); } public CompactDisc(String title, String artist) { this.title = title; this.artist = artist; System.out.println("CompacDisc有參構造函數。。。。" + this.toString()); } public CompactDisc(String title, String artist, Map tracks) { this.title = title; this.artist = artist; this.tracks = tracks; System.out.println("CompacDisc有三個參構造函數。。。。" + this.toString()); } public void play(){ System.out.println("播放CD音樂。。。。。" + this.toString() +" " +this.title+ " by " +this.artist); for (String key : this.tracks.keySet()) { System.out.println("key:" + key ); Music music = this.tracks.get(key); System.out.println("音樂:" + music.getTitle() + ".時長:" + music.getDuration()); } }
}
applicationContext.xml
//map類型注入需要使用entry
#### 6.6.8 注入數組類型 -通過構造函數 CompactDisc
public class CompactDisc {
private String title; private String artist; //設置Music為數組類型 private Music[] tracks; public CompactDisc() { super(); System.out.println("CompacDisc構造函數。。。。" + this.toString()); } public CompactDisc(String title, String artist) { this.title = title; this.artist = artist; System.out.println("CompacDisc有參構造函數。。。。" + this.toString()); } //設置Music為數組類型 public CompactDisc(String title, String artist, Music[] tracks) { this.title = title; this.artist = artist; this.tracks = tracks; System.out.println("CompacDisc有三個參構造函數。。。。" + this.toString()); } public void play(){ System.out.println("播放CD音樂。。。。。" + this.toString() +" " +this.title+ " by " +this.artist); for (Music track : this.tracks) { System.out.println("音樂:" + track.getTitle() + ".時長:" + track.getDuration()); } }
}
applicationContext.xml
#### 6.6.9 屬性注入 1.set注入屬性注入 applicationContext-properties.xml - property 注入元素
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
Music - 屬性注入只需set方法就可以 - 屬性的構造方法,會走無參構造函數
public class Music {
//聲明的是私有的成員變量 private String title; private Integer duration; //創建getter setter 方法 public String getTitle() { return title; } //setTitle是屬性 public void setTitle(String title) { this.title = title; System.out.println("--在" +this.toString() + "中注入title"); } public Integer getDuration() { return duration; } //setDuration是屬性 public void setDuration(Integer duration) { this.duration = duration; System.out.println("--在" +this.toString() + "中注入duration"); } //創建無參構造方法 public Music() { super(); System.out.println("Music的構造函數。。。"+this.toString()); } //創建有參構造方法 public Music(String title, Integer duration) { this.title = title; this.duration = duration; }
}
AppTest
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext-properties.xml")
public class AppTest {
@Test public void test(){ }
}
測試結果
Music的構造函數。。。com.cloud.deam.soundsys
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/75700.html
摘要:我的學習筆記匯總標簽筆記分為兩大部分和筆記內容主要是對一些基礎特性和編程細節進行總結整理,適合了解基礎語法,想進一步深入學習的人如果覺得不錯,請給,這也是對我的鼓勵,有什么意見歡迎留言反饋目錄基礎鞏固筆記反射基礎鞏固筆記泛型基礎鞏 我的java&javaweb學習筆記(匯總) 標簽: java [TOC] 筆記分為兩大部分:javase和javaweb javase javawe...
摘要:最近系統整理了一套初學者最佳的學習方法以及會遇到的坑等,希望對你有所幫助。正常的智商其實,學習并不需要所謂的數學邏輯好,需要英語水平棒。大周期每天學習時間五個小時以上的,建議學習周期。三學習時會遇到的坑不知道學習的重點,下面學習路線會畫。 最近系統整理了一套java初學者最佳的學習方法以及會遇到的坑等,希望對你有所幫助。 目錄: 一、學習java的前提 二、學習java的方法 三、學習...
摘要:而面向搜索引擎,就是我們要及時的使用百度谷歌遇到問題無法解決,先別急著放棄,可以去網絡尋找答案,你的坑大部分別人都已經走過了,大部分都可以找到合適的解決方案。 showImg(https://segmentfault.com/img/remote/1460000019236352?w=866&h=456); 前言: ●眾多的語言,到底哪一門才是適合我的?●我們為什么要學習Java語言呢...
摘要:請回復這個帖子并注明組織個人信息來申請加入。權限分配靈活,能者居之。數量超過個,在所有組織中排名前。網站日超過,排名的峰值為。導航歸檔社區自媒體平臺微博知乎專欄公眾號博客園簡書合作侵權,請聯系請抄送一份到贊助我們 Special Sponsors showImg(https://segmentfault.com/img/remote/1460000018907426?w=1760&h=...
摘要:請回復這個帖子并注明組織個人信息來申請加入。版筆記等到中文字幕翻譯完畢后再整理。數量超過個,在所有組織中排名前。網站日超過,排名的峰值為。主頁歸檔社區自媒體平臺微博知乎專欄公眾號博客園簡書合作侵權,請聯系請抄送一份到贊助我們 Special Sponsors showImg(https://segmentfault.com/img/remote/1460000018907426?w=1...
閱讀 2642·2021-11-11 16:55
閱讀 680·2021-09-04 16:40
閱讀 3077·2019-08-30 15:54
閱讀 2615·2019-08-30 15:54
閱讀 2403·2019-08-30 15:46
閱讀 403·2019-08-30 15:43
閱讀 3227·2019-08-30 11:11
閱讀 2982·2019-08-28 18:17