日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網(wǎng)為廣大站長提供免費(fèi)收錄網(wǎng)站服務(wù),提交前請做好本站友鏈:【 網(wǎng)站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(wù)(50元/站),

點(diǎn)擊這里在線咨詢客服
新站提交
  • 網(wǎng)站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

這篇文章中我們將會介紹Spring的框架以及本體內(nèi)容,包括核心容器,注解開發(fā),AOP以及事務(wù)等內(nèi)容

那么簡單說明一下Spring的必要性:

 

  • Spring技術(shù)是JAVAEE開發(fā)的必備技能,企業(yè)開發(fā)技術(shù)選型率高達(dá)90%!
  • Spring可以幫助簡化開發(fā),降低企業(yè)級開發(fā)的復(fù)雜度
  • Spring可以進(jìn)行框架整合,高效整合其他技術(shù),提高企業(yè)級應(yīng)用開發(fā)與運(yùn)行效率

 

Spring的核心內(nèi)容:

 

  • IoC技術(shù)
  • DI技術(shù)
  • AOP
  • 事務(wù)處理

 

Spring可進(jìn)行的框架整合:

 

  • MaBatis
  • MyBatis-plus
  • Struts
  • Struts2
  • Hibernate

 

在接下來的文章中,我們會學(xué)習(xí)Spring的框架思想,學(xué)習(xí)Spring的基本操作,結(jié)合案例熟練掌握

 

溫馨提醒:在學(xué)習(xí)本篇文章前請先學(xué)習(xí)JavaWeb相關(guān)內(nèi)容 (HTTP,Tomcat,Servlet,Request,Response,MVC,Cookie,Session,Ajax,Vue等內(nèi)容)
初識Spring

 

官網(wǎng):Spring | Home

Spring發(fā)展至今已經(jīng)形成了一套開發(fā)的生態(tài)圈,Spring提供了相當(dāng)多的項(xiàng)目,每個項(xiàng)目用于完成特定功能


 

我們常用的主流技術(shù)包括有:

 

  • Spring Framework:Spring框架
  • Spring Boot:Spring簡化代碼開發(fā)
  • Spring Cloud:Spring分布設(shè)計
Spring FrameWork系統(tǒng)架構(gòu)

 

在系統(tǒng)學(xué)習(xí)Spring之前,我們需要先來了解FrameWork系統(tǒng)結(jié)構(gòu)

 

  • Spring FrameWork是Spring生態(tài)圈中最基本的項(xiàng)目,是其他項(xiàng)目的根基

 


 

我們現(xiàn)在所使用的Spring FrameWork是4.0版本,已經(jīng)趨于穩(wěn)定

下面我們對架構(gòu)圖進(jìn)行解釋:

 

  • Core Container:核心容器
  • AOP:面向切面編程
  • Aspects:AOP思想實(shí)現(xiàn)
  • Data Access:數(shù)據(jù)訪問
  • Data Intergration:數(shù)據(jù)集成
  • Web:Web開發(fā)
  • Test:單元測試與集成測試

 

我們可以在官方中獲得如此評價:

 

  • 強(qiáng)大的基于 JavaBeans 的采用控制反轉(zhuǎn)(Inversion of Control,IoC)原則的配置管理,使得應(yīng)用程序的組建更加快捷簡易。
  • 數(shù)據(jù)庫事務(wù)的一般化抽象層,允許插件式事務(wù)管理器,簡化事務(wù)的劃分使之與底層無關(guān)。
  • 一個可用于從 Applet 到 Java EE 等不同運(yùn)行環(huán)境的核心 Bean 工廠。
核心概念介紹

 

首先我們思索一下我們之前的業(yè)務(wù)層與數(shù)據(jù)層:

// 數(shù)據(jù)層接口 public interface BookDao { public void save(); }// 數(shù)據(jù)層實(shí)現(xiàn) public class BookDaoImpl implements BookDao { public void save() { System.out.println("book dao save ..."); } }// 業(yè)務(wù)層接口 public interface BookService { public void save(); }// 業(yè)務(wù)層實(shí)現(xiàn) public class BookServiceImpl implements BookService { private BookDao bookDao; public void save() { bookDao.save(); } }

如果我們修改BookDaoImpl內(nèi)容,那么相對應(yīng)的業(yè)務(wù)層實(shí)現(xiàn)中的bookDao的new實(shí)現(xiàn)也要進(jìn)行修改,甚至下方方法的對象也要進(jìn)行修改

Spring使用前問題

代碼書寫現(xiàn)狀:

 

  • 耦合度偏高

 

解放方案:

 

  • 使用對象時,在程序中不要主動使用new產(chǎn)生對象,轉(zhuǎn)換為由外部提供對象
Spring思想以及實(shí)現(xiàn)

 

IoC(Inversion of Control)控制反轉(zhuǎn)思想:

 

  • 使用對象時,由主動new創(chuàng)建對象轉(zhuǎn)換為由外部提供對象
  • 此過程中對象創(chuàng)建控制權(quán)由程序轉(zhuǎn)移到外部,被稱為控制反轉(zhuǎn)

 

