Spring基礎知識及入門

---恢復內容開始---html

spring框架概述java

1.1 什麼是spring

   Spring是一個開源框架,Spring是於2003 年興起的一個輕量級的Java 開發框架,由Rod Johnson 在其著做Expert One-On-One J2EE Development and Design中闡述的部分理念和原型衍生而來。它是爲了解決企業應用開發的複雜性而建立的。框架的主要優點之一就是其分層架構,分層架構容許使用者選擇使用哪個組件,同時爲 J2EE 應用程序開發提供集成的框架。Spring使用基本的JavaBean來完成之前只可能由EJB完成的事情。然而,Spring的用途不只限於服務器端的開發。從簡單性、可測試性和鬆耦合的角度而言,任何Java應用均可以從Spring中受益。Spring的核心是控制反轉(IoC)和麪向切面(AOP)。簡單來講,Spring是一個分層的JavaSE/EE full-stack(一站式) 輕量級開源框架。web

l 輕量級:與EJB對比,依賴資源少,銷燬的資源少。spring

l 分層: 一站式,每個層都提供的解決方案express

web層:strutsspring-MVC編程

service層:springapi

dao層:hibernatemybatis , jdbcTemplate  --> spring-data數組

1.2 spring核心服務器

 

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

  IoC(Inversion of control): 控制反轉控制權由對象自己轉向容器;由容器根據配置文件去建立實例並建立各個實例之間的依賴關係

 AOP(Aspect Oriented Programming),也就是面向方面編程的技術。AOP基於IoC基礎,是對OOP的有益補充。

1.3spring優勢

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

  • Spring就是一個大工廠(容器),能夠將全部對象建立和依賴關係維護,交給Spring管理
  • spring工廠是用於生成bean

l AOP編程的支持

  • Spring提供面向切面編程,能夠方便的實現對程序進行權限攔截、運行監控等功能

l 聲明式事務的支持

  • 只須要經過配置就能夠完成對事務的管理,而無需手動編程

l 方便程序的測試

  • SpringJunit4支持,能夠經過註解方便的測試Spring程序

l 方便集成各類優秀框架

  • Spring不排斥各類優秀的開源框架,其內部提供了對各類優秀框架(如:StrutsHibernateMyBatisQuartz等)的直接支持

l 下降JavaEE API的使用難度

  • Spring JavaEE開發中很是難用的一些APIJDBCJavaMail、遠程調用等),都提供了封裝,使這些API應用難度大大下降

 

 

1.4 spring體系結構

 

                                                                                                  

                                                                                                                                核心容器:beanscorecontextexpression

 

入門案例:IoC【掌握】

1.1 導入jar

