Spring:
--1 使用jar包:
spring.jar
commons-logging.jar
使用aop
aspectjweaver.jar
aspectjrt.jar
cglib-nodep-2.1_3.jar
使用註解:
common-annotations.jar
--2 實例化容器:
ApplicationContext ctx =
new ClasspathXmlApplicationContext("applicationContext.xml");
ApplicationContext context=
new FileSystemXmlApplicationContext(new String[]{"d:\\beans.xml"});
--3 使用ContextLoaderListener
從ServletContext取得web.xml中初始化的ApplicationContext
首先在web.xml中配置listener。
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:spring/*.xml</param-value>
</context-param>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
然後從ServletContext中獲得ApplicationContext。
ApplicationContext context =
WebApplicationContextUtils.getWebApplicationContext(application);
對於無法獲得ServletContext的環境,最好自定義一個listener,
將生成的ApplicationContext放入一個單例中,以便日後使用。
--Spring配置要點:
(1) 在xml中使用spring-2.x的DTD。
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN"
"http://www.springframework.org/dtd/spring-beans-2.0.dtd">
相比schema真是方便了很多,這樣可以在必須使用特定schema的時候,再讓他重裝上陣。
spring-2.x中去掉了singleton屬性,使用scope屬性做替代。
如果還想使用singleton屬性,必須配置成spring-1.x格式的DTD。
提示:
spring中已不再推薦使用singleton屬性,因爲單例在多jvm,
遠程調用,集羣的情況下難以掌控,還是爲實例指明生存的scope比較好。
(2)default-lazy-init
懶惰加載,系統啓動的時候並不加載xml中定義的bean,
而是等到實際調用的時候纔去加載,這樣可以縮短系統初始化時間,
在測試系統部分功能的情況下有極大的好處。
注意,PropertityPlaceHolderConfigurer,springmvc,
xfire,quartz等的配置文件不能聲明爲懶惰加載,否則會出問題。
(3) default-autowire="byName"
按名稱自動綁定。設置了這個,只要定義bean的時候名稱與需要綁定的屬性名相同,
在實例化對象的時候,spring就會將這些實例自動綁定,
不需要再去聲明綁定哪些property。減少xml代碼量,使得結構更清晰。
在使用compass的時候要注意,不能使用按名稱自動綁定,
會自動爲compass綁定dataSource導致錯誤。
(4) import (????)
將xml統一放在classpath下,這樣更有利於進行單元測試,
對於多個模塊的xml使用import進行導入,層次更清晰。
<import resource="classpath:jbpm/applicationContext-jbpm4.xml"/>
(5) CharacterEncodingFilter
spring提供的編碼過濾器,好處一是不用自己動手寫了,
好處二是保證每次請求只過濾一次。配置如下:(web.xml)
<filter>
<filter-name>encodingFilter</filter-name>
<filter-class>
org.springframework.web.filter.CharacterEncodingFilter
</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
(6) IntrospectorCleanupListener
spring提供的監聽器,避免Struts,Quartz的內存泄露導致ClassLoader不能加載。
配置如下:(web.xml)
<listener>
<listener-class>
org.springframework.web.util.IntrospectorCleanupListener
</listener-class>
</listener>
(5) PropertyPlaceholderConfigurer
讀取properties中的變量,在xml中可以通過${變量名}的方式調用。配置如下:
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath*:conf/jdbc.properties</value>
</list>
</property>
</bean>
<bean id="userManager" class="com.family168.manager.UserManager">
<property name="username" value="${jdbc.username}"/>
</bean>
解析:jdbc.properties文件,內有對應的(key)username配置。
(6)PropertyOverrideConfigurer
與PropertyPlaceholderConfigurer不同,
PropertyOverrideConfigurer會在ApplicationContext初始化後,
根據properties中的定義,修改對應屬性的值。
配置如下:
<bean id="testPropertyConfigurer" class="org.springframework.beans.factory.config.PropertyOverrideConfigurer">
<property name="locations" value="classpath*:override.properties"/>
<property name="ignoreInvalidKeys" value="true"/>
</bean>
用來在測試環境下覆蓋已有的配置,比如在override.properties中
有userManager.username=111,那麼id="userManager"的bean的username屬性
就會被修改爲111。
(7) Spring-2.x對AOP和事務管理的簡化配置:
1. 首先要使用schema
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
2.然後要聲明標記(不知道是不是必要的)
<!-- 支持annotation @Transactional 標記 -->
<tx:annotation-driven/>
<!-- 支持annotation @AspectJ 標記-->
<aop:aspectj-autoproxy/>
3. 配置aop
<aop:config proxy-target-class="true">
<aop:advisor pointcut="execution(* com.family168.manager..*Manager.*(..))" advice-ref="txAdvice"/>
</aop:config>
注意:
name-pattern千萬不要寫成*..*Manager ,
這樣子會把所有第三方類庫的Manager比如Spring的PlatformTranstationManager
也加入aop,非常危險。所以最好還是加上項目的package前綴,
如"com.family168.manager..*Manager"
因爲有*,會修飾所有方法,有些hibernateTemplate的final的方法不能被cglib修改,
會拋warning,無害。事務定義一般默認的PROPAGATION_REQUIRED即可,
另提供的幾個選擇很少使用。值得注意的是一個PROPAGATION_NESTED,
嵌入式事務的意義在於多級事務,如果出錯只rollback子事務自己,不rollback主事務的所有操作。
這需要JDBC3.0 SavePoint功能的支持。 而一般service間互相嵌入調用時,
如果都定義爲PROPAGATION_REQUIRED,有其中一個操作出錯,rollback全部操作。
----------------
4 配置txAdvice處理事務
<tx:advice id="txAdvice">
<tx:attributes>
<tx:method name="get*" read-only="true"/>
<tx:method name="find*" read-only="true"/>
<tx:method name="pagedQuery*" read-only="true"/>
<tx:method name="load*" read-only="true"/>
<tx:method name="*"/>
</tx:attributes>
</tx:advice>
解析:
tx這個命名空間會要求咱們提供一個名字爲transactionManager的bean,用這個來作爲默認的事務管理器。
Spring參考文檔 7.3 chema-based AOP support 提供了aspect,advisor,advide三種組裝方法的解釋,
其中aspect是aspectJ原裝,但稍複雜,這裏唯一有點難懂的是pointcut裏的語法,其實也很好學,
Spring參考文檔7.2.3.4裏有完整說明 ,其實一排子過去是:
execution(modifiers-pattern? ret-type-pattern declaring-type-pattern? name-pattern(param-pattern)
throws-pattern?)
modifiers-pattern:(public/protected) 可以不填
ret-type-pattern:返回值可任意
declaring-type-pattern 可以不填
name-pattern 路徑
param-pattern 參數
throws-pattern 可以不填
eg1:
//返回值任意,com.family168.manager路徑下的,類名結尾爲Manager類的任意參數類型方法
* com.family168.manager..*Manager.*(..)
eg2:
execution(* *..BookManager.save(..))
第一顆* //ret-type-pattern 返回值可任意,
eg2:
*..*Manager //任意Package裏的以Manager結尾的類。
eg3:
如果寫成com.xyz.service.* //com.xyz.service下的任意類
eg4:
com.xyz.service..* com.xyz.service//com.xyz.service及其子package下的任意類
save代表save方法,也可以寫save* 代表saveBook()等方法
(..) 匹配0個參數或者多個參數的,任意類型
(x,..) 第一個參數的類型必須是X
(x,*,*,s,..) 匹配至少4個參數,第一個參數必須是x類型,
第二個和第三個參數可以任意,第四個必須是s類型。
--------------------
(8) Spring中的零配置
其實也不是完全的零配置,我們需要在xml中制定規範,然後在java中使用註解進行標註。
首先要在xml中配置如下標記:
<context:component-scan base-package="com.family168.manager" />
這裏需要使用Spring的schema命名空間進行配置,例子中使用的是springside中提供的例子,
指定了默認在哪個包下查找需要進行注入的類。在Service類中使用@Service註釋,
Dao類中使用@Repository註釋,通過pacakge掃描加入Spring的applicationContext。
在私有屬性或注入方法(不需要嚴格按setter命名)上 使用@Autowired 註釋 進行byType注入,
如果需要byName注入,增加@Qualifier註釋。另@auwowired默認隱含了@Required特性
使用@Required註釋非@Autowired的屬性,保證autowired下對象必然被注入,
如果對象沒有被注入則報錯。使用JSR250的@PostConstruct來定義在執行完
所有setter注入後必須執行的函數,比以往的實現接口或者在applicationContext.xml中
配置init-method的方式更爲標準。
爲提高效率,還是需要在xml中默認配置default-lazy-load和default-autowire byName。
------------------------
(9) Spring中的資源訪問(????)
1. ResourceLoader
ResourceLoader 可以獲得ClassPath, File,URL中的文件,返回類型爲Resource的統一資源定義。
ApplicationContext中就擁有ResourceLoader。
實現resourceLoaderAware接口可以獲得ResourceLoader。
2. ResourcePatternResolver
ResourcePatternResolver 是ResourceLoader的升級版子接口,能解決ant-style的文件模糊批量定義,
如applicationContext-*.xml。
ApplicationContext中的ResourceLoader其實是ResourcePatternResolver ,
可以通過強制轉型獲得,友好一點的做法是使用ResourcePatternUtils來轉換。
public class RescManager implements InitializingBean, BeanNameAware,
ResourceLoaderAware {
private ResourceLoader resourceLoader;
public void demo() throws IOException {
ResourcePatternResolver resolver = ResourcePatternUtils
.getResourcePatternResolver(resourceLoader);
Resource[] rescs = resolver.getResources(
"classpath*:spring/applicationContext*.xml");
System.out.println(rescs);
}
}
-------------------------------
(10)Spring的微內核與FactoryBean擴展機制
1. 微內核的功能
1.1. DI(依賴注入)與Singleton管理
利用POJO setter的DI機制,估計每位同學隨手都能寫一個簡單版本,不多說了。
Singleton管理說白了就是先到一個map中按id找找看有沒有已存在的實例。
1.2. BeanName與BeanFactory注入
除了DI注入的屬性,微內核還有什麼能賣給POJO呢?就是Bean在xml 定義裏的id和BeanFactory自己了。
賣的機制是讓POJO 實現 BeanNameAware和BeanFactoryAware接口。
BeanFactory用 if(pojo instance of BeanFactoryAware)判斷到POJO需要注入BeanFactory,
就調用setBeanFactory(this)將自己注入。
1.3. DI後的初始化函數調用
比如屬性A,B注入之後,需要同時根據A和B來對A,B進行加工或者裝配一個內部屬性C,
這樣就需要在所有屬性注入後再跑一個init()函數。
Spring提供兩種方式:
一種是和上面的原理一樣,實現InitializingBean接口的afterPropertiesSet()函數供Spring調用。
一種是在xml定義文件裏面自行定義init函數名。
懶得每次在xml文件裏定義的就採用第1種方式,不想與spring耦合的pojo就採用第2種方式。
本來就是爲了擴展Spring而存在的FactoryBean多采用第一種。
所謂微內核,就是僅提供以上三種功能的DI容器。
但作爲輕量級容器,還需要以下兩種方式,向容器內的POJO 附加各種服務。
2. FactoryBean擴展機制
Spring的AOP、ORM、事務管理、JMX、Quartz、Remoting、Freemarker、Velocity,
都靠FacotryBean的擴展,FacotryBean幾乎遍佈地上:
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"/>
<bean id="baseDAOService" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"/>
這原理說出來好簡單,所有FactoryBean 實現FactoryBean接口的getObject()函數。
Spring容器getBean(id)時見到bean的定義是普通class時,就會構造該class的實例來獲得bean,
而如果發現是FactoryBean接口的實例時,就通過調用它的getObject()函數來獲得bean,
僅此而以.......可見,很重要的思想,可以用很簡單的設計來實現。
3. Bean Post-Processor擴展機制(???)
如果說FactoryBean 是一種Factory、Wrapper式的擴展,
Bean Post-Processor就是另一種AOP、visitor式的機制,所以也多用於spring的AOP架構。
Post-Processor的原理就是BeanFactory在前文裏的調用afterPropertiesSet()/init-method前後,
調用在工廠裏註冊了的post-processor的postProcessBeforeInitialization()和postProcessAfterInitialization()。
那怎麼註冊登記呢?又分請不請禮儀公司兩類。
如果是ApplicationContext,你把繼承BeanPostProcessor 的bean往xml裏一擱就行了,
application context自會打理。如果是BeanFacotry,就要顯式的註冊,代碼大概像:
XmlBeanFactory factory = new XmlBeanFactory("C:/beans.xml");
BeanPostLogger logger = new BeanPostLogger();
factory.addBeanPostProcessor(logger);
Spring配置
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章
Mybatis Generator生成Bean、Mapper、Dao文件
entomb
2018-08-27 20:02:42
Spring中使用 JavaMailSenderImpl來實現郵件的發送
entomb
2018-08-27 20:02:41
Spring中@Configuration的使用
entomb
2018-08-27 20:02:41
spring bean定義的依賴性檢查
abu168
2018-08-27 19:48:01
Spring Cloud基礎教程(持續更新)
程序猿DD
2018-08-27 19:44:19
爲Spring Cloud Config插上管理的翅膀
程序猿DD
2018-08-27 19:44:19
Spring Boot 2.0與Java 9
程序猿DD
2018-08-27 19:44:18
Eureka 2.0 開源流產,真的對你影響很大嗎?
程序猿DD
2018-08-27 19:44:18
Spring Boot基礎教程(持續更新)
程序猿DD
2018-08-27 19:44:17
使用Swagger2Markup實現API文檔的靜態部署(一):AsciiDoc
程序猿DD
2018-08-27 19:44:06
Spring Cloud Zuul中使用Swagger彙總API接口文檔
程序猿DD
2018-08-27 19:44:05
Spring Boot 2.0正式發佈,升還是不升呢?
程序猿DD
2018-08-27 19:44:05
Spring Boot中使用LDAP來統一管理用戶信息
程序猿DD
2018-08-27 19:44:05
Spring Cloud構建微服務架構:消息驅動的微服務(核心概念)【Dalston版】
程序猿DD
2018-08-27 19:44:04
使用Swagger2Markup實現API文檔的靜態部署(二):Markdown和Confluence
程序猿DD
2018-08-27 19:44:04