spring 7大組成模塊:
1:spring core:提供了spring 的核心功能,BeanFactory是spring核心容器的主要組件,
它通過Ioc把程序的配置和依賴性與實際的代碼分開,是整個spring的基礎
2:spring context:通過配置文件向spring提供上下文信息,
它構建在BeanFactory之上,另外增加了國際化和資源訪問等功能
3:spring dao:提供了一個簡單有效的JDBC應用
4:spring aop:提供了面向方面編程的功能
5:spring orm:spring除了有自己的JDBC以外還提供了對其他ORM框架的支持,如Hibernate,都可以和spring進行良好的結合
6:spring web:提供了簡化的處理多部分請求以及把請求參數綁定到域的任務。
7:spring MVC:提供了MVC2模式的實現,也可以和struts良好的集成在一起。
這七大模塊可以單獨使用,不需要其他模塊的支持
--------------------------------------------------------
spring的特點:
1:設計良好的分層結構。
2:以IOC為核心,提倡面向接口編程。
3:良好的架構設計。
4:可以代替EJB
5:實現了MVC2
6:可以和其他框架良好的結合如:Hibernate ,struts等
編寫第一個HelloWorld程序:
1:interface
public interface IHelloWorld {
public void sayHello();
}
2:實現類:
public class HelloWorld implements IHelloWorld{
private String msg;
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public void sayHello(){
System.out.println(msg);
}
}
3:編寫spring配置文件:applicationContext.xml
<beans>
<bean id="Hello" class="EnHelloWorld">
<property name="msg">
<value>Hello World!</value>
</property>
</bean>
</beans>
4:編寫測試類:
public class TestHelloWorld {
public static void main(String[] args) {
ApplicationContext ac = new FileSystemXmlApplicationContext("applicationContext.xml");
IHelloWorld hw= (IHelloWorld)ac.getBean("Hello");
hw.sayHello();
}
}
---------------------------------------------------------------------
依賴注入的三種方式:
1:接口注入
2:set注入
3:構造注入
spring支持set注入和構造注入
把上面的HelloWorld改為構造注入:
1:實現類:
public class CHelloWorld implements IHelloWorld{
public String msg;
public CHelloWorld(String msg){
this.msg = msg;
}
public void sayHello(){
System.out.print(msg);
}
}
2:在spring配置文件:applicationContext.xml中:
<bean id="CHello" class="CHelloWorld">
<constructor-arg index="0">
<value>C Hello World!</value>
</constructor-arg>
</bean>
constructor-arg 用來表示用構造方式注入參數
index="0"表示是構造方法中的第一個參數
3:編寫測試類:
public class TestHelloWorld {
public static void main(String[] args) {
ApplicationContext ac = new FileSystemXmlApplicationContext("applicationContext.xml");
IHelloWorld hw= (IHelloWorld)ac.getBean("CHello");
hw.sayHello();
}
}
---------------------------------------------------------------------------
Spring的核心容器:
spring中兩個最基本最重要的包:
org.springframework.context和org.springframework.beans為spring的IOC提供了基礎
在這兩個最重要的類是BeanFactory和ApplicationContext。BeanFactory來管理各種bean。ApplicationContext在BeanFactory之上
增加了其他功能如國際化,獲取資源事件傳遞等。
1:bean的標志(id 和name)
每個bean都有一個id在管理bean的BeanFactory和ApplicationContext中必須是唯一標志。
id和name都可以用來指定id這兩者中至少有一個。區別是id的命名必須符合xml id中和合法字符。name則沒有限制,而且可以使用name指定多個id
2:bean的類
class屬性路徑要完整,包名.類名
3:singleton的使用
在spring 中bean可以定義為兩種部署模式:singleton和non-singleton
singleton:只有一個共享的實例存在
non-singleton:每次請求都創建新的實例
4:bean的屬性:
在定義bean的屬性時除了直接指定bean的屬性外還可以參考配置文件中定義的其他bean
1:
<bean id="DateHello" class="DateHelloWorld">
<property name="msg">
<value>Hello World!</value>
</property>
<property name="date">
<bean id="date" class="java.util.Date"/>
</property>
</bean>
2:
<bean id="DateHello" class="DateHelloWorld">
<property name="msg">
<value>Hello World!</value>
</property>
<property name="date">
<ref bean="date"/>
</property>
</bean>
<bean id="date" class="java.util.Date"/>
5:null值的處理
把屬性設為null值有兩種方法:
1:
<bean id="DateHello" class="DateHelloWorld">
<property name="msg">
<value>null</value>
</property>
</bean>
2:
<bean id="DateHello" class="DateHelloWorld">
<property name="msg">
<null/>
</property>
</bean>
6:使用depends-on
bean的depends-on可以用來在初始化這個bean前,強制執行一個或多個bean的初始化。
如:
<bean id="DateHello" class="DateHelloWorld" depends-on="date">
---------------------------------------------------------------------------------------
bean的生命周期:
1:bean的定義
//配置bean的開始,beans中包含一個或多個bean
<beans>
//定義一個bean id是唯一標志,class是bean的來源
<bean id="DateHello" class="DateHelloWorld">
//配置bean的開始
<property name="msg">
<null/>
</property>
//定義bean的結束
</bean>
//配置bean的結束
</beans>
2:bean的初始化
初始化有兩種方式:
1在配置文件中指定init-method屬性來完成
public class HelloWorld {
private String msg;
public void init(){
msg="Hello World";
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public void sayHello(){
System.out.println(msg);
}
}
applicationContext.xml文件中
<bean id="DateHello" class="HelloWorld" init-method="init">
2實現org.springframework.beans.factory.InitialingBean接口
實現其中的afterPropertiesSet()方法
public class HelloWorld implements InitializingBean{
private String msg;
public void afterPropertiesSet(){
msg="Hello World";
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public void sayHello(){
System.out.println(msg);
}
}
applicationContext.xml文件中
<bean id="DateHello" class="HelloWorld">
</bean>
3:bean的使用
有三種方式:
1:使用BeanWrapper
HelloWorld helloWorld = new HelloWorld ();
BeanWrapper bw = new BeanWrapperImpl(helloWorld);
bw.setPropertyValue("msg","HelloWorld");
System.out.println(bw.getPropertyValue("msg"));
2:使用BeanFactory
InputStream is = new FileInputStream("applicationContext.xml");
XmlBeanFactory factory = new XmlBeanFactory (is);
HelloWorld helloWorld = (HelloWorld)factory.getBean ("HelloWorld");
helloWorld.sayHello();
3:使用ApplicationContext
ApplicationContext ac = new FileSystemXmlApplicationContext("applicationContext.xml");
IHelloWorld hw= (IHelloWorld)ac.getBean("CHello");
hw.sayHello();
4:bean的銷毀
銷毀有兩種方式:
1在配置文件中指定destory-method屬性來完成
public class HelloWorld {
private String msg;
public void init(){
msg="Hello World";
}
public void cleanup(){
msg="";
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public void sayHello(){
System.out.println(msg);
}
}
applicationContext.xml文件中
<bean id="DateHello" class="HelloWorld" init-method="init" destory-method="cleanup">
2實現org.springframework.beans.factory.DisposeableBean接口
實現其中的destory()方法
public class HelloWorld implements InitializingBean,DisposeableBean{
private String msg;
public void afterPropertiesSet(){
msg="Hello World";
}
public void destory(){
msg="";
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public void sayHello(){
System.out.println(msg);
}
}
applicationContext.xml文件中
<bean id="DateHello" class="HelloWorld">
</bean>
----------------------------------------------------------
用ref屬性指定依賴的三種方式
1:用local屬性指定:local屬性的值必須與被參考引用的bean的id一致,如果在同一個xml文件里沒有匹配的元素,xml解析將產生一個錯誤
如:
<bean id="DateHello" class="DateHelloWorld">
<property name="msg">
<value>Hello World!</value>
</property>
<property name="date">
<ref local="date"/>
</property>
</bean>
<bean id="date" class="java.util.Date"/>
2:用bean屬性指定
用ref元素中的bean屬性指定被參考引用的bean是spring中最常見的形式,它允許指向的bean可以在同一xml文件中也可以不在同一個xml文件里
bean屬性的值可以與被引用的bean的id相同也可以與name相同。
<bean id="DateHello" class="DateHelloWorld">
<property name="msg">
<value>Hello World!</value>
</property>
<property name="date">
<ref bean="date"/>
</property>
</bean>
<bean id="date" class="java.util.Date"/>
3:用parent屬性指定
用ref元素中的parent屬性指定被參考引用的bean時,允許引用當前BeanFactory或ApplicationContext的父BeanFactory或ApplicationContext
bean屬性的值可以與被引用的bean的id相同也可以與name相同。
<bean id="DateHello" class="DateHelloWorld">
<property name="msg">
<value>Hello World!</value>
</property>
<property name="date">
<ref parent="date"/>
</property>
</bean>
用local屬性指定和用bean屬性指定的比較
相同:都可以使用id來參考引用,可以對同一xml文件進行參考引用
不同:bean屬性的值可以與被引用的bean的id相同也可以與name相同。可以引用不在同一個xml文件里的bean
----------------------------------------------------------
bean自動裝配的5種模式:
可以使用bean元素的autowire屬性來指定bean的裝配模式:
1:byName
2: byType
3:constructor
4:autodetect
5:no
顯示的指定依賴如:property 和constructor-arg元素總會覆蓋自動裝配。對與大型應用不鼓勵使用自動裝配
--------------------------------------------------------------
bean 依賴檢查的4種模式:
依賴檢查能夠分別對每個bean應用或取消應用,默認的是不檢查依賴關系,
可以使用bean元素的dependency-check屬性來指定bean的依賴檢查,共有4種:
1:使用simple模式
是指對基本類型、字符串和集合進行依賴檢查
如:
<bean id="DateHello" class="DateHelloWorld" autowire="autodetect" dependency-check="simple">
</bean>
<bean id="date" class="java.util.Date"/>
只會對msg進行檢查
2:使用object模式
是指對對象進行依賴檢查
如:
<bean id="DateHello" class="DateHelloWorld" autowire="autodetect" dependency-check="object">
</bean>
<bean id="date" class="java.util.Date"/>
只會對date進行檢查
3:使用all模式
是指對所有屬性進行依賴檢查
如:
<bean id="DateHello" class="DateHelloWorld" autowire="autodetect" dependency-check="all">
</bean>
<bean id="date" class="java.util.Date"/>
會對msg進行檢查和date進行檢查
4:使用none模式
是指對所有屬性不進行依賴檢查
如:
<bean id="DateHello" class="DateHelloWorld" autowire="autodetect" dependency-check="none">
</bean>
<bean id="date" class="java.util.Date"/>
不會對msg進行檢查和date進行檢查
總結:一般情況下依賴檢查和自動裝配結合使用,當bean屬性都有默認值或不需要對bean的屬性是否被設置到bean上檢查時,依賴檢查的作用就不大了
-----------------------------------------------------------------------
集合的注入方式
對于集合List Set Map Props元素則有不同的配置方式
1:List
public class HelloWorld{
//定義一個List變量msg
List msg=null;
public void setMsg(List msg){
this.msg = msg;
}
}
xml文件:
<bean id="Hello" class="HelloWorld">
<property name="msg">
<list>
<value>Hello World!</value>
<value>Hello World2!</value>
</list>
</property>
</bean>
2:set
public class HelloWorld{
//定義一個Set變量msg
Set msg=null;
public void setMsg(Set msg){
this.msg = msg;
}
}
xml文件:
<bean id="Hello" class="HelloWorld">
<property name="msg">
<set>
<value>Hello World!</value>
<value>Hello World2!</value>
</set>
</property>
</bean>
3:map
public class HelloWorld{
//定義一個Map變量msg
Map msg=null;
public void setMsg(Map msg){
this.msg = msg;
}
}
xml文件:
<bean id="Hello" class="HelloWorld">
<property name="msg">
<map>
<entry key="h1">
<value>Hello World!</value>
</entry>
<entry key="h2">
<value>Hello World2!</value>
</entry>
</map>
</property>
</bean>
4:properties
public class HelloWorld{
//定義一個properties變量msg
Properties msg;
public void setMsg(Properties msg){
this.msg = msg;
}
}
xml文件:
<bean id="Hello" class="HelloWorld">
<property name="msg">
<props>
<prop key ="h1">Hello World!</prop>
<prop key ="h2">Hello World2!</prop>
</props>
</property>
</bean>
---------------------------------------------------------------
Spring AOP(Aspect Oriented Programming)
應用程序通常包含兩種代碼:一是核心業務代碼,一是和業務關系不大的代碼如日志、事物處理等。
AOP的思想就是使這兩種代碼分離,從而降低了兩種代碼的偶合性,達到了易于重用和維護的目的。
AOP和OOP:
在AOP里,每個關注點的實現并不知道是否有其他關注點關注它,這是AOP和OOP的主要區別,
在AOP里組合的流向是從橫切關注點到主關注點,在OOP中組合流向是從主關注點到橫切關注點。
AOP和OOP所關注的對象不同,AOP是OOP有益的補充,不是對立面。
AOP的3個關鍵概念:
1:切入點:(PiontCut)
連接點(Jion piont):是指程序運行中的某個階段,如方法的調用、異常的拋出等。
PiontCu就是Jion piont點的集合,它是程序中需要注入的Advice的集合。指明Advice
在什么 條件下才被觸發。
2:通知(Advice):
某個連接點采用的處理邏輯,也就是向連接點注入的代碼。
3:Advisor
是PiontCut和Advice的配置器,它包含PiontCut和Advice,是把Advice注入到PiontCut位置的代碼。
Spring 的3種切入點的實現:
1:靜態切入點:
靜態切入點只限于給定的方法和目標類。不考慮方法的參數。
2:動態切入點:
動態切入點不僅限于給定的方法和目標類,還可以指定方法的參數。
動態切入點有很大的性能損耗,一般很少使用。
3:自定義切入點:
正在發展
Spring 的通知:
1:Intercdption Around通知
Intercdption Around在JiontPoint的前后執行。實現Intercdption Around通知要實現
MethodInterceptor接口,示例代碼如下:
public class LoginInterceptor implements MethodInterceptor{
public Object invoke(MenthodInvocation invocation) throws Throwable{
System.out.println("開始審核數據");
Object result = invocation.proceed();
System.out.println("審核數據結束");
return result;
}
}
2:Before通知
Before通知在JiontPoint的前執行。實現Befored通知要實現
MethodBeforeAdvice接口,示例代碼如下:
public class LoginBeforeAdvice implements MethodBeforeAdvice{
public void Beforee(Menthod m,Object [] atgs,Object target) throws Throwable{
System.out.println("開始審核數據");
}
}
3:After Return 通知
After Return通知在JiontPoint后執行。實現After Returnd通知要實現
AfterReturningAdvice接口,示例代碼如下:
public class LoginAfterAdvice implements AfterReturningAdvice{
public void AfterReturning(Menthod m,Object [] atgs,Object target) throws Throwable{
System.out.println("審核數據結束");
}
}
4:Throw通知
Throw通知在JiontPoint拋出異常時執行。實現Throw通知要實現
ThrowAdvice接口,示例代碼如下:
public class LoginThrowAdvice implements ThrowAdvice{
public void AfterThrowing(RemoteException ex) throws Throwable{
System.out.println("審核數據異常");
}
}
5:Introduction 通知
Introduction通知在JiontPoint 調用完畢后執行。實現Introduction通知要實現
IntroductionAdvisor接口和IntroductionInterceptor接口。
用ProxyFactoryBean創建AOP代理
使用org.springfamework.aop.framework.ProxyFactoryBean是創建AOP代理的基本方式。
1:使用ProxyFactoryBean代理目標類中的所有方法
示例代碼:
<beans>
<bean id="log" class="logAround"/>
<bean id="logBefore" class="logBefore"/>
<bean id="logAfter" class="logAfter"/>
<bean id="logThrow" class="logThrow"/>
<bean id="timebook" class="TimeBook"/>
<!-設定代理類-->
<bean id="logProxy" class ="org.springframework.aop.framework.ProxyFactoryBean">
<!--代理的是接口-->
<property name="proxyInterface">
<value>TimeBookInterface</value>
</property>
<!--要代理的目標類-->
<property name="target">
<ref bean="timebook"/>
</property>
<!--程序中的Advice-->
<property name="interceptorNames">
<list>
<value>logBefore</value>
<value>logAfter</value>
<value>logThrow</value>
</list>
</property>
</bean>
</beans>
2:使用ProxyFactoryBean代理目標類中的指定方法
示例代碼:
<beans>
<bean id="log" class="logAround"/>
<bean id="logBefore" class="logBefore"/>
<bean id="logAfter" class="logAfter"/>
<bean id="logThrow" class="logThrow"/>
<bean id="timebook" class="TimeBook"/>
<!--代理目標類的指定方法-->
<bean id ="logAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
<property name="advice">
<ref bean="log"/>
</property>
<!--指定要代理的方法-->
<property name="patterns">
<value>doCheck*</value>
</property>
</bean>
<!-設定代理類-->
<bean id="logProxy" class ="org.springframework.aop.framework.ProxyFactoryBean">
<!--代理的是接口-->
<property name="proxyInterfaces">
<value>TimeBookInterface</value>
</property>
<!--要代理的目標類-->
<property name="target">
<ref bean="timebook"/>
</property>
<!--程序中的Advice-->
<property name="interceptorNames">
<list>
<value>logAdvisor</value>
</list>
</property>
</bean>
</beans>
---------------------------------------------------------
正則表達式:
1:.表示可以匹配任何一個字符
2:[]表示只有[]里指定的字符才能匹配
3:*表示匹配次數
4:?表示可以匹配1或0次
5:\是正則表達式的連接符
---------------------------------------------------------------
Spring 中兩種AOP代理方式
1:動態代理
動態代理是指代理的是接口,Spring默認的是動態代理
2:CGLIB代理
<beans>
<bean id="log" class="logAround"/>
<bean id="logBefore" class="logBefore"/>
<bean id="logAfter" class="logAfter"/>
<bean id="logThrow" class="logThrow"/>
<bean id="timebook" class="TimeBook"/>
<bean id="logProxy" class ="org.springframework.aop.framework.ProxyFactoryBean">
<property name="proxyTargetClass">
<value>true</value>
</property>
<property name="target">
<ref bean="timebook"/>
</property>
<property name="interceptorNames">
<list>
<value>logBefore</value>
<value>logAfter</value>
<value>logThrow</value>
</list>
</property>
</bean>
</beans>
-----------------------------------------------------------------------
Spring 中的自動代理方式
自動代理可以跨越多個類,不管哪個類中的方法只要符合要求都可以代理
<beans>
<bean id="log" class="logAround"/>
<bean id="logBefore" class="logBefore"/>
<bean id="logAfter" class="logAfter"/>
<bean id="logThrow" class="logThrow"/>
<bean id="timebook" class="TimeBook"/>
<bean id="timework" class="TimeWork"/>
<!--使用自動代理-->
<bean id="autoProxy" class ="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"/>
<bean id="logBeforAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
<property name="advice">
<ref bean="logBefore"/>
</property>
<property name="patterns">
<value>.*do.*</value>
</property>
</bean>
</beans>
------------------------------------------------------------
Spring中的事務處理
事務處理是由多個步驟組成,這些步驟之間有一定的邏輯關系,作為一個整體的操作過程,所有的步驟必須同時成功或失敗。
1:提交 當所有的操作步驟都被完整執行后,稱為該事物被提交。
2:回滾 由于某個操作失敗,導致所有的步驟都沒被提交則事物必須回滾,回到事物執行前的狀態。
事務的特性:
ACID:原子性(Atomicity)一致性(Consistency)隔離性(Isolation)持久性(Durablity)
Spring中的事務處理是基于動態AOP機制的實現。
1:編程式事務處理:
spring 提供的TransactionTemplate能夠以編程的方式實現事務控制。
HelloADO.java:
public int create(String msg){
DefaultTransactionDefinition def = new DefaultTransactionDefinition();
TransactionStatus status = transactionManager.getTransaction(def);
try{
JdbcTemplate jt = new JdbcTemplate(dataSource);
int i=jt.update("insert into st(name,password) values('zz','zz')");
return i;
}catch (Exception e){
transactionManager.rollback(status);
return 0;
}
finally {
transactionManager.commit(status);
}
}
applicationContext.xml
<beans>
<bean id ="dataSource" class ="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName">
<value>com.mysql.jdbc.Driver</value>
</property>
<property name="url">
<value>jdbc:mysql://localhost:3306/newdb</value>
</property>
<property name="username">
<value>root</value>
</property>
<property name="password">
<value>lxl</value>
</property>
</bean>
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource">
<ref bean="dataSource"/>
</property>
</bean>
<bean id="helloDAO" class ="HelloDAO">
<property name="dataSource">
<ref bean="dataSource"/>
</property>
<property name="transactionManager">
<ref bean="transactionManager"/>
</property>
</bean>
</beans>
2:聲明式事務處理:
HelloADO.java:
public class HelloDAO {
private DataSource dataSource ;
private JdbcTemplate jdbcTemplate;
public void setDataSource(DataSource dataSource) {
this.dataSource = dataSource;
jdbcTemplate = new JdbcTemplate(dataSource);
}
public void create(String name){
jdbcTemplate.update("insert into st(name,password)values('lxl','lxl')");
}
}
applicationContext.xml
<beans>
<bean id ="dataSource" class ="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName">
<value>com.mysql.jdbc.Driver</value>
</property>
<property name="url">
<value>jdbc:mysql://localhost:3306/newdb</value>
</property>
<property name="username">
<value>root</value>
</property>
<property name="password">
<value>lxl</value>
</property>
</bean>
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource">
<ref bean="dataSource"/>
</property>
</bean>
<bean id="helloDAO" class ="HelloDAO">
<property name="dataSource">
<ref bean="dataSource"/>
</property>
</bean>
<!-- 聲明式事務處理-->
<bean id="helloDAOProxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager">
<ref bean="transactionManager"/>
</property>
<property name="target">
<ref bean="helloDAO"/>
</property>
<property name="transactionAttributes">
<props>
<!-- 對create方法進行事務管理,PROPAGATION_REQUIRED表示如果沒有事務就新建一個事務-->
<prop key="create*">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>
</beans>
-------------------------------------------------------
Spring持久層的封裝
通過xml實現DataSource數據源的注入有3種方式:
1:使用spring自帶的DriverManagerDataSource
<beans>
<bean id ="dataSource" class ="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName">
<value>com.mysql.jdbc.Driver</value>
</property>
<property name="url">
<value>jdbc:mysql://localhost:3306/newdb</value>
</property>
<property name="username">
<value>root</value>
</property>
<property name="password">
<value>lxl</value>
</property>
</bean>
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource">
<ref bean="dataSource"/>
</property>
</bean>
<bean id="helloDAO" class ="HelloDAO">
<property name="dataSource">
<ref bean="dataSource"/>
</property>
</bean>
<!-- 聲明式事務處理-->
<bean id="helloDAOProxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager">
<ref bean="transactionManager"/>
</property>
<property name="target">
<ref bean="helloDAO"/>
</property>
<property name="transactionAttributes">
<props>
<!-- 對create方法進行事務管理,PROPAGATION_REQUIRED表示如果沒有事務就新建一個事務-->
<prop key="create*">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>
</beans>
2:使用DBCP連接池
<beans>
<bean id ="dataSource" class ="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName">
<value>com.mysql.jdbc.Driver</value>
</property>
<property name="url">
<value>jdbc:mysql://localhost:3306/newdb</value>
</property>
<property name="username">
<value>root</value>
</property>
<property name="password">
<value>lxl</value>
</property>
</bean>
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource">
<ref bean="dataSource"/>
</property>
</bean>
<bean id="helloDAO" class ="HelloDAO">
<property name="dataSource">
<ref bean="dataSource"/>
</property>
</bean>
<!-- 聲明式事務處理-->
<bean id="helloDAOProxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager">
<ref bean="transactionManager"/>
</property>
<property name="target">
<ref bean="helloDAO"/>
</property>
<property name="transactionAttributes">
<props>
<!-- 對create方法進行事務管理,PROPAGATION_REQUIRED表示如果沒有事務就新建一個事務-->
<prop key="create*">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>
</beans>
3:使用Tomcat提供的JNDI
<beans>
<bean id ="dataSource" class ="org.springframework.jndi.JndiObjectFactoryBean">
<property name="driverClassName">
<value>com.mysql.jdbc.Driver</value>
</property>
<property name="url">
<value>jdbc:mysql://localhost:3306/newdb</value>
</property>
<property name="username">
<value>root</value>
</property>
<property name="password">
<value>lxl</value>
</property>
</bean>
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource">
<ref bean="dataSource"/>
</property>
</bean>
<bean id="helloDAO" class ="HelloDAO">
<property name="dataSource">
<ref bean="dataSource"/>
</property>
</bean>
<!-- 聲明式事務處理-->
<bean id="helloDAOProxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager">
<ref bean="transactionManager"/>
</property>
<property name="target">
<ref bean="helloDAO"/>
</property>
<property name="transactionAttributes">
<props>
<!-- 對create方法進行事務管理,PROPAGATION_REQUIRED表示如果沒有事務就新建一個事務-->
<prop key="create*">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>
</beans>
-------------------------------------------------------
Spring 和 Struts的整合使用
Spring 和 Struts的整合有3種方式:
1:通過Spring的ActionSupport類
2:通過Spring的DelegatingRequestProcessor類
3:通過Spring的DelegatingActionProxy類
a: 通過Spring的ActionSupport類:(對應工程:SpringStruts)
方法是Action類不再繼承Struts的Action而是繼承Spring提供的ActionSupport,
然后在Action中獲得Spring的ApplicationContext.
缺點是Action和Spring耦合在一起,而且Action不在Spring控制之內。也不能處理多個動作在一個Action中的情況。
步驟:
1:加入spring.
2: 加入struts
3:修改struts配置文件struts-config.xml文件注冊ContextLoaderPlugIn插件。
<plug-in className="org.springframework.web.struts.ContextLoaderPlugIn">
<set-property property="contextConfigLocation" value="/WEB-INF/applicationContext.xml"/>
</plug-in>
4:創建Action時:
(1) 處,我通過從 Spring 的 ActionSupport 類而不是 Struts 的 Action 類進行擴展,創建了一個新的 Action。
(2) 處,我使用 getWebApplicationContext() 方法獲得一個 ApplicationContext。為了獲得業務服務,我使用在
(3) 處 查找一個 Spring bean。
//(1)
public class LoginAction extends ActionSupport {
public ActionForward execute(
ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response) {
LoginForm loginForm = (LoginForm) form;
// TODO Auto-generated method stub
//(2)
ApplicationContext ac = this.getWebApplicationContext();//獲得ApplicationContext
//(3)
LoginInterface li = (LoginInterface)ac.getBean("loginInterface");//獲得Bean
boolean you = li.checkUser(loginForm.getName(),loginForm.getPassword());
if(you){
request.setAttribute("msg","welcome");
return mapping.findForward("show");
}
else{
request.setAttribute("msg","failed");
return mapping.findForward("show");
}
}
}
applicationContext.xml:
<beans>
<bean id="loginInterface" class="spring.LoginImp"/>
</beans>
b: 通過Spring的DelegatingRequestProcessor類:(對應工程:SpringStruts2)
方法是Spring的DelegatingRequestProcessor代替Struts的RequstProcessor,
把Struts的Action置于Spring的的控制之下
缺點是開發人員可以自己定義RequestProcessor這樣就需要手工整合Struts和Spring。
步驟:
1:加入spring.
2: 加入struts
3:修改struts配置文件struts-config.xml文件注冊ContextLoaderPlugIn插件。
<struts-config>
<form-beans >
<form-bean name="loginForm" type="com.yourcompany.struts.form.LoginForm" />
</form-beans>
<action-mappings >
<action
attribute="loginForm"
input="/login.jsp"
name="loginForm"
path="/login"
scope="request"
type="com.yourcompany.struts.action.LogAction">
<forward name="show" path="/show.jsp" />
</action>
</action-mappings>
<controller processorClass="org.springframework.web.struts.DelegatingRequestProcessor"></controller>
<message-resources parameter="com.yourcompany.struts.ApplicationResources" />
<plug-in className="org.springframework.web.struts.ContextLoaderPlugIn">
<set-property property="contextConfigLocation" value="/WEB-INF/applicationContext.xml"/>
</plug-in>
</struts-config>
4:創建Action時:
public class LogAction extends Action {
private LoginInterface logInterface;
public ActionForward execute(
ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response) {
LoginForm loginForm = (LoginForm) form;
// TODO Auto-generated method stub
boolean you = logInterface.checkUser(loginForm.getName(),loginForm.getPassword());
if(you){
request.setAttribute("msg","welcome");
return mapping.findForward("show");
}
else{
request.setAttribute("msg","failed");
return mapping.findForward("show");
}
}
public void setLogInterface(LoginInterface logInterface) {
this.logInterface = logInterface;
}
}
applicationContext.xml:
<beans>
<bean id="loginInterface" class="spring.LoginImp"/>
<!--要和Struts的路徑對應-->
<bean name="/login" class="com.yourcompany.struts.action.LogAction">
<property name="logInterface">
<ref bean="loginInterface"/>
</property>
</bean>
</beans>
c: 通過Spring的DelegatingActionProxy類:(對應工程:SpringStruts3)
方法是Spring的DelegatingActionProxy代替Struts的Action,
把Struts的Action置于Spring的的控制之下
這種方式最靈活強大。并且它可以利用 Spring AOP 特性的優點。
步驟:
1:加入spring.
2: 加入struts
3:修改struts配置文件struts-config.xml文件注冊ContextLoaderPlugIn插件。
<struts-config>
<data-sources />
<form-beans >
<form-bean name="loginForm" type="com.yourcompany.struts.form.LoginForm" />
</form-beans>
<action-mappings >
<action
attribute="loginForm"
input="/form/login.jsp"
name="loginForm"
path="/login"
scope="request"
type="org.springframework.web.struts.DelegatingActionProxy">
<forward name="show" path="/show.jsp" />
</action>
</action-mappings>
<message-resources parameter="com.yourcompany.struts.ApplicationResources" />
<plug-in className="org.springframework.web.struts.ContextLoaderPlugIn">
<set-property property="contextConfigLocation" value="/WEB-INF/applicationContext.xml"/>
</plug-in>
</struts-config>
4:創建Action時:
public class LogAction extends Action {
private LoginInterface logInterface;
public ActionForward execute(
ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response) {
LoginForm loginForm = (LoginForm) form;
// TODO Auto-generated method stub
boolean you = logInterface.checkUser(loginForm.getName(),loginForm.getPassword());
if(you){
request.setAttribute("msg","welcome");
return mapping.findForward("show");
}
else{
request.setAttribute("msg","failed");
return mapping.findForward("show");
}
}
public void setLogInterface(LoginInterface logInterface) {
this.logInterface = logInterface;
}
}
applicationContext.xml:
<beans>
<bean id="loginInterface" class="spring.LoginImp"/>
<!--要和Struts的路徑對應-->
<bean name="/login" class="com.yourcompany.struts.action.LogAction">
<property name="logInterface">
<ref bean="loginInterface"/>
</property>
</bean>
</beans>
攔截 Struts
通過將 Struts 動作委托給 Spring 框架而整合 Struts 和 Spring 的一個主要的優點是:您可以將
Spring 的 AOP 攔截器應用于您的 Struts 動作。通過將 Spring 攔截器應用于 Struts
動作,您可以用最小的代價處理橫切關注點。
雖然 Spring 提供很多內置攔截器,但是我將向您展示如何創建自己的攔截器并把它應用于一個 Struts
動作。為了使用攔截器,您需要做三件事:
1: 創建攔截器。
2:注冊攔截器。
3:聲明在何處攔截代碼。
這看起來非常簡單的幾句話卻非常強大。例如,在清單 7 中,我為 Struts 動作創建了一個日志記錄攔截器。
這個攔截器在每個方法調用之前打印一句話:
清單 7. 一個簡單的日志記錄攔截器
public class LoggingInterceptor implements MethodBeforeAdvice {
public void before(Method method, Object[] objects, Object o) throws Throwable {
System.out.println("logging before!");
}
}
這個攔截器非常簡單。before()
方法在攔截點中每個方法之前運行。在本例中,它打印出一句話,其實它可以做您想做的任何事。下一步就是在 Spring
配置文件中注冊這個攔截器,如清單 8 所示:
清單 8. 在 Spring 配置文件中注冊攔截器
<beans>
<bean id="bookService" class="ca.nexcel.books.business.BookServiceImpl"/>
<bean name="/searchSubmit" class="ca.nexcel.books.actions.SearchSubmit">
<property name="bookService"> <ref bean="bookService"/> </property>
</bean>
<!-- Interceptors -->
<bean name="logger" class="ca.nexcel.books.interceptors.LoggingInterceptor"/> |(1)
<!-- AutoProxies -->
<bean name="loggingAutoProxy" class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator"> |(2)
<property name="beanNames"> <value>/searchSubmit</value> |(3) </property>
<property name="interceptorNames">
<list>
<value>logger</value> |(4)
</list>
</property>
</bean>
</beans>
您可能已經注意到了,清單 8 擴展了 清單 6 中所示的應用程序以包含一個攔截器。具體細節如下:
在 (1) 處,我注冊了這個攔截器。
在 (2) 處,我創建了一個 bean 名稱自動代理,它描述如何應用攔截器。還有其他的方法定義攔截點,但是這種方法常見而簡便。
在 (3) 處,我將 Struts 動作注冊為將被攔截的 bean。如果您想要攔截其他的 Struts 動作,則只需要在
"beanNames" 下面創建附加的 <value> 標記。
在 (4) 處,當攔截發生時,我執行了在 (1) 處創建的攔截器 bean
的名稱。這里列出的所有攔截器都應用于“beanNames”。
就是這樣。就像這個例子所展示的,將您的 Struts 動作置于 Spring 框架的控制之下,為處理您的 Struts
應用程序提供了一系列全新的選擇。在本例中,使用動作委托可以輕松地利用 Spring 攔截器提高 Struts
應用程序中的日志記錄能力。
-----------------------------------------------------------------------------------------------
Struts + Spring + Hibernate的整合使用
開發工具:Eclipse3.1,MyEclipse4.0 ,Tomcat5.0.28,mysql-4.0.18
開發步驟:
1:創建web projectSSHlogin 加入struts1.2
創建loginForm選擇DynaValidatorForm,加入password,username,創建jsp文件打上鉤,將路徑改為 /login.jsp,然后下一步,改LoginAction的Input source改為/login.jsp,加入 <forward name="ok" path="ok.jsp" />點擊完成
完成后修改struts-config.xml文件加入
<plug-in className="org.apache.struts.validator.ValidatorPlugIn">
<set-property property="pathnames" value="/WEB-INF/validator-rules.xml,/WEB-INF/validation.xml" />
</plug-in>
拷貝validator-rules.xml和validation.xml到WEB-INF目錄中 在validation.xml文件中加入
<form-validation>
<formset>
<form name="loginForm">
<field property="username" depends="required">
<arg0 key="prompt.username" />
</field>
<field property="password" depends="required">
<arg0 key="prompt.password" />
</field>
</form>
</formset>
</form-validation>
validator-rules.xml文件直接考一個就行。
編輯資源文件“ApplicationResources.properties”
增加以下內容
prompt.username=User Name
prompt.password=User Password
errors.required={0} is required.
修改LoginAction.java文件的execute方法,內容如下
public ActionForward execute(
ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response) {
DynaValidatorForm loginForm = (DynaValidatorForm) form;
String username=loginForm.getString("username");
String password=loginForm.getString("password");
if(username.equals("test")||password.equals("test")){
return mapping.findForward("indexGo");
}else{
return mapping.getInputForward();
}
}
好了,現在可以啟動Tomcat進行測試了如果不輸入任何數據而直接提交表單的話就可以看到效果了。
好了,如果沒有什么問題的話就繼續往下看吧,如果有問題的話就得往上看了^_^
2:加入Spring框架
在這里我將Spring所有的包全部加載進去,因為我還不知道具體用到哪些類,全部加進去方便點
單選框選第二個,這樣的話所有的類庫和標簽等都將拷貝到項目中去,這樣方便以后的布署
下一步后是創建配置文件,將文件放到“WebRoot/WEB-INF”目錄下,文件名稱為“applicationContext.xml”
配置struts-config.xml文件,添加(spring)的插件
<plug-in className="org.springframework.web.struts.ContextLoaderPlugIn">
<set-property property="contextConfigLocation" value="/WEB-INF/applicationContext.xml" />
</plug-in>
修改LoginAction配置
原:
<action
attribute="loginForm"
input="/login.jsp"
name="loginForm"
path="/login"
scope="request"
validate="true"
type="com.test.struts.action.LoginAction" >
<forward name="ok" path="ok.jsp" />
</action>
</action-mappings>
改為:
<action
attribute="loginForm"
input="/login.jsp"
name="loginForm"
path="/login"
scope="request"
validate="true"
type="org.springframework.web.struts.DelegatingActionProxy">
<forward name="ok" path="ok.jsp" />
</action>
</action-mappings>
這里將使用spring的代理器來對Action進行控制
當提交到/login.do是將控制權交給了spring,然后由spring來決定是否轉回到struts的Action
現在來配置spring
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<bean name="/login" class="com.test.struts.action.LoginAction" singleton="false"></bean>
</beans>
好了,現在可以啟動Tomcat進行測試了如果沒有什么問題的話就繼續往下看吧,如果有問題的話就得往上看了^_^
3:創建Hibernate框架
建立數據庫在 這里我使用的是mysql4.1.18
CREATE TABLE `user` (
`ID` int(11) NOT NULL auto_increment,
`USERNAME` varchar(50) NOT NULL default '',
`PASSWORD` varchar(50) NOT NULL default '',
PRIMARY KEY (`ID`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
添加記錄 insert into user (USERNAME,PASSWORD) values ('test','test')
在配置界面中配置數據庫的連接部份,重要的是點擊鏈接將jdbc驅動拷貝到lib目錄中
使用MyEclipse的數據Database Explorer工具創建User.hmb.xml、AbstractUser.java、User.java映射文件
創建UserDAO.java、UserDAOImp.java
UserDAO.java:
public interface UserDAO {
public abstract boolean isValidUser(String username, String password);
}
UserDAOImp.java:
import java.util.List;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
public class UserDAOImp extends HibernateDaoSupport implements UserDAO {
private static String hql = "from User u where u.username=? and password=?";
public boolean isValidUser(String username, String password) {
String[] userlist=new String[2];
userlist[0]=username;
userlist[1]=password;
List userList = this.getHibernateTemplate().find(hql,userlist);
if (userList.size() > 0) {
return true;
}
return false;
}
}
修改LoginAction.java文件,使用userDao的方法來進行用戶驗證
package com.test.struts.action;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.validator.DynaValidatorForm;
import com.test.UserDAO;
public class LoginAction extends Action {
private UserDAO userDAO;
public UserDAO getUserDAO() {
return userDAO;
}
public void setUserDAO(UserDAO userDAO) {
this.userDAO = userDAO;
}
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response) {
DynaValidatorForm loginForm = (DynaValidatorForm) form;
// TODO Auto-generated method stub
String username = (String) loginForm.get("username");
String password = (String) loginForm.get("password");
loginForm.set("password", null);
if (userDAO.isValidUser(username,password)) {
return mapping.findForward("ok");
} else {
return mapping.getInputForward();
}
}
}
現在剩下最后的spring配置了
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName">
<value>com.mysql.jdbc.Driver</value>
</property>
<property name="url">
<value>jdbc:mysql://localhost/test</value>
</property>
<property name="username">
<value>root</value>
</property>
<property name="password">
<value>lxl</value>
</property>
</bean>
<!-- 配置sessionFactory, 注意這里引入的包的不同 -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource">
<ref local="dataSource" />
</property>
<property name="mappingResources">
<list>
<value>com/test/Hibernate/User.hbm.xml</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
</bean>
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory">
<ref local="sessionFactory" />
</property>
</bean>
<bean id="userDAO" class="com.test.UserDAOImp">
<property name="sessionFactory">
<ref local="sessionFactory" />
</property>
</bean>
<bean id="userDAOProxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager">
<ref bean="transactionManager" />
</property>
<property name="target">
<ref local="userDAO" />
</property>
<property name="transactionAttributes">
<props>
<prop key="insert*">PROPAGATION_REQUIRED</prop>
<prop key="get*">PROPAGATION_REQUIRED,readOnly</prop>
<prop key="is*">PROPAGATION_REQUIRED,readOnly</prop>
</props>
</property>
</bean>
<bean name="/login" class="com.test.struts.action.LoginAction" singleton="false">
<property name="userDAO">
<ref bean="userDAOProxy" />
</property>
</bean>
</beans>
現在可以進行測試了!
在編寫代碼有配置內容時一定要注意 hibernate 和 hibernate3 ,這兩個包的名字就只差一個字,千萬不要有錯,否則找錯誤可是很難的。
注意要把spring-hibernate.jar或者把spring.jar加到工程lib里
工程原碼見SSHlogin
本文來源:http://blog.csdn.net/xwchen/archive/2007/04/06/1554245.aspx
本文地址:http://www.newbooks.com.cn/info/120271.html
Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1562865