DI(Dependency Injection)依賴注入:

 

  • 在容器中建立Bean與Bean之間的依賴關(guān)系和整個過程,被稱為依賴注入

 

Spring技術(shù)對Ioc思想進(jìn)行了實(shí)現(xiàn):

 

  • Spring提供了一個容器,被稱為Ioc容器,用來充當(dāng)IoC思想的外部
  • IoC容器負(fù)責(zé)對象的創(chuàng)建,初始化等一系列工作,被創(chuàng)建和管理的對象在IoC容器中被稱為Bean
// 數(shù)據(jù)層實(shí)現(xiàn) public class BookDaoImpl implements BookDao { public void save() { System.out.println("book dao save ..."); } }// IoC容器 /* 包含 dao service 兩者可以建立連接 */// 業(yè)務(wù)層實(shí)現(xiàn) public class BookServiceImpl implements BookService { private BookDao bookDao; public void save() { bookDao.save(); } }

 

目的:充分解耦

 

  • IoC:使用IoC容器管理bean
  • DI:在IoC容器內(nèi)將有依賴關(guān)系的bean進(jìn)行關(guān)系綁定

 

最終效果:

 

  • 使用對象不僅可以直接從IoC容器中獲取,還可以將已獲得的Bean之間綁定依賴關(guān)系
IoC入門

 

首先我們需要明白IoC的使用規(guī)則:

 

  1. IoC負(fù)責(zé)管理什么:Service和Dao
  2. 如何被管理的對象告知IoC容器:(配置)
  3. 被管理的對象交給IoC容器,如何獲得IoC容器:(接口)
  4. IoC容器得到之后,如何獲得Bean:(接口方法)
  5. 使用Spring所需要導(dǎo)入的坐標(biāo):(pom.xml)

 

下面我們給出IoC入門的詳細(xì)步驟:

 

  1. 創(chuàng)建Maven項(xiàng)目,在pom.xml中導(dǎo)入坐標(biāo)
org.springframework spring-context 5.2.10.RELEASE
  1. 創(chuàng)建Spring.xml的配置包(applicationContext.xml,導(dǎo)入坐標(biāo)后xml中更新該XML)
  1. 主函數(shù)
package com.itheima; import com.itheima.dao.BookDao; import com.itheima.service.BookService; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class App2 { public static void main(String[] args) { //3.獲取IoC容器 ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml"); //4.獲取bean(根據(jù)bean配置id獲取) //BookDao bookDao = (BookDao) ctx.getBean("bookDao"); //bookDao.save(); // 注意:需要類型轉(zhuǎn)化 BookService bookService = (BookService) ctx.getBean("bookService"); bookService.save(); } }DI入門

 

首先我們需要明白DI的使用規(guī)則:

 

  1. 基于IoC管理bean
  2. Service中使用new形式創(chuàng)建Dao對象是否保留:(否)
  3. Service中需要Dao對象如何進(jìn)入到Service中:(提供方法)
  4. Service與Dao之間的關(guān)系如何描述:(配置)

 

下面我們給出DI入門的詳細(xì)步驟(基于IoC入門):

 

  1. 刪除new方法
public class BookServiceImpl implements BookService { //5.刪除業(yè)務(wù)層中使用new的方式創(chuàng)建的dao對象 private BookDao bookDao; public void save() { System.out.println("book service save ..."); bookDao.save(); } }
  1. 創(chuàng)建對象的set方法
public class BookServiceImpl implements BookService { //5.刪除業(yè)務(wù)層中使用new的方式創(chuàng)建的dao對象 private BookDao bookDao; public void save() { System.out.println("book service save ..."); bookDao.save(); } //6.提供對應(yīng)的set方法 public void setBookDao(BookDao bookDao) { this.bookDao = bookDao; } }
  1. 創(chuàng)建Dao和Service的連接
Bean整體介紹

 

Bean是保存在IoC中的對象,我們通過配置的方式獲得Bean

下面我們從三個方面分別講解Bean:

bean基本配置

首先我們先介紹bean本身性質(zhì):

類別

描述

名稱

bean

類型

所屬

beans標(biāo)簽

功能

定義Spring核心容器管理對象

格式

屬性列表

id:bean的id,使用容器可以通過id值獲得對應(yīng)的bean,在一個容器中id值唯一
class:bean的類型,即配置的bean的全路徑類名

范例

然后我們介紹一下bean的別名:

類別

描述

名稱

name

類型

所屬

bean標(biāo)簽

功能

定義bean的別名,可定義多個,使用逗號,分號,空格分隔

范例

 

正常情況下,使用id和name都可以獲得bean,但推薦還是使用唯一id 獲得bean無論通過id還是name獲取,如果無法找到則拋出異常NosuchBeanDefinitionException

 

最后我們介紹一下bean的作用范圍scope:

類別

描述

名稱

scope

類型

所屬

bean標(biāo)簽

功能

定義bean的作用范圍,可選范圍如下:
singleton:單列(默認(rèn))
prototype:非單列

范例

 

這里的scope指產(chǎn)生對象的數(shù)量 我們的scope在默認(rèn)情況下是singleton,因?yàn)楹芏鄬ο笾恍枰獎?chuàng)建一次,多次創(chuàng)建會導(dǎo)致內(nèi)存膨脹 合適交給容器進(jìn)行管理的bean(singleton): 表現(xiàn)層對象業(yè)務(wù)層對象數(shù)據(jù)層對象工具對象 不合適交給容器進(jìn)行管理的bean(prototype): 封裝實(shí)體的域?qū)ο螅◣в袪顟B(tài)的bean)
bean實(shí)例化

 

