spring系列知識速記

一、bean注入方式

1、設值注入
2、構造注入


二、bean配置項

bean配置項
Id 標識符
Class 指定類                                              
Scope 作用域
Constructor  arguments 構造器參數
Properties 自身屬性
Aotowiring mode 自動裝配模式
Lazy-initialization mode 懶加載模式
Initialization/destruction method 初始化/銷燬方法


Scope

  • singleton:單例,一個bean容器只存在一份
  • prototype:每次請求創建新的實例,destroy無效
  • request:每次http請求創建一個實例且僅在當前request有效
  • session:同上,
  • global session:基於portle的web中有效(portle中定義了global session),如果是在web中,同session


三、bean生命週期


1、初始化

  • 實現org.springframework.beans.factory.InitializingBean接口,覆蓋afterPropetiesSet方法
  • 配置init-method


2、銷燬

  • 實現org.springframework.beans.factory.DisposableBean接口,覆蓋destory方法;
  • 配置destory-method

配置有全局配置,bean中配置。當三種方法都存在時,全局配置不起作用。其他兩種都會執行,且實現接口方法先於bean中配置執行


四、bean裝配


1、Aware接口

  • ApplicationContextAware :爲實現此接口的bean提供上下文信息;
  • BeanNameAware:提供bean在工廠中的id,提供了回調自身的能力
  • ApplicationEventPublisherAware:bean事件發佈
  • BeanClassLoaderAware:bean加載容器
  • BeanFactoryAware:獲取beanfactory

可以先通過BeanNameAware接口得到beanName,再通過ApplicationContextAware接口的getbean獲取該bean


2、bean的自動裝配(Autowiring)

  • No:不做任何操作
  • byname:根據屬性名自動裝配,(根據set***方法的後面名字首字母小寫匹配bean配置中id的)
  • byType:根據屬性自動裝配。如果存在多個會拋出異常,不存在什麼事都不會發生
  • Constuctor:與byType方式類似,不同之處在於它應用於構造參數。

自動裝配意義在於不需要在手動注入了 ,使配置更加簡潔方便。在xml的【beans】中配置。


3、bean註解

  • @Component  是一個通用註解,可用於任何bean,一般用於註冊bean並指定一個id
  • @Repository  通常用於註解DAO類,即持久層
  • @Service 通常用於註解Service類,即持久層
  • @Controller 通常用於Controller類,即控制層
  •  記得加上<context:component-scan>

參考資料:spring常用註解

元註解:註解的註解,可以將多條註解自定義爲一個註解

參考資料:Spring4.0系列4-Meta Annotation(元註解)

bean的自動檢和註冊:


Spring可以將上面四個註解的bean自動註冊到容器(ApplicationContext)中,都有個name屬性可以顯示的設值bean的id,在xml中需要配置自動註冊路徑

bean的名稱是由BeanNameGenerrator生成的,要自定義命名策略可以實現該接口並一定要包含一個無參構造器,並在<context:component-scan>;的name-generator中配置使用。

參考資料:Spring <context:annotation-config/> 解說 

Spring 開啓Annotation <context:annotation-config> 和 <context:component-scan>詮釋及區別

注意使用context配置時需要加上相應的命名空間。


自動註冊可以通過<context:component-scan>的屬性配置要註冊的文件和要排除的文件;

自動註冊的bean作用域默認是:singleton,可以@Scope指定,也可以使用自定義的scope策略,要實現ScopeMetadataResolver接口,並類似上面自定義命名規則的當時註冊

可以使用scoped-proxy屬性指定代理。三個可選值:no,interfaces,targetClass

@Required註解:適用於bean方法的setter方法,表示當被註解的屬性在bean被裝配時必須被設置,否則會拋出BeanInitializationException異常

@Autowired註解:可用於構造器、方法或成員變量,可以用此註解替代上面提到的Autowiring自動裝配不用再寫太多配置也不用再寫set方法,方便快捷;如果找不到合適的bean將會拋出異常,可以通過required=false來避免。

@inject等效@AutoWiried        @Named 等效Component  @Named還可根據name注入字段

常見使用:

@AutoWired經常用來註解哪些衆所周知的接口,來直接獲取這些接口

@Autowired也可以通過添加註解給一些數組的字段或方法,來獲取applicationContext中所有特定類型的bean

