一、bean注入方式
1、設值注入
2、構造注入
二、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: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註解來實現;
@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);
}