bean的實(shí)例化通常分為四種方法,我們在下面一一介紹:

 

  1. 構(gòu)造方法(常用)

 

我們需要在數(shù)據(jù)類中提供構(gòu)造方法,配置條件中不需要改變

// 數(shù)據(jù)類 public class BookDaoImpl implements BookDao { public BookDaoImpl() { System.out.println("book dao constructor is running ...."); } public void save() { System.out.println("book dao save ..."); } }

若無參構(gòu)造方法不存在,則拋出異常BeanCreationException
  1. 靜態(tài)工廠(了解)

 

我們在之前的案例中存在有對象工廠的說法,我們可以設(shè)置工廠并調(diào)用其方法得到bean

// 靜態(tài)工廠 package com.itheima.factory; import com.itheima.dao.OrderDao; import com.itheima.dao.impl.OrderDaoImpl; //靜態(tài)工廠創(chuàng)建對象 public class OrderDaoFactory { public static OrderDao getOrderDao(){ System.out.println("factory setup...."); return new OrderDaoImpl(); } }

  1. 實(shí)例工廠(了解)

 

和靜態(tài)工廠相同,但不同點(diǎn)是方法不是靜態(tài),我們需要提前創(chuàng)建一個bean

// 實(shí)例工廠 package com.itheima.factory; import com.itheima.dao.UserDao; import com.itheima.dao.impl.UserDaoImpl; //實(shí)例工廠創(chuàng)建對象 public class UserDaoFactory { public UserDao getUserDao(){ return new UserDaoImpl(); } }

  1. FactoryBean(重要實(shí)用)

 

除了我們之前自己定義的工廠外,Spring提供了一種官方版本的FactoryBean

// FactoryBean工廠(需接口,< >中填寫數(shù)據(jù)類接口) package com.itheima.factory; import com.itheima.dao.UserDao; import com.itheima.dao.impl.UserDaoImpl; import org.springframework.beans.factory.FactoryBean; //FactoryBean創(chuàng)建對象 public class UserDaoFactoryBean implements FactoryBean { //代替原始實(shí)例工廠中創(chuàng)建對象的方法 // 返回創(chuàng)建對象類型為UserDaoImpl() public UserDao getObject() throws Exception { return new UserDaoImpl(); } // 這里填寫接口類型 public Class getObjectType() { return UserDao.class; } // 可以修改來修改其scope屬性 public boolean isSingleton() { return false; } }bean生命周期

我們先來接單介紹生命周期相關(guān)概念:

 

  • 生命周期:從創(chuàng)建到消亡的完整過程
  • bean生命周期:bean從創(chuàng)建到銷毀的整體過程
  • bean生命周期控制:在bean創(chuàng)建后到銷毀前做一些事情

 

接下來我們介紹生命周期控制方法:

 

  1. 數(shù)據(jù)層提供控制方法

 

由數(shù)據(jù)層提供方法,在xml配置文件中設(shè)置該方法

// 數(shù)據(jù)層 package com.itheima.dao.impl; import com.itheima.dao.BookDao; public class BookDaoImpl implements BookDao { public void save() { System.out.println("book dao save ..."); } //表示bean初始化對應(yīng)的操作 public void init(){ System.out.println("init..."); } //表示bean銷毀前對應(yīng)的操作 public void destory(){ System.out.println("destory..."); } }

  1. 接口控制方法(了解)

 

Spring為創(chuàng)建提供了兩個接口,我們只需要繼承并實(shí)現(xiàn)該方法即可

package com.itheima.service.impl; import com.itheima.dao.BookDao; import com.itheima.service.BookService; import org.springframework.beans.factory.DisposableBean; import org.springframework.beans.factory.InitializingBean; // InitializingBean,DisposableBean 分別對應(yīng)afterPropertiesSet,destroy方法,代表創(chuàng)建和銷毀 public class BookServiceImpl implements BookService, InitializingBean, DisposableBean { private BookDao bookDao; public void setBookDao(BookDao bookDao) { System.out.println("set ....."); this.bookDao = bookDao; } public void save() { System.out.println("book service save ..."); bookDao.save(); } public void destroy() throws Exception { System.out.println("service destroy"); } public void afterPropertiesSet() throws Exception { System.out.println("service init"); } }

我們需要提及一下bean的銷毀時機(jī):(了解即可)

 

  • 因?yàn)槟J(rèn)情況下,我們的bean不會被銷毀,因?yàn)樘摂M機(jī)會直接退出,ClassPathXmlApplicationContext會被忽略銷毀過程

 

所以如果我們希望銷毀bean觀察到destroy的實(shí)現(xiàn),需要手動關(guān)閉:

 

  1. 手動關(guān)閉容器方法:
package com.itheima; import com.itheima.dao.BookDao; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class AppForLifeCycle { public static void main( String[] args ) { // 注意:這里需要采用ClassPathXmlApplicationContext作為對象,因?yàn)橹挥羞@個類才具有close方法 ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml"); BookDao bookDao = (BookDao) ctx.getBean("bookDao"); bookDao.save(); //關(guān)閉容器 ctx.close(); } }
  1. 注冊關(guān)閉鉤子,在虛擬機(jī)退出前先關(guān)閉容器再推出虛擬機(jī)
package com.itheima; import com.itheima.dao.BookDao; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class AppForLifeCycle { public static void main( String[] args ) { ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml"); BookDao bookDao = (BookDao) ctx.getBean("bookDao"); bookDao.save(); //注冊關(guān)閉鉤子函數(shù),在虛擬機(jī)退出之前回調(diào)此函數(shù),關(guān)閉容器 ctx.registerShutdownHook(); } }
最后我們統(tǒng)計一下整體生命周期: 初始化容器:創(chuàng)建對象(分配內(nèi)存)->執(zhí)行構(gòu)造方法->執(zhí)行屬性注入(set操作)->執(zhí)行bean初始化方法使用bean:執(zhí)行業(yè)務(wù)操作關(guān)閉/銷毀容器:執(zhí)行bean銷毀方法
依賴注入方式

 

首先我們要知道類中傳遞數(shù)據(jù)的方法有兩種:

 

  • 普通方法(Set方法)
  • 構(gòu)造方法

 

然后我們要知道數(shù)據(jù)的類型大體分為兩種:

 

  • 引入類型(數(shù)據(jù)層)
  • 簡單類型(基本數(shù)據(jù)類型和String)

 

所以我們把依賴注入方式分為四種:

 

  • setter注入簡單類型引用類型
  • 構(gòu)造器注入簡單類型引入類型
setter注入簡單類型

 

首先我們需要在bean種定義簡單類型屬性并提供可以訪問的set方法

package com.itheima.dao.impl; import com.itheima.dao.BookDao; public class BookDaoImpl implements BookDao { private String databaseName; private int connectionNum; //setter注入需要提供要注入對象的set方法 public void setConnectionNum(int connectionNum) { this.connectionNum = connectionNum; } //setter注入需要提供要注入對象的set方法 public void setDatabaseName(String databaseName) { this.databaseName = databaseName; } public void save() { System.out.println("book dao save ..."+databaseName+","+connectionNum); } }

然后在配置中使用property標(biāo)簽value屬性注入簡單類型數(shù)據(jù)

setter注入引用類型

首先我們需要在bean種定義引用類型屬性并提供可以訪問的set方法

package com.itheima.service.impl; import com.itheima.dao.BookDao; import com.itheima.dao.UserDao; import com.itheima.service.BookService; public class BookServiceImpl implements BookService{ private BookDao bookDao; private UserDao userDao; //setter注入需要提供要注入對象的set方法 public void setUserDao(UserDao userDao) { this.userDao = userDao; } //setter注入需要提供要注入對象的set方法 public void setBookDao(BookDao bookDao) { this.bookDao = bookDao; } public void save() { System.out.println("book service save ..."); bookDao.save(); userDao.save(); } }

然后在配置中使用property標(biāo)簽ref屬性注入引用類型數(shù)據(jù)

構(gòu)造器注入簡單類型(了解)

在bean中定義簡單類型屬性并提供可訪問的set方法

public class BookDaoImpl implements BookDao{ private int connectionNumber; pubilc void setConnectionNumber(int connectionNumber){ this.connectionNumber = connectionNumber; } }

配置中使用constructor-arg標(biāo)簽value屬性注入簡單類型數(shù)據(jù)

根據(jù)構(gòu)造方法參數(shù)名稱注入構(gòu)造器注入引用類型(了解)

在bean中定義引用類型屬性并提供可訪問的構(gòu)造方法

public class BookDaoImpl implements BookDao{ private BookBao bookBao; pubilc void setConnectionNumber(int connectionNumber){ this.bookBao = bookBao; } }

配置中使用constructor-arg標(biāo)簽ref屬性注入簡單類型數(shù)據(jù)

構(gòu)造器注入?yún)?shù)配置問題(了解)

在前面我們已經(jīng)介紹了構(gòu)造器的注入方法

但如果我們在bean中的數(shù)據(jù)名稱發(fā)生改變,配置就不再適配,所以提供了一些方法來解決參數(shù)配置問題:

 

  • 配置中使用constructor-arg標(biāo)簽type屬性設(shè)置按形參類型注入
根據(jù)構(gòu)造方法參數(shù)類型注入
  • 配置中使用constructor-arg標(biāo)簽index屬性設(shè)置按形參類型注入
依賴注入方式選擇

 

依賴注入方式有以下選擇標(biāo)準(zhǔn):

 

  1. 強(qiáng)制依賴使用構(gòu)造器進(jìn)行,使用setter注入有概率不進(jìn)行注入導(dǎo)致null對象出現(xiàn)
  2. 可選依賴使用setter注入進(jìn)行,靈活性高
  3. Spring框架倡導(dǎo)使用構(gòu)造器,第三方框架內(nèi)部大多數(shù)采用構(gòu)造器注入的形式進(jìn)行數(shù)據(jù)初始化,相對嚴(yán)謹(jǐn)
  4. 如果有必要可以兩者并用,使用構(gòu)造器注入完成強(qiáng)制依賴的注入,使用setter注入完成可選依賴的注入
  5. 實(shí)際開發(fā)中根據(jù)情況分析,如果受控對象沒有提供setter方法則只能采用構(gòu)造器注入
  6. 自己開發(fā)的模塊盡量推薦setter注入
依賴自動裝配

 

在前面我們學(xué)習(xí)了手動注入的方法,但Spring其實(shí)為我們提供了一種依賴自動裝配的語法:

 

  • IoC容器根據(jù)bean所依賴的資源在容器中自動查找并注入bean中的過程稱為自動裝配

 

自動裝配方式:

 

  • 按類型(常用)
  • 按名稱
  • 按構(gòu)造方法
  • 不啟用

 

自動裝配語法:

 

依賴自動裝配特征: 自動裝配用于引用類型注入,不能對簡單類型進(jìn)行操作使用按類型裝配時(byType)必須保障容器中相同類型的bean唯一,推薦使用使用按名稱裝配時(byName)必須保障容器中具有指定名稱的bean,因變量名與配置耦合,不推薦使用自動裝配優(yōu)先級低于setter注入和構(gòu)造器注入,同時出現(xiàn)時,自動裝配配置失效
依賴集合注入

 

除了基本類型和引入類型外,我們有時也需要注入集合

下面我們簡單介紹一下結(jié)合的注入:

// 數(shù)據(jù)類 package com.itheima.dao.impl; import com.itheima.dao.BookDao; import java.util.*; public class BookDaoImpl implements BookDao { private int[] array; private List list; private Set set; private Map map; private Properties properties; public void setArray(int[] array) { this.array = array; } public void setList(List list) { this.list = list; } public void setSet(Set set) { this.set = set; } public void setMap(Map map) { this.map = map; } public void setProperties(Properties properties) { this.properties = properties; } public void save() { System.out.println("book dao save ..."); System.out.println("遍歷數(shù)組:" + Arrays.toString(array)); System.out.println("遍歷List" + list); System.out.println("遍歷Set" + set); System.out.println("遍歷Map" + map); System.out.println("遍歷Properties" + properties); } }100 200 300 itcast itheima boxuegu chuanzhihui itcast itheima boxuegu boxuegu china henan kaifeng案例:數(shù)據(jù)源對象管理

針對一個新的數(shù)據(jù)源對象,我們采用兩步來創(chuàng)建bean(我們以druid為案例):

 

  • 導(dǎo)入druid坐標(biāo)
4.0.0 com.itheima spring_09_datasource 1.0-SNAPSHOT org.springframework spring-context 5.2.10.RELEASE com.alibaba druid 1.1.16 MySQL mysql-connector-java 5.1.47
  • 配置數(shù)據(jù)源對象作為Spring管理的bean
案例:加載properties文件

 

這個案例我們將會介紹如何加載properties文件,并將文件帶入到property基本信息中

我們大致將步驟分為以下三步:

 

  • 開辟context命名空間:
  • 使用context命名空間,加載指定properties文件
  • 使用${}讀取加載的屬性值

 

除了上述的基本操作,我們在context命名空間的使用中有很多需要注意的點(diǎn):

 

  • 不加載系統(tǒng)屬性
  • 加載多個properties文件
  • 加載所有properties文件
  • 加載properties文件標(biāo)準(zhǔn)格式
  • 從類路徑或jar包中搜索并加載properties文件
核心容器

 

前面已經(jīng)完成bean與依賴注入的相關(guān)知識學(xué)習(xí),接下來我們主要學(xué)習(xí)的是IOC容器中的核心容器。

這里所說的核心容器,大家可以把它簡單的理解為ApplicationContext,接下來我們從以下幾個問題入手來學(xué)習(xí)下容器的相關(guān)知識:

 

  • 如何創(chuàng)建容器?
  • 創(chuàng)建好容器后,如何從容器中獲取bean對象?
  • 容器類的層次結(jié)構(gòu)是什么?
  • BeanFactory是什么?
容器的創(chuàng)建方式

 

案例中創(chuàng)建ApplicationContext的方式為(類路徑下的XML配置文件):

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

除了上面這種方式,Spring還提供了另外一種創(chuàng)建方式為(文件的絕對路徑):

ApplicationContext ctx = new FileSystemXmlApplicationContext("D:\workspace\spring\spring_10_container\src\main\resources\applicationContext.xml");Bean的三種獲取方式

方式一,就是目前案例中獲取的方式:

BookDao bookDao = (BookDao) ctx.getBean("bookDao");

這種方式存在的問題是每次獲取的時候都需要進(jìn)行類型轉(zhuǎn)換

方式二:

BookDao bookDao = ctx.getBean("bookDao",BookDao.class);

這種方式可以解決類型強(qiáng)轉(zhuǎn)問題,但是參數(shù)又多加了一個,相對來說沒有簡化多少。

方式三:

BookDao bookDao = ctx.getBean(BookDao.class);

這種方式就類似我們之前所學(xué)習(xí)依賴注入中的按類型注入。必須要確保IOC容器中該類型對應(yīng)的bean對象只能有一個。

容器類層次結(jié)構(gòu)

下面我們給出容器的層次圖


 

BeanFactory的使用

使用BeanFactory來創(chuàng)建IOC容器的具體實(shí)現(xiàn)方式為:

public class AppForBeanFactory { public static void main(String[] args) { Resource resources = new ClassPathResource("applicationContext.xml"); BeanFactory bf = new XmlBeanFactory(resources); BookDao bookDao = bf.getBean(BookDao.class); bookDao.save(); } }

為了更好的看出BeanFactory和ApplicationContext之間的區(qū)別,在BookDaoImpl添加如下構(gòu)造函數(shù):

public class BookDaoImpl implements BookDao { public BookDaoImpl() { System.out.println("constructor"); } public void save() { System.out.println("book dao save ..." ); } }

如果不去獲取bean對象,打印會發(fā)現(xiàn):

 

  • BeanFactory是延遲加載,只有在獲取bean對象的時候才會去創(chuàng)建
  • ApplicationContext是立即加載,容器加載的時候就會創(chuàng)建bean對象
  • ApplicationContext要想成為延遲加載,只需要按照如下方式進(jìn)行配置
  •  
核心概念總結(jié)

 

接下來我們對前面知識的一個總結(jié),共包含如下內(nèi)容:

容器相關(guān)

  • BeanFactory是IoC容器的頂層接口,初始化BeanFactory對象時,加載的bean延遲加載
  • ApplicationContext接口是Spring容器的核心接口,初始化時bean立即加載
  • ApplicationContext接口提供基礎(chǔ)的bean操作相關(guān)方法,通過其他接口擴(kuò)展其功能
  • ApplicationContext接口常用初始化類ClassPathXmlApplicationContext(常用)FileSystemXmlApplicationContext
bean相關(guān)

 


 

依賴注入相關(guān)


 

注解開發(fā)

在上述的開發(fā)中,我們采用xml配置文件的形式來說依舊顯得有些復(fù)雜

這時我們就需要發(fā)揮Spring的優(yōu)點(diǎn):簡化開發(fā),通過注解來簡化開發(fā)過程

下面我們會通過多個方面將Bean逐步轉(zhuǎn)化為注解

注解開發(fā)Bean

在前面的內(nèi)容中,我們的bean在xml配置文件中裝配

在后期,我們的bean可以采用注解的形式,直接在實(shí)現(xiàn)類中注解表示為bean

我們采用@Component定義bean,可以添加參數(shù)表示id,也可以不添加參數(shù),后期我們采用class類的類型來進(jìn)行匹配

package com.itheima.dao.impl; import com.itheima.dao.BookDao; import org.springframework.stereotype.Component; import org.springframework.stereotype.Controller; import org.springframework.stereotype.Repository; //@Component定義bean @Component("bookDao") public class BookDaoImpl implements BookDao { public void save() { System.out.println("book dao save ..."); } }package com.itheima.service.impl; import com.itheima.dao.BookDao; import com.itheima.service.BookService; import org.springframework.stereotype.Component; import org.springframework.stereotype.Service; //@Component定義bean @Component public class BookServiceImpl implements BookService { private BookDao bookDao; public void setBookDao(BookDao bookDao) { this.bookDao = bookDao; } public void save() { System.out.println("book service save ..."); bookDao.save(); } }

@Componenty延伸出了三種類型,在實(shí)現(xiàn)手法上是一致,但可以具體使用于各種類中(僅用于自我識別)

 

  • @Controller:用于表現(xiàn)層bean定義
  • @Service:用于業(yè)務(wù)層bean定義
  • @Repository:用于數(shù)據(jù)層定義
package com.itheima.dao.impl; import com.itheima.dao.BookDao; import org.springframework.stereotype.Component; import org.springframework.stereotype.Controller; import org.springframework.stereotype.Repository; //@Component定義bean //@Component("bookDao") //@Repository:@Component衍生注解 @Repository("bookDao") public class BookDaoImpl implements BookDao { public void save() { System.out.println("book dao save ..."); } }package com.itheima.service.impl; import com.itheima.dao.BookDao; import com.itheima.service.BookService; import org.springframework.stereotype.Component; import org.springframework.stereotype.Service; //@Component定義bean //@Component //@Service:@Component衍生注解 @Service public class BookServiceImpl implements BookService { private BookDao bookDao; public void setBookDao(BookDao bookDao) { this.bookDao = bookDao; } public void save() { System.out.println("book service save ..."); bookDao.save(); } }

 

但是,在上述情況下,即使我們將@Component的類定義為bean

我們的xml文件是無法探測到的,所以我們需要配置相關(guān)掃描組件來掃描bean

純注解開發(fā)

我們前面所提到的注解開發(fā)屬于2.5的附屬版本

在Spring3.0版本,Spring就提供了純注解開發(fā)模式,利用java類代替配置文件,開啟了Spring快速開發(fā)時代

在之前我們的xml配置文件是很繁瑣的:

但是我們可以通過創(chuàng)建單獨(dú)的類來表示配置文件:

 

  • @Configuration:用于聲明當(dāng)前類為Spring配置類
  • @ComponentScan:用于掃描類文件(類似于)
package com.itheima.config; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; //聲明當(dāng)前類為Spring配置類 @Configuration //設(shè)置bean掃描路徑,多個路徑書寫為字符串?dāng)?shù)組格式 @ComponentScan({"com.itheima.service","com.itheima.dao"}) public class SpringConfig { }
注意:因?yàn)樵擃悓儆谂渲妙悾覀兺ǔ瘟幸粋€文件夾來表示 常用文件夾:config 命名規(guī)范:SpringConfig,UserConfig...

 

因?yàn)槲覀兊拈_發(fā)不再依靠于xml配置文件,所以在主函數(shù)中的Spring容器獲得方式也發(fā)生了改變:

package com.itheima; import com.itheima.dao.BookDao; import com.itheima.service.BookService; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class App { public static void main(String[] args) { // 這是我們之前的獲取方式,采用路徑獲取xml文件 // ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml"); // 這是新的獲取方式,直接提供配置類的類型 // AnnotationConfigApplicationContext加載Spring配置類初始化Spring容器 ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class); // 后面操作無需變化 BookDao bookDao = (BookDao) ctx.getBean("bookDao"); System.out.println(bookDao); //按類型獲取bean BookService bookService = ctx.getBean(BookService.class); System.out.println(bookService); } }注解開發(fā)Bean作用范圍與管理

既然我們的Bean開發(fā)從xml轉(zhuǎn)移到注解開發(fā),那么一些配置設(shè)置同樣發(fā)生改變

首先我們介紹Scope范圍的設(shè)置方式:

 

  • @Scope:定義bean的作用范圍
package com.itheima.dao.impl; import com.itheima.dao.BookDao; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Repository; import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; @Repository //@Scope設(shè)置bean的作用范圍(singleton或prototype),可以不添加默認(rèn)singleton @Scope("singleton") public class BookDaoImpl implements BookDao { public void save() { System.out.println("book dao save ..."); } }

 

然后我們介紹一下bean生命周期的init和destroy操作:

 

  • @PostConstruct:定義init操作,表示構(gòu)造后操作
  • @PreDestroy:定義destroy操作,表示銷毀前操作
依賴注入(自動裝配)

 

在Spring3.0中,省略掉了前面繁瑣的依賴注入,我們的bean依賴注入只留下了自動裝配這一操作:

 

  • 使用@Autowired注解開啟自動裝配模式(按類型)
  • 當(dāng)存在相同類型時,我們采用@Qualifier開啟按名自動裝配
package com.itheima.service.impl; import com.itheima.dao.BookDao; import com.itheima.service.BookService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; @Service public class BookServiceImpl implements BookService { //@Autowired:注入引用類型,自動裝配模式,默認(rèn)按類型裝配 @Autowired //@Qualifier:自動裝配bean時按bean名稱裝配 @Qualifier("bookDao") private BookDao bookDao; public void save() { System.out.println("book service save ..."); bookDao.save(); } }
注意:自動裝配基于反射設(shè)計創(chuàng)建對象并暴力反射對應(yīng)屬性為私有屬性初始化數(shù)據(jù),因此無需提供setter方法 注意:自動轉(zhuǎn)配建議使用無參構(gòu)造方法創(chuàng)建對象(默認(rèn)),如果不提供對應(yīng)構(gòu)造方法,請?zhí)峁┪ㄒ坏臉?gòu)造方法 注意:@Qualifier是基于@Autowired實(shí)現(xiàn)的,必須保證先有Autowired才能存在Qualifier

 

除了上述的bean類型裝配,我們的簡單類型裝配依舊存在:

 

  • 我們采用@Value的形式來配置簡單類型的值
package com.itheima.dao.impl; import com.itheima.dao.BookDao; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Repository; @Repository("bookDao") public class BookDaoImpl implements BookDao { //@Value:注入簡單類型(無需提供set方法) @Value("123") private String name; public void save() { System.out.println("book dao save ..." + name); } }

 

之所以使用@Value的形式配置,是因?yàn)槲覀兊念愋椭挡灰欢ㄊ怯墒謩虞斎氲模锌赡軄碜杂赑roperties資源:

 

  • 首先我們需要在Springconfig中配置相關(guān)資源
package com.itheima.config; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.PropertySource; @Configuration @ComponentScan("com.itheima") //@PropertySource加載properties配置文件 @PropertySource({"jdbc.properties"}) public class SpringConfig { }
  • 然后我們在數(shù)據(jù)層調(diào)用時,采用${}來匹配數(shù)據(jù)
package com.itheima.dao.impl; import com.itheima.dao.BookDao; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Repository; @Repository("bookDao") public class BookDaoImpl implements BookDao { //@Value:注入簡單類型(無需提供set方法) @Value("${name}") private String name; public void save() { System.out.println("book dao save ..." + name); } }注解開發(fā)第三方bean

 

我們在實(shí)際開發(fā)中不僅僅需要對自己的bean進(jìn)行管理,有時候可能需要引進(jìn)其他的bean

下面我們以Druid為例進(jìn)行講解:

 

  1. 首先在pom.xml中導(dǎo)入Druid坐標(biāo)
4.0.0 com.itheima spring_14_annotation_third_bean_manager 1.0-SNAPSHOT org.springframework spring-context 5.2.10.RELEASE com.alibaba druid 1.1.16
  1. 使用@Bean配置第三方Bean
// 該bean同樣屬于config文件,我們同樣放置在config文件夾下 // 在后續(xù)我們將會講解如何進(jìn)行連接 package com.itheima.config; import com.alibaba.druid.pool.DruidDataSource; import com.itheima.dao.BookDao; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import javax.sql.DataSource; public class JdbcConfig { // 1.定義一個方法獲得要管理的對象 // 2.添加@Bean,表示當(dāng)前方法的返回值是一個bean // @Bean修飾的方法,形參根據(jù)類型自動裝配 @Bean public DataSource dataSource(){ DruidDataSource ds = new DruidDataSource(); ds.setDriverClassName("com.mysql.jdbc.Driver"); ds.setUrl("jdbc:mysql://localhost:3306/spring_db"); ds.setUsername("root"); ds.setPassword("123456"); return ds; } }
  1. 將獨(dú)立的配置類加入核心配置(導(dǎo)入法)
// SpringConfig package com.itheima.config; import com.alibaba.druid.pool.DruidDataSource; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; import javax.sql.DataSource; @Configuration @ComponentScan("com.itheima") //@Import:導(dǎo)入配置信息(如果需要多個,同樣采用{}數(shù)組形式) @Import({JdbcConfig.class}) public class SpringConfig { }// JdbcConfig package com.itheima.config; import com.alibaba.druid.pool.DruidDataSource; import com.itheima.dao.BookDao; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import javax.sql.DataSource; //@Configuration public class JdbcConfig { //@Bean修飾的方法,形參根據(jù)類型自動裝配 @Bean public DataSource dataSource(){ DruidDataSource ds = new DruidDataSource(); // 配置信息 return ds; } }
注意:除了上述的導(dǎo)入法外還存在有其他方法,但導(dǎo)入法屬于主流,因此我們不介紹其他流派,感興趣的同學(xué)可以去查閱一下
注解開發(fā)為第三方導(dǎo)入資源

 

我們的第三方bean也可能需要導(dǎo)入部分資源,下面我們進(jìn)行簡單介紹:

 

  • 簡單類型依賴注入
package com.itheima.config; import com.alibaba.druid.pool.DruidDataSource; import com.itheima.dao.BookDao; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import javax.sql.DataSource; //@Configuration public class JdbcConfig { //1.定義一個方法獲得要管理的對象 @Value("com.mysql.jdbc.Driver") private String driver; @Value("jdbc:mysql://localhost:3306/spring_db") private String url; @Value("root") private String userName; @Value("root") private String password; //2.添加@Bean,表示當(dāng)前方法的返回值是一個bean //@Bean修飾的方法,形參根據(jù)類型自動裝配 @Bean public DataSource dataSource(){ DruidDataSource ds = new DruidDataSource(); ds.setDriverClassName(driver); ds.setUrl(url); ds.setUsername(userName); ds.setPassword(password); return ds; } }
  • 依賴類型依賴注入
package com.itheima.config; import com.alibaba.druid.pool.DruidDataSource; import com.itheima.dao.BookDao; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import javax.sql.DataSource; public class JdbcConfig { @Bean public DataSource dataSource(BookDao bookDao){ // 我們只需要調(diào)用即可,系統(tǒng)會為我們自動裝配 System.out.println(bookDao); } }
引入類型注入只需要為bean定義方法設(shè)置形參即可,容器會根據(jù)類型自動裝配對象
原文鏈接:https://www.cnblogs.com/qiuluoyuweiliang/p/16750470.html

分享到:
標(biāo)簽:Spring
用戶無頭像

網(wǎng)友整理

注冊時間:

網(wǎng)站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網(wǎng)站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網(wǎng)站吧!
最新入駐小程序

數(shù)獨(dú)大挑戰(zhàn)2018-06-03

數(shù)獨(dú)一種數(shù)學(xué)游戲,玩家需要根據(jù)9

答題星2018-06-03

您可以通過答題星輕松地創(chuàng)建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學(xué)四六

運(yùn)動步數(shù)有氧達(dá)人2018-06-03

記錄運(yùn)動步數(shù),積累氧氣值。還可偷

每日養(yǎng)生app2018-06-03

每日養(yǎng)生,天天健康

體育訓(xùn)練成績評定2018-06-03

通用課目體育訓(xùn)練成績評定