注意:@Autowired由Spring的BeanPostProcessor處理的,不能在 自己的BeanPostProcessor或BeanFactoryPosrProcessor類型應用這些註解,這些類型必須通過XML或者Spring的@Bean註解來實現;

參考資料:Spring@Autowired註解與自動裝配

@Order註解可以實現類的有序加載,其value越小越先被加載,針對list數組有效,對map數組無效。

@Qualifier當用@Autowiried自動裝配時,是根據屬性類型來裝配的,可能有多個bean實例,可以用此註釋來指定是哪一個bean實例。否則會報錯。

參考資料:Spring @Qualifier 註釋

@Resouce相當於@Autowiried加上@Qualifier的功能,某屬性有多個bean時大多使用此註解,有兩個參數name、type。有name時會按照byName進行裝配

有type時會按照byType進行裝配,兩者都有時按照name和type查找。兩者都沒有時按照屬性名利用反射機制裝配。

@Bean常與@Configuration配合使用,@Congfiguration相當於<beans>,註解在類上表示一個註解類,@Bean相當於<bean>,註解在方法上,返回一個bean,不指定name,默認爲方法名。默認是單例的

使用bean時也要加上<context:component-scan>掃面@bean註解的類的包

參考資料:Spring中基於Java的配置@Configuration和@Bean用法


在xml中<context:property-placeholder location="****.properties"/>用來加載資源文件。之後在xml中可以用${}引用,常見於數據庫的配置信息

用註解的實現方式爲@ImportResource("路徑")@Value引用。

使用properties文件的方法:

在properties文件中寫好鍵值對,如:name=tom

在xml中配置引入properties文件。<context:property-placeholder location="properties文件路徑"/>

在java類上引入資源:@ImportSource("xml路徑"),在字段上註解@Value("${name}")便可讓字段獲取tom值了

4、Spring AOP

1、AOP相關概念:

  • 切面(Aspect):一個關注點的切面化,這個關注點可能會橫切多個對象

  • 連接點(Joinpoint):程序執行過程中的某個特定的點

  • 通知(Advice):在切面某個連接點上執行的動作

  • 切入點(Pointcut):匹配連接點的點,在AOP中通知和一個切入點關聯

  • 引入(Introduction):在不修改類代碼的前提下,爲類添加新的方法和屬性

  • 目標對象(Target Object):被一個或多個切面所通知的對象

  • AOP代理(AOP Proxy):AOP框架創建的對象,用來實現切面契約(aspect contract)(包括通知方法執行等功能)

  • 織入(weaving):把切面鏈接到其他的應用或者對象上,並創建一個被通知的對象,分爲:編譯時織、類加載時織入、執行時織入


2、Advice類型

  • 前置通知(Before advice):在某連接點(join point)之前執行的通知,但不能阻止連接點的執行(除非拋出異常)

  • 返回後通知(After returning advice):在某連接點(join point)正常完成後執行的通知

  • 拋出異常後通知(After throwing advice):在方法拋出異常退出時執行的通知

  • 後通知(After (final)advice)當某連接點退出時執行的通知(不論是正常返回還是異常退出)

  • 環繞通知(Around Advice):包圍一個連接點的通知,環繞通知(Around advice)的方法第一個參數必須是ProceedingJoinPoint,調用他的proceed()方法;

Spring所有切面和通知器都必須放在一個<aop:config>可以配置多個,每一個<aop:config>可以包含pointcut,advisor和aspect元素,必須按照這個順序進行聲明


3、pointcut

*:匹配任何數量字符;

..:匹配任何數量字符的重複,如在類型模式中匹配任何數量子包;而在方法參數模式中匹配任何數量參數。

+:匹配指定類型的子類型;僅能作爲後綴放在類型模式後邊。

參考資料:切入點表達式的配置

4、advisors

充當Advice和Pointcut的適配器,將pointcut和advice結合起來

5、引入(Introductions)

簡介允許一個切面聲明一個實現指定接口的通知對象,並且提供了一個接口實現類來代表這些對象。簡單點說就是將原有的一個bean僞裝成一個我們自己的類,調用該bean時會調用我們僞裝的類。



5、spring AOP API

Pointcut通過API實現之一:NameMatchMethodPoint,根據方法名稱進行匹配,成員變量:mappedNames裏,有匹配的方法名集合

<bean id="***" class="org.springframework.aop.support.NameMatchMethodPointcut">

          <property name="mappedNames">

              <list>

                     <value>se*<!--    方法名     --></value>

              </list>

          </property>

</bean>

