1. 程式人生 > >spring框架概述

spring框架概述

destroy tac expr proto service ima ops 程序 repo

1 spring框架概述

1.1 什麽是spring

Spring是一個開源框架,Spring是於2003 年興起的一個輕量級的Java 開發框架,由Rod Johnson開發。

它是為了解決企業應用開發的復雜性而創建的。框架的主要優勢之一就是其分層架構,分層架構允許使用者選擇使用哪一個組件,同時為 J2EE 應用程序開發提供集成的框架

dao(JdbcTemplate) service(spring控制事務) web(springmvc)

Spring的核心是控制反轉(IoC)和面向切面(AOP)。

簡單來說,Spring是一個分層的JavaSE/EE full-stack 輕量級開源框架。 1)IoC 和DI 2)AOP

一句話描述spring:full-stack 輕量級開源框架

分層: full-stack,每一個層都提供解決方案

web層:struts,spring-MVC

service層:spring 事務控制 spring

dao層:hibernate,mybatis , jdbcTemplate(spring提供了一個模板對象) --> spring-data

技術分享圖片

ssh:struts2+spring+hibernate(以前的了解一下)

ssm:spring+springmvc+mybatis(現階段常用)

1.2 spring核心

Spring的核心是控制反轉(IoC面向切面(AOP

1.3 spring優點

1. 方便解耦,簡化開發 (高內聚低耦合)

  • Spring就是一個大工廠(容器),可以將所有對象創建和依賴關系維護,交給Spring管理
  • spring工廠是用於生成bean (靜態工廠模式)

面試題:spring的IoC(控制反轉)底層用到什麽設計模式?-- 靜態工廠模式

2. AOP編程的支持

  • Spring提供面向切面編程,可以方便的實現對程序進行權限攔截、運行監控等功能
  • 打印日誌
  • 面試題: aop的底層運用到什麽設計模式? -- 動態代理

3. 聲明式事務的支持 (AOP 動態代理)

  • 只需要通過配置就可以完成對事務的管理,而無需手動編程

4. 方便程序的測試

  • Spring對Junit4支持,可以通過註解方便的測試Spring程序
  • @RunWith(SpringJUnit4ClassRunner.class)
  • @ContextConfiguration("applicationContext.xml")

5. 方便集成各種優秀框架 *****

  • Spring不排斥各種優秀的開源框架,其內部提供了對各種優秀框架(如:Struts、Hibernate、MyBatis、Quartz(任務調度)等)的直接支持
  • Redis
  • Solr 搜索引擎
  • 消息隊列 ActiveMQ
  • ……

6. 降低JavaEE API的使用難度 EJB

  • Spring 對JavaEE開發中非常難用的一些API(JDBC、JavaMail、遠程調用等),都提供了封裝,使這些API應用難度大大降低

1.4 spring體系結構

技術分享圖片

核心容器:beans、core、context、expression

dao service 對象的創建 交給spring

2 入門案例:IoC【掌握】

2.1 導入jar包

4 + 1 : 4個核心(beans、core、context、expression) + 1個依賴(commons-loggins...jar)

2.2 目標類

1. 提供UserService接口和實現類

2. 獲得UserService實現類的實例

之前開發中,直接new一個對象即可。

UsersService service = new UsersServiceImpl();

學習spring之後,將由Spring創建對象實例--> IoC 控制反轉(Inverse of Control)

之後需要實例對象時,從spring工廠(容器)中獲得,需要將實現類的全限定名稱配置到xml文件中

把創建對象的過程交給spring來創建,IoC

2.3 配置文件

1. 位置:任意,開發中一般在classpath下(src)

2. 名稱:任意,開發中常用applicationContext.xml

不是必須的。

3. 內容:添加schema約束

約束文件位置:spring-framework-XXX.RELEASE\docs\spring-framework-reference\html\ xsd-config.html

<bean id="userService" name="us" class="com.itqf.service.impl.UserServiceImpl"></bean>

2.4 測試

//創建ApplicationContext對象

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

//根據spring的核心對象解析applicationContext.xml配置文件 從配置文件中獲取一個UserService 對象

//從spring的配置文件中獲取對象的三種方式

//方式一:根據對象的class

UserService userService = aContext.getBean(UserService.class);

//單詞寫錯:NoSuchBeanDefinitionException: No bean named ‘userService11‘ available

UserService userService2 = (UserService) aContext.getBean("userService");

UserService userService3 = (UserService) aContext.getBean("us");

System.out.println(userService==userService2);

3 DI案例【掌握】 依賴註入

1. DI Dependency Injection ,依賴註入

類與類之間的依賴關系,由spring通過spring註入 ---依賴註入

class B {

private A a = new A(); //B類依賴A類 Service依賴dao

}

依賴:一個對象需要使用另一個對象

註入:通過setter方法(或其他方式)進行另一個對象實例設置。

class B {

private A a ;//B類依賴A類 Service依賴dao

}

a對象由spring通過setter方法註入

2. 例如:練習

class BookServiceImpl{

//之前開發:接口 = 實現類 (service和dao耦合)

//private BookDao bookDao = new BookDaoImpl();

//spring之後 (解耦:service實現類使用dao接口,不知道具體的實現類)

private BookDao bookDao;

setter方法

}

模擬spring執行過程

創建service實例:BookService bookService = new BookServiceImpl() -->IoC <bean>

創建dao實例:BookDao bookDao = new BookDaoImple() -->IoC

將dao設置給service:bookService.setBookDao(bookDao); -->DI <property

IoC:把創建對象的過程交給了Spring (<bean ………………>)

DI:通過調用setXXX方法註入另外的對象 <property name=”” ref=””>

<!-- 1.dao

等價於: BookDao bookDao = new BookDaoImpl();

-->

<bean id="bookDao" class="com.itqf.di.dao.impl.BookDaoImpl"></bean>

<!-- service

等價於:

BookService bookService = new BookServiceImpl();

bookService.setBookDao(bookDao);

-->

<bean id="bookService" class="com.itqf.di.service.impl.BookServiceImpl">

<!-- 註入dao -->

<property name="bookDao" ref="bookDao" ></property>

</bean>

4 schema xml提示

1. 步驟一:確定xsd文件位置

spring-framework-RELEASE\schema\beans

2. 步驟二:復制路徑

技術分享圖片

3. 步驟三:搜索“xml catalog”

4. 步驟四:添加約束提示

技術分享圖片

5 核心API

1. api整體了解,之後不使用,在學習過程需要。

技術分享圖片

2. BeanFactory :這是一個工廠,用於生成任意bean。 創建對象

采取延遲加載,第一次getBean時才會初始化Bean

3. ApplicationContext:是BeanFactory的子接口,功能更強大。當配置文件被加載,就進行對象實例化。

ClassPathXmlApplicationContext 用於加載classpath(類路徑、src)下的xml

加載xml運行時位置 --> /WEB-INF/classes/...xml

FileSystemXmlApplicationContext 用於加載指定盤符下的xml

加載xml運行時位置 --> /WEB-INF/...xml

通過java web ServletContext.getRealPath() 獲得具體盤符

BeanFactory

FactoryBean 區別?

6 實例化Bean 基於XML

6.1 實例化方式

l 3種bean實例化方式:默認構造、靜態工廠、實例工廠

6.1.1 默認構造(常用)

<bean id="" class=""> 必須提供默認構造

6.1.2 靜態工廠

1. 常用與spring整合其他框架(工具)

2. 靜態工廠:用於生成實例對象,所有的方法必須是static

<bean id="" class="工廠全限定類名" factory-method="靜態方法">

編寫靜態工廠類

<bean id="userServiceId" class="工廠類對象全路徑 " factory-method="createService"></bean>

6.1.3 實例工廠

1. 實例工廠:必須先有工廠實例對象,通過實例對象創建對象。提供所有的方法都是“非靜態”的

普通的工廠類 (非靜態方法).

<!-- 創建工廠實例 -->

<bean id="myBeanFactoryId" class="工廠對象全路徑 "></bean>

<!-- 獲得userservice

* factory-bean 確定工廠實例

* factory-method 確定普通方法

-->

<bean id="userServiceId" factory-bean="myBeanFactoryId" factory-method="createService"></bean>

7 作用域

面試:spring bean的作用域? / springBean的scope的取值?

作用域:用於確定spring創建bean實例個數

servlet:單例

struts2:action(處理請求):多例

面試題: struts2是線程安全還是不安全的?

安全的。

spring:bean:默認是單例

bean標簽有scope屬性可以設置bean的作用域。

技術分享圖片

取值:

singleton 單例,默認值。

prototype 多例,每執行一次getBean將獲得一個實例。例如:struts整合spring,配置action多例。

面試題: 什麽時候bean的作用域需要設計為多例的?

Ssh整合(或者struts2和spring整合時),action的創建交給spring創建,需要給bean設計為多例的。

配置信息

<bean id="" class="" scope="">

8 生命周期

8.1 初始化和銷毀

l 目標方法執行前後執行後,將進行初始化或銷毀。

<bean id="" class="" init-method="初始化方法名稱" destroy-method="銷毀的方法名稱">

<bean id="userDao" name="userDao2" class="com.itqf.lifecycle.UserDao"

init-method="init" destroy-method="destory"></bean>

9 依賴註入

9.1 屬性依賴註入

依賴註入方式:手動裝配 和 自動裝配

手動裝配:一般進行配置信息都采用手動

基於xml裝配:構造方法、setter方法 、 p標簽註入

基於註解裝配:@autowrired @resource

自動裝配:

autowire="byName"

byType:按類型裝配

byName:按名稱裝配

constructor構造裝配,

auto: 不確定裝配。

9.1.1 構造方法

<constructor-arg> 用於配置構造方法一個參數argument

name :參數的名稱

value:設置普通數據

ref:引用數據,一般是另一個bean id值

index :參數的索引號,從0開始 。如果只有索引,匹配到了多個構造方法時,默認使用第一個。

type :確定參數類型

例如1:使用名稱name

<constructor-arg name="username" value="jack"></constructor-arg>

<constructor-arg name="age" value="18"></constructor-arg>

例如2:【類型type 和 索引 index】

<constructor-arg index="0" type="java.lang.String" value="1"></constructor-arg>

<constructor-arg index="1" type="java.lang.Integer" value="2"></constructor-arg>

9.1.2 setter方法

普通數據

<property name="" value="值">

等效

<property name=""> <value>值</value>

引用數據

<property name="" ref="另一個bean">

等效

<property name="">

<ref bean="另一個bean"/>

9.1.3 P命令空間[了解]

對“setter方法註入”進行簡化,替換<property name="屬性名">,而是在

<bean p:屬性名="普通值" p:屬性名-ref="引用值">

p命名空間使用前提,必須添加命名空間

<bean id="userService" class="com.itqf.bean.p.UserServiceImpl" p:userDao-ref="userDao" >

</bean>

<bean scope="prototype" id="userAction" class="com.itqf.bean.p.UserAction" p:userService-ref="userService"></bean>

9.1.4 集合註入

<bean id="myCollection" class="com.itqf.bean.collection.MyCollection" autowire="default">

<property name="name" value="天線寶寶"></property>

<!-- 數組 -->

<property name="arr">

<array>

<value>張三</value>

<value>lisi</value>

<value>王蘇</value>

</array>

</property>

<!-- 集合 -->

<property name="list">

<list>

<value>basketball</value>

<value>football</value>

<value>pingpongball</value>

</list>

</property>

<!-- set -->

<property name="set">

<set>

<value>寶馬</value>

<value>勞斯萊斯</value>

<value>法拉利</value>

<value>賓利</value>

<value>QQ</value>

</set>

</property>

<!-- Map -->

<property name="map">

<map>

<entry>

<key><value>1001</value></key>

<value>張三</value>

</entry>

<entry>

<key><value>1002</value></key>

<value>李四</value>

</entry>

<entry>

<key><value>1003</value></key>

<value>趙六</value>

</entry>

</map>

</property>

<!-- properties 類型 -->

<property name="properties">

<props>

<prop key="jdbc.driverClass">com.mysql.jdbc.Driver</prop>

<prop key="jdbc.url">jdbc:mysql://localhost:3306/book</prop>

</props>

</property>

</bean>

10 使用註解(常用重點)

面試題:請說出spring常用的註解有哪些?

l 註解:就是一個類,使用@註解名稱

l 開發中:使用註解 取代 xml配置文件。

1. @Component取代<bean class="">

@Component("id") 取代 <bean id="" class="">

2.web開發,提供3個@Component註解衍生註解(功能一樣)取代<bean class="">

@Repository :dao層

@Service:service層

@Controller:web層

3.依賴註入,給私有字段設置,也可以給setter方法設置

引用值:

方式1:按照【類型】註入

@Autowired

private BookDao bookDao;

方式2:按照【名稱】註入2

@Resource( name="名稱")

eg:

@Resource( name="bookDao")

private BookDao bookDao; spring容器中找name為bookDao

方式3:按照類型註入(autowired)時,如果有兩個匹配結果,會報錯

可以使用如下解決方案:

@Qualifier("userServiceImpl2")

//@Autowired //按照類型註入 但是,如果找到多個匹配的就會報錯,expected single matching bean but found 2

//@Qualifier("userServiceImpl2") //按照名稱註入

註意:@Qualifier不能當獨使用,一般配合autowired使用

//@Autowired 按照類型註入

//@Qualifier("userServiceImpl") //按照名稱註入

@Resource(name="userServiceImpl") //按照名稱註入

private UserService userService;

//註入dao

@Autowired //按照類型註入

public void setUserDao(UserDao userDao) {

this.userDao = userDao;

}

創建對象:

四個:

@Componet

@Repository dao

@Service service

@Controller 控制層

註入:

@Autowired 按照類型註入 (spring提供)

@Qulifer() 配合Autowired 使用(用的少)

@Resource() 按照名稱註入 (jdk)



4.生命周期

初始化:@PostConstruct

銷毀: @PreDestroy

5.作用域 (類前)

@Scope("prototype") 多例

l

註意:

註解使用前提,導入aop的包,添加命名空間,讓spring掃描含有註解類

spring-aop-4.3.5.RELEASE.jar

在配置文件中添加context標簽:

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"

xmlns:context="http://www.springframework.org/schema/context"

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

http://www.springframework.org/schema/context

http://www.springframework.org/schema/context/spring-context.xsd">

<!—掃描含有註解的包-->

<context:component-scan base-package="com.qf.annotation"></context:component-scan>

6. 普通屬性有關的註解

@value 註入屬性值

1、加在成員變量上:通過反射的Field賦值(破壞對象的封裝性)

@Value("慧慧")

private String name;

2、加在set方法上:通過set方法賦值

@Value("tom")

public void setName(String name) {

this.name = name;

}

@Value直接讀取properties文件中的內容

a1 配置文件

<!-- 掃描properties文件 -->

<context:property-placeholder location="classpath:dbinfo.properties"/> <!—掃描一次-->

<!-- 掃描帶有註解的包

指定要掃描的包

-->

<context:component-scan base-package="com.itqf"></context:component-scan>

b1 在類中使用@value註解讀取配置文件中的內容

@value(“${properties配置文件中的key}”)

@Value("${jdbc.driver}")

private String driverClassName;

@Value("${jdbc.url}")

private String url;

@Value("${jdbc.username}")

private String username;

@Value("${jdbc.password}")

private String password;

11 Spring整合JUnit4測試

spring整合junit,為我們提供了方便的測試方式

1、導包:在spring-02-annotation項目中再加入如下包

spring-test-4.3.5.RELEASE.jar

junit4的包

2、創建測試類

//創建容器

@RunWith(SpringJUnit4ClassRunner.class)

//指定創建容器時使用哪個配置文件

@ContextConfiguration("classpath:applicationContext.xml")

public class RunWithTest {

//將名為user的對象註入到u變量中

@Resource(name="person")

private Person p;

@Test

public void testCreatePerson(){

System.out.println(p);

}

}

IoC:控制反轉 ,把對象的創建反轉給spring來創建。

底層:靜態工廠

DI:依賴註入,把類與類之間的依賴關系,交給spring註入。

功能:減少耦合度

創建對象三種方式:

bean中

inti-method

distory-method

bean的作用域

scope=”singleton” 默認 單例

prototype 多例

註入:

構造器註入

setter

p標簽註入

spring框架概述