l 4 + 1  : 4個核心(beanscorecontextexpression) + 1個依賴(commons-loggins...jar

 

 

 

 

1.2 目標類

l 提供UserService接口和實現類

l 得到UserService實現類的實例

以前開發中,直接new一個對象便可。

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

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

public interface UserService {

 

public void addUser();

 

}

 

public class UserServiceImpl implements UserService {

 

@Override

public void addUser() {

System.out.println("a_ico add user");

}

 

}

 

1.3 配置文件

l 位置:任意,開發中通常在classpath下(src

l 名稱:任意,開發中經常使用applicationContext.xml

l 內容:添加schema約束

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

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

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

       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">

<!-- 配置service 

<bean> 配置須要建立的對象

id :用於以後從spring容器得到實例時使用的

class :須要建立實例的全限定類名

-->

<bean id="userServiceId" class="com.zqy.a_ioc.UserServiceImpl"></bean>

</beans>

 

 

1.4 測試

@Test

public void demo02(){

//spring容器得到

//1 得到容器

String xmlPath = "com/zqy/a_ioc/beans.xml";

ApplicationContext applicationContext = new ClassPathXmlApplicationContext(xmlPath);

//2得到內容 --不須要本身new,都是從spring容器得到

UserService userService = (UserService) applicationContext.getBean("userServiceId");

userService.addUser();

 

}

 

 

 

 

入門案例:DI【掌握】

l DI Dependency Injection ,依賴注入

is a :是一個,繼承。

has a:有一個,成員變量,依賴。

class B {

           private A a;   //B類依賴A

        }

依賴:一個對象須要使用另外一個對象

注入:經過setter方法進行另外一個對象實例設置。

l 例如:

class BookServiceImpl{

        //以前開發:接口 實現類  (servicedao耦合)

//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設置給servicebookService.setBookDao(bookDao); -->DI   <property>

 

2.1 目標類

l 建立BookService接口和實現類

l 建立BookDao接口和實現類

l 將daoservice配置 xml文件

l 使用api測試

2.1.1 dao

public interface BookDao {

 

public void addBook();

 

}

public class BookDaoImpl implements BookDao {

 

@Override

public void addBook() {

System.out.println("di  add book");

}

 

}

 

 

2.1.2 service

 

public interface BookService {

 

public abstract void addBook();

 

}

public class BookServiceImpl implements BookService {

 

// 方式1:以前,接口=實現類

// private BookDao bookDao = new BookDaoImpl();

// 方式2:接口 + setter

private BookDao bookDao;

public void setBookDao(BookDao bookDao) {

this.bookDao = bookDao;

}

 

@Override

public void addBook(){

this.bookDao.addBook();

}

 

}

 

 

2.2 配置文件

 

 

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

       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">

<!-- 

模擬spring執行過程

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

建立dao實例:BookDao bookDao = new BookDaoImpl() IoC

dao設置給servicebookService.setBookDao(bookDao); DI   <property>

 

<property> 用於進行屬性注入

name: bean的屬性名,經過setter方法得到

setBookDao ##> BookDao  ##> bookDao

ref :另外一個beanid值的引用

 -->

 

<!-- 建立service -->

<bean id="bookServiceId" class="com.zqy.b_di.BookServiceImpl">

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

</bean>

 

<!-- 建立dao實例 -->

<bean id="bookDaoId" class="com.zqy.b_di.BookDaoImpl"></bean>

 

 

</beans>

 

 

2.3 測試

@Test

public void demo01(){

//spring容器得到

String xmlPath = "com/zqy/b_di/beans.xml";

ApplicationContext applicationContext = new ClassPathXmlApplicationContext(xmlPath);

BookService bookService = (BookService) applicationContext.getBean("bookServiceId");

 

bookService.addBook();

 

}

 

myeclipse schema xml提示

l 步驟一:肯定xsd文件位置

spring-framework-3.2.0.RELEASE\schema\beans

 

 

l 步驟二:複製路徑

 

 

l 步驟三:搜索「xml catalog

 

 

 

l 步驟四:添加約束提示

 

 

 

核心API

l api總體瞭解,以後不使用,在學習過程須要。

 

 

l BeanFactory :這是一個工廠,用於生成任意bean

採起延遲加載,第一次getBean時纔會初始化Bean

l ApplicationContext:是BeanFactory的子接口,功能更強大。(國際化處理、事件傳遞、Bean自動裝配、各類不一樣應用層的Context實現)。當配置文件被加載,就進行對象實例化。

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

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

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

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

經過java web ServletContext.getRealPath() 得到具體盤符

 

@Test

public void demo02(){

//使用BeanFactory  --第一次條用getBean實例化

String xmlPath = "com/zqy/b_di/beans.xml";

 

BeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource(xmlPath));

 

BookService bookService = (BookService) beanFactory.getBean("bookServiceId");

 

bookService.addBook();

 

}

 

 

 

裝配Bean 基於XML

5.1 實例化方式

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

 

5.1.1 默認構造

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

 

5.1.2 靜態工廠

l 經常使用與spring整合其餘框架(工具)

l 靜態工廠:用於生成實例對象,全部的方法必須是static

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

 

5.1.2.1 工廠

public class MyBeanFactory {

 

/**

 * 建立實例

 * @return

 */

public static UserService createService(){

return new UserServiceImpl();

}

}

 

5.1.2.2 spring配置

<!-- 將靜態工廠建立的實例交予spring 

class 肯定靜態工廠全限定類名

factory-method 肯定靜態方法名

-->

<bean id="userServiceId" class="com.zqy.c_inject.b_static_factory.MyBeanFactory" factory-method="createService"></bean>

 

5.1.3 實例工廠

l 實例工廠:必須先有工廠實例對象,經過實例對象建立對象。提供全部的方法都是「非靜態」的。

 

5.1.3.1 工廠

/**

 * 實例工廠,全部方法非靜態

 *

 */

public class MyBeanFactory {

 

/**

 * 建立實例

 * @return

 */

public UserService createService(){

return new UserServiceImpl();

}

 

}

 

5.1.3.2 spring配置

 

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

<bean id="myBeanFactoryId" class="com.zqy.c_inject.c_factory.MyBeanFactory"></bean>

<!-- 得到userservice 

* factory-bean 肯定工廠實例

* factory-method 肯定普通方法

-->

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

 

 

 

5.2 Bean種類

l 普通bean:以前操做的都是普通bean<bean id="" class="A"> spring直接建立A實例,並返回

l FactoryBean:是一個特殊的bean,具備工廠生成對象能力,只能生成特定的對象。

bean必須使用 FactoryBean接口,此接口提供方法 getObject() 用於得到特定bean

<bean id="" class="FB"> 先建立FB實例,使用調用getObject()方法,並返回方法的返回值

FB fb = new FB();

return fb.getObject();

l BeanFactory 和 FactoryBean 對比?

BeanFactory:工廠,用於生成任意bean

FactoryBean:特殊bean,用於生成另外一個特定的bean。例如:ProxyFactoryBean ,此工廠bean用於生產代理。<bean id="" class="....ProxyFactoryBean"> 得到代理對象實例。AOP使用

 

5.3 做用域

 

l 做用域:用於肯定spring建立bean實例個數

 

l 取值:

singleton 單例,默認值。

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

l 配置信息

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

                                 

 

 

<bean id="userServiceId" class="com.zqy.d_scope.UserServiceImpl" 

scope="prototype" ></bean>

 

 

5.4 生命週期

5.4.1 初始化和銷燬

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

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

 

5.4.1.1 目標類

public class UserServiceImpl implements UserService {

 

@Override

public void addUser() {

System.out.println("e_lifecycle add user");

}

 

public void myInit(){

System.out.println("初始化");

}

public void myDestroy(){

System.out.println("銷燬");

}

 

}

 

5.4.1.2 spring配置

<!--  

init-method 用於配置初始化方法,準備數據等

destroy-method 用於配置銷燬方法,清理資源等

-->

<bean id="userServiceId" class="com.zqy.e_lifecycle.UserServiceImpl" 

init-method="myInit" destroy-method="myDestroy" ></bean>

 

5.4.1.3 測試

@Test

public void demo02() throws Exception{

//spring 工廠

String xmlPath = "com/zqy/e_lifecycle/beans.xml";

ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext(xmlPath);

UserService userService = (UserService) applicationContext.getBean("userServiceId");

userService.addUser();

 

//要求:1.容器必須close,銷燬方法執行; 2.必須是單例的

// applicationContext.getClass().getMethod("close").invoke(applicationContext);

// * 此方法接口中沒有定義,實現類提供

applicationContext.close();

 

}

 

5.4.2 BeanPostProcessor 後處理Bean

l spring 提供一種機制,只要實現此接口BeanPostProcessor,並將實現類提供給spring容器,spring容器將自動執行,在初始化方法前執行before(),在初始化方法後執行after() 。 配置<bean class="">

 

 

l Factory hook(勾子) that allows for custom modification of new bean instances, e.g. checking for marker interfaces or wrapping them with proxies. 

l spring提供工廠勾子,用於修改實例對象,能夠生成代理對象,是AOP底層。

模擬

A a =new A();

a = B.before(a) --> a的實例對象傳遞給後處理bean,能夠生成代理對象並返回。

a.init();

a = B.after(a);

 

a.addUser(); //生成代理對象,目的在目標方法先後執行(例如:開啓事務、提交事務)

 

a.destroy()

 

5.4.2.1 編寫實現類

public class MyBeanPostProcessor implements BeanPostProcessor {

 

@Override

public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {

System.out.println("前方法 : " + beanName);

return bean;

}

 

@Override

public Object postProcessAfterInitialization(final Object bean, String beanName) throws BeansException {

System.out.println("後方法 : " + beanName);

// bean 目標對象

// 生成 jdk 代理

return Proxy.newProxyInstance(

MyBeanPostProcessor.class.getClassLoader(), 

bean.getClass().getInterfaces(), 

new InvocationHandler(){

@Override

public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

 

System.out.println("------開啓事務");

 

//執行目標方法

Object obj = method.invoke(bean, args);

 

System.out.println("------提交事務");

return obj;

}});

}

}

 

5.4.2.2 配置

<!-- 將後處理的實現類註冊給spring -->

<bean class="com.zqy.e_lifecycle.MyBeanPostProcessor"></bean>

 

l 問題1:後處理bean做用某一個目標類,仍是全部目標類?

全部

l 問題2:如何只做用一個?

經過「參數2beanName進行控制

 

5.5 屬性依賴注入

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

l 手動裝配:通常進行配置信息都採用手動

基於xml裝配:構造方法、setter方法

基於註解裝配:

l 自動裝配:strutsspring 整合能夠自動裝配

byType:按類型裝配 

byName:按名稱裝配

constructor構造裝配,

auto: 不肯定裝配。

5.5.1 構造方法

5.5.1.1 目標類

public class User {

 

private Integer uid;

private String username;

private Integer age;

 

public User(Integer uid, String username) {

super();

this.uid = uid;

this.username = username;

}

 

public User(String username, Integer age) {

super();

this.username = username;

this.age = age;

}

 

 

5.5.1.2 spring配置

<!-- 構造方法注入 

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

name :參數的名稱

value:設置普通數據

ref:引用數據,通常是另外一個bean id

 

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

type :肯定參數類型

例如:使用名稱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>

-->

<bean id="userId" class="com.zqy.f_xml.a_constructor.User" >

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

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

</bean>

5.5.2 setter方法

<!-- setter方法注入 

普通數據 

<property name="" value="">

等效

<property name="">

<value>

引用數據

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

等效

<property name="">

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

 

-->

<bean id="personId" class="com.zqy.f_xml.b_setter.Person">

<property name="pname" value="陽志"></property>

<property name="age">

<value>1234</value>

</property>

 

<property name="homeAddr" ref="homeAddrId"></property>

<property name="companyAddr">

<ref bean="companyAddrId"/>

</property>

</bean>

 

<bean id="homeAddrId" class="com.zqy.f_xml.b_setter.Address">

<property name="addr" value="阜南"></property>

<property name="tel" value="911"></property>

</bean>

<bean id="companyAddrId" class="com.zqy.f_xml.b_setter.Address">

<property name="addr" value="北京八寶山"></property>

<property name="tel" value="120"></property>

</bean>

 

5.5.3 P命令空間[瞭解]

l 對「setter方法注入」進行簡化,替換<property name="屬性名">,而是在

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

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

 

 

 

<bean id="personId" class="com.zqy.f_xml.c_p.Person" 

p:pname="禹太璞" p:age="22" 

p:homeAddr-ref="homeAddrId" p:companyAddr-ref="companyAddrId">

</bean>

 

<bean id="homeAddrId" class="com.zqy.f_xml.c_p.Address"

p:addr="DG" p:tel="東莞">

</bean>

<bean id="companyAddrId" class="com.zqy.f_xml.c_p.Address"

p:addr="DG" p:tel="島國">

</bean>

 

 

 

5.5.4 集合注入

<!-- 

集合的注入都是給<property>添加子標籤

數組:<array>

List<list>

Set<set>

Map<map> map存放k/v 鍵值對,使用<entry>描述

Properties<props>  <prop key=""></prop>  【】

 

普通數據:<value>

引用數據:<ref>

-->

<bean id="collDataId" class="com.zqy.f_xml.e_coll.CollData" >

<property name="arrayData">

<array>

<value>DS</value>

<value>DZD</value>

<value>屌絲</value>

<value>屌中屌</value>

</array>

</property>

 

<property name="listData">

<list>

<value>於嵩楠</value>

<value>曾衛</value>

<value>楊煜</value>

<value>曾小賢</value>

</list>

</property>

 

<property name="setData">

<set>

<value>H封</value>

<value>J紙</value>

<value>A系</value>

</set>

</property>

 

<property name="mapData">

<map>

<entry key="jack" value="傑克"></entry>

<entry>

<key><value>rose</value></key>

<value>肉絲</value>

</entry>

</map>

</property>

 

<property name="propsData">

<props>

<prop key="高富帥">ASD</prop>

<prop key="白富美">AS</prop>

<prop key="男屌絲">GG</prop>

</props>

</property>

</bean>

 

 

 

 

 

 

 

裝配Bean 基於註解

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

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

 

 

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

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

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

@Repository dao

@Serviceservice

@Controllerweb

3.依賴注入 ,給私有字段設置,也能夠給setter方法設置

普通值:@Value("")

引用值:

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

@Autowired

方式2:按照【名稱】注入1

@Autowired

@Qualifier("名稱")

方式3:按照【名稱】注入2

@Resource("名稱")

4.生命週期

初始化:@PostConstruct

銷燬:@PreDestroy

5.做用域

@Scope("prototype") 多例

 

l 註解使用前提,添加命名空間,讓spring掃描含有註解類

 

 

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

       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

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

       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.zqy.g_annotation.a_ioc"></context:component-scan>

</beans>

相關文章
相關標籤/搜索