before advice:實現接口。MethodBeforeAdvice

Throw Advice :類似,找接口

After Returning advice :實現org.springframework.aop.AfterReturningAdvice接口

around advice:實現MethodInterceptor接口

6、spring對aspectj的支持

1、@AspectJ切面使用@Aspect註解配置。擁有@Aspect的任何bean將被spring自動識別並應用

2、用@Aspect註解的類可以有方法和字段,他們也可能包括切入點、通知和引入聲明

3、@Aspect註解是不能夠通過類路徑自動檢測和發現的,所以需要配合@Conponent註釋或者在xml中配置bean

4、一個類中的@Aspect註解標誌它爲一個切面,並且將自己從自動代理中排除

5、一個切點通過一個普通的方法定義來提供,並且切入點表達式使用@Pointcut註解,方法返回類型必須爲void


7、spring事務管理


1、主要包括3個接口:

  • PlatformTransactionManager事務管理器
  • TransactionDefinition事務定義信息(隔離、傳播、超時、只讀)
  • TransactionStatus事務具體運行狀態

spring爲不同的持久化框架實現了不同的PlatformTransactionManage接口

髒讀:一個事務讀到了另一個事務還沒有提交的數據。如果數據被回滾,則獨到的數據是無效的

不可重複讀:在同一事物中,多次讀取統一數據返回的結果有所不同

幻讀:一個事務讀取了幾行記錄後,另一個事務插入一些記錄,幻讀就發生了。再後來的查詢中第一個事務就會發現有些原來沒有的數據。

隔離級別:

DEFAULT:使用後端數據庫默認的隔離級別

READ_UNCOMMITED :允許你讀取還未提交的改變了的數據。可能導致髒、幻、不可重複讀

READ_COMMITTED  :允許併發事務已經提交後讀取。可防止髒讀、但幻讀和不可重複讀仍可發生

REPEATABLE_READ   :對相同字段的多次讀取是一致的,除非數據被事務本身改變。可防止髒、不可重複讀,但幻讀仍可能發生。

SERIALIZABLE:完全服從ACID的隔離級別,確保不發生髒、幻、不可重複讀。這是所有的隔離級別中最慢的,他是典型的通過完全鎖定在事務中涉及的數據來完成的

事務傳播行爲:

PROPERGATION_REQUIRED:支持當前事務,如果不存在則創建一個

PROPERGATON_SUPPORTS:支持當前事務,如果不存在,就不使用事務

PROPERGATION_MANDATORY:支持當前事務,如果不存在,拋出異常

PROPERGATION_REQUIRES_NEW:如果有事務存在,掛起當前事務,創建一個新的事務

PROPERGATION_NOT_SUPPORTED:以非事務方式運行,如果有事務存在,掛起當前事務

PROPERGATION_NEVER:以非事務方式運行,如果存在事務,拋出異常

PROPERGATION_NESTED:如果當前事務存在,嵌套當前事務執行


2、spring支持兩種事務管理:

---編程式事務管理

  • 在實際應用中很少使用
  • 通過TransactionTemplate手動管理事務


---使用XML配置聲明式事務

  • 開發中推薦使用
  • spring的聲明式事務是通過AOP實現

3、編程式事務管理的實現(很少使用):

  • 在要管理的類中使用TransactionTemplate,執行excute方法,在方法內構造一個TransactionCallbackWithoutResult()內部函數,覆蓋 doInTransactionWithoutResult()方法
  • TransactionTemplate依賴DataSourceTransactionManager
  • DataSourceTransactionManager依賴DataSource構造


4、聲明式事務管理:

  • 需要的類爲:org.springframework.transaction.interceptor.TransactionProxyFactoryBean;

<!-- 配置業務層代理 -->
<bean id="baseTransactionProxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
   <!-- 配置目標對象 -->
   <property name="target" ref="accountService"/>
<pre name="code" class="html">   <!-- 配置事務管理 -->
<property name="transactionManager" ref="transactionManager"/> <!-- 配置事務屬性 -->
<property name="transactionAttributes"> <props>
 <prop key="insert*">PROPAGATION_REQUIRED</prop> <prop key="update*">PROPAGATION_REQUIRED</prop> <prop key="*">PROPAGATION_REQUIRED,readOnly</prop> </props> </property> </bean>


prop的取值有:

  • PROPAGATION :事務的傳播行爲
  • ISOLATON ::事務的隔離級別
  • readOnly  :只讀(不可修改)
  • -Exception:發生哪些異常回滾事務
  • +Exception :發生哪些異常不回滾

5、基於Aspectj的xml方式配置事務管理(經常使用):

<!-- 配置事務管理器 -->
	<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<property name="dataSource" ref="dataSource"/>
	</bean>
	
	<!-- 配置事務通知(事務的增強)
		transaction-manager指向事務管理器
		method配置需要假如事務的方法名並可以陪配置相關屬性
	-->
	<tx:advice id="txAdvice" transaction-manager="transactionManager">
		<tx:attributes>
			<tx:method name="transfer" propagation="REQUIRED"/>
		</tx:attributes>
	</tx:advice>
	
	<!-- 配置切面  -->
	<aop:config>
		<!-- 配置切點 -->
		<aop:pointcut expression="execution(* com.transaction.demo3.AccountService+.*(..))" id="pointcut1"/>
		<!-- 裝配切點和通知 -->
		<aop:advisor advice-ref="txAdvice" pointcut-ref="pointcut1"/>
	</aop:config>

6、基於註解的事務管理方式(經常使用)

也需要配置事務管理器

<!-- 開啓事務註解 -->
	<tx:annotation-driven transaction-manager="transactionManager"/>

在所需要假如事務的方法的類上加上@Transactional即可,並在@Transactional中可以配置事務相關屬性;


8、SpringMVC


1、springMVC配置


pom.xml中配置

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>imooc-arthur</groupId>
	<artifactId>spring-mvc-study</artifactId>
	<version>1.0.0-SNAPSHOT</version>

	<properties>
		<commons-lang.version>2.6</commons-lang.version>
		<slf4j.version>1.7.6</slf4j.version>
		<spring.version>4.1.3.RELEASE</spring.version>
        <jackson.version>2.5.4</jackson.version>
	</properties>


	<dependencyManagement>
		<dependencies>
			<dependency>
				<groupId>org.springframework</groupId>
				<artifactId>spring-framework-bom</artifactId>
				<version>${spring.version}</version>
				<type>pom</type>
				<scope>import</scope>
			</dependency>
		</dependencies>
	</dependencyManagement>

	<dependencies>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-webmvc</artifactId>
		</dependency>

		<dependency>
			<groupId>commons-lang</groupId>
			<artifactId>commons-lang</artifactId>
			<version>${commons-lang.version}</version>
		</dependency>


		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>slf4j-log4j12</artifactId>
			<version>${slf4j.version}</version>
			<exclusions>
				<exclusion>
					<artifactId>slf4j-api</artifactId>
					<groupId>org.slf4j</groupId>
				</exclusion>
			</exclusions>
		</dependency>

		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>slf4j-api</artifactId>
			<version>${slf4j.version}</version>
		</dependency>

		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>servlet-api</artifactId>
			<version>2.5</version>
		</dependency>

	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.eclipse.jetty</groupId>
				<artifactId>jetty-maven-plugin</artifactId>
				<version>9.2.2.v20140723</version>
			</plugin>
		</plugins>
	</build>

</project>



web.xml中:

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee 
	http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
  <display-name>Spring MVC Study</display-name>
  <!-- Spring應用上下文, 理解層次化的ApplicationContext -->
  <context-param>
 		<param-name>contextConfigLocation</param-name>
		<param-value>/WEB-INF/configs/spring/applicationContext*.xml</param-value>
  </context-param>
  
  <listener>
		<listener-class>
			org.springframework.web.context.ContextLoaderListener
		</listener-class>
  </listener>
  
  <!-- DispatcherServlet, Spring MVC的核心 -->
  <servlet>
		<servlet-name>mvc-dispatcher</servlet-name>
		<servlet-class> org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<!-- DispatcherServlet對應的上下文配置, 默認爲/WEB-INF/$servlet-name$-servlet.xml
		 -->
		<init-param>
          <param-name>contextConfigLocation</param-name>
          <param-value>/WEB-INF/configs/spring/mvc-dispatcher-servlet.xml</param-value>
        </init-param>
		<load-on-startup>1</load-on-startup>
	</servlet>
	<servlet-mapping>
		<servlet-name>mvc-dispatcher</servlet-name>
	    <!-- mvc-dispatcher攔截所有的請求-->
		<url-pattern>/</url-pattern>
	</servlet-mapping>
</web-app>


dispatcher-servlet.xml配置

<?xml version="1.0" encoding="UTF-8"?>
<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"
	xmlns:mvc="http://www.springframework.org/schema/mvc"
	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
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc.xsd">

	<!-- 本配置文件是工名爲mvc-dispatcher的DispatcherServlet使用, 提供其相關的Spring MVC配置 -->

	<!-- 啓用Spring基於annotation的DI, 使用戶可以在Spring MVC中使用Spring的強大功能。 激活 @Required 
		@Autowired,JSR 250's @PostConstruct, @PreDestroy and @Resource 等標註 -->
	<context:annotation-config />

	<!-- DispatcherServlet上下文, 只管理@Controller類型的bean, 忽略其他型的bean, 如@Service -->
	<context:component-scan base-package="com.imooc.mvcdemo">
		<context:include-filter type="annotation"
			expression="org.springframework.stereotype.Controller" />
	</context:component-scan>

	<!-- HandlerMapping, 無需配置, Spring MVC可以默認啓動。 DefaultAnnotationHandlerMapping 
		annotation-driven HandlerMapping -->

	<!-- 擴充了註解驅動,可以將請求參數綁定到控制器參數 -->
	<mvc:annotation-driven />

	<!-- 靜態資源處理, css, js, imgs -->
	<mvc:resources mapping="/resources/**" location="/resources/" />

	<bean
		class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<property name="viewClass"
			value="org.springframework.web.servlet.view.JstlView" />
		<property name="prefix" value="/WEB-INF/jsps/" />
		<property name="suffix" value=".jsp" />
	</bean>

</beans>
applicationContext.xml配置:

<?xml version="1.0" encoding="UTF-8"?>
<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"
	xmlns:mvc="http://www.springframework.org/schema/mvc"
	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
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc.xsd">

	<context:annotation-config />
	
	<!-- @Controller已經在dispatcher-servlet.xml中配置過了。排除它 -->
	<context:component-scan base-package="com.imooc.mvcdemo">
		<context:exclude-filter type="annotation"
			expression="org.springframework.stereotype.Controller" />
	</context:component-scan>
</beans>

2、通過@RequestParam和@PathVariable兩個標記可以獲取到URL中傳遞的參數


3、Spring單文件上傳

需要在dispatcher-servlet.xml中配置:

<!--200*1024*1024即200M resolveLazily屬性啓用是爲了推遲文件解析,以便捕獲文件大小異常 -->
	<bean id="multipartResolver"
		class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
		<property name="maxUploadSize" value="209715200" />
		<property name="defaultEncoding" value="UTF-8" />
		<property name="resolveLazily" value="true" />
	</bean>

pom.xml中配置

<dependency>
			<groupId>commons-fileupload</groupId>
			<artifactId>commons-fileupload</artifactId>
			<version>1.3.1</version>
</dependency>

並在文件上傳的form中指定enctype="multipart/form-data"

4、處理JSON


需要在dispatcher-servlet.xml中配置:

<!-- 配置ViewResolver。 可以用多個ViewResolver。 使用order屬性排序。 InternalResourceViewResolver放在最後。 -->
	<bean
		class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
		<property name="order" value="1" />
		<property name="mediaTypes">
			<map>
				<entry key="json" value="application/json" />
				<entry key="xml" value="application/xml" />
				<entry key="htm" value="text/html" />
			</map>
		</property>

		<property name="defaultViews">
			<list>
				<!-- JSON View -->
				<bean
					class="org.springframework.web.servlet.view.json.MappingJackson2JsonView">
				</bean>
			</list>
		</property>
		<property name="ignoreAcceptHeader" value="true" />
	</bean>

引入依賴:

                <dependency>
			<groupId>com.fasterxml.jackson.core</groupId>
			<artifactId>jackson-databind</artifactId>
			<version>2.5.4</version>
		</dependency>

@Controller上的格式:
        //兩者都可以返回json數據
        @RequestMapping(value="/{courseId}",method=RequestMethod.GET)
	public @ResponseBody Course getCourseInJson(@PathVariable Integer courseId){
		return  courseService.getCoursebyId(courseId);
	}
	
	
	@RequestMapping(value="/jsontype/{courseId}",method=RequestMethod.GET)
	public  ResponseEntity<Course> getCourseInJson2(@PathVariable Integer courseId){
		Course course =   courseService.getCoursebyId(courseId);		
		return new ResponseEntity<Course>(course, HttpStatus.OK);
	}




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章