Spring框架就是個大雜燴(使用它后其他好多框架的配置文件都會被統一管理),它集成了好多技術,它的核心就是IOC控制反轉(以前我們創(chuàng)建對象時,控制權都在自己手中,因為需要自己去new對象,而用了spring后,它的ioc容器也就是spring的核心內褲會給我們自動創(chuàng)建對象并且可以注入屬性,控制權就不在我們手上,即控制權反轉了)Spring的ioc是用DI即依賴注入實現的,Spring里面包含的內容那是相當龐大的,但我感覺用的最普遍的就是它的IOC和AOP,所以先學了這個部分。
同樣和以前的總結方式一樣,我只會寫出重要的、常用的知識面:
1、閑話不多說了,每個框架都一樣,使用起來先加jar包、拷貝配置文件:
(1)spring.jar這是核心包,還有就是再加上兩個關于日志的包log4j-1.2.14.jar和commons-logging.jar就行了,由于我們要 用spring的AOP,所以在加個aspectj下的兩個jar包。
(2)接下來可以在spring提供的例子中拷貝applicationContext.xml和log4j.properties,我建的是Java項目
就直接考到src下(記得自己的項目盡量別放在有中文的目錄,這樣很可能會出問題)。
好了,基本工作就已經OK了,在學習Spring時有一點我是深有感觸呀,就是它內褲中的好多類名字那是相當的長呀,幸好我這男人還是比較心細的,能耐住性去寫,嘿嘿。
2、Spring 注入對象時可以用構造函數和set方法,但一般用set方法比較多。
3、當你給UserAction中注入了UserDAO,那么當你創(chuàng)建UserAction時就不能new了,必須從spring容器中獲得,否則UserDAO無法
注入進來。
4、Spring 中可以有多個配置文件,但<bean id="">這個id不能重復,雖然我們表面上看有好多個配置文件,但我們一起加載時, 實質內部也是放在一塊解析的。
5、org.springframework.beans.factory.config.CustomEditorConfigurer這是Spring提供的屬性類型轉換器。
6、在spring容器中如果有許多重復的屬性要配置,那么為了減少配置量可以配置公共的屬性,后面加上abstract="true",在需要 加入這些公共屬性的bean后加上parent="公共bean的id"
7、Spring 默認注入返回的實例都是單實例,即你第二次調用getBean方法返回同一個類實例,不會再次創(chuàng)建,但可以在容器中配 置它為多實例。
8、Spring 中還提供了自動裝配功能比如:根據名稱裝配(即在注入時不用配置類所依賴的屬性,只要類中屬性名跟配置文件的id 名稱相等就行)、根據類型裝配,這些都必須加額外的配置,spring默認是不支持的。
優(yōu)點:可以減少依賴配置。缺點:看不出類對象的依賴關系。(不建議使用)
9、AOP面向切面編程,這個切面可以理解成我們的關注點也就是要操作或者代理的方法或類,Spring的AOP只針對方法。
10、JDK提供的動態(tài)代理要實現這個接口java.lang.reflect.InvocationHandler,JDK的動態(tài)代理實現條件就是目標類必須實現一 個接口。
11、spring的AOP默認用JDK的動態(tài)代理實現,還可以有其他方式,比如:cglib,只要引入cglib的jar包再到ioc配置中設置一下 就可以了,如果目標對象沒有實現接口就要用cglib實現動態(tài)代理,cglib實現代理是創(chuàng)建目標對象的子類,因此目標對象不能 是final類型的。(我們在aop中也可以不用配置cglib的啟動,如果我們的目標對象實現了接口則spring默認會采用jdk的動態(tài) 代理,如果某些類沒有實現接口,則spring會自動切換到cglib,前提是加入了cglib的jar包)
12、spring的AOP實現方式:
(1)注解Annotation的方式——要加入兩個aop實現包(lib/aspectj/中的兩個jar包),spring對它做了集成(默認內部就是用JDK動態(tài)代理實現的)。
(2)采用配置方試——跟上面需要的包一樣,然后去ioc容器中配置。
一下列出spring的簡單配置:
1、先看下常用注入方式
<!-- 這里id就是ioc容器將要給你創(chuàng)建的對象的一個表示id,這個不能有重復,因為要在后臺加載對象時用,class屬性就
是ioc容器要裝載類的全名 -->
<bean id="userDao" class="com.mwt.daoImlements.UserDAO"/>
<bean id="departDao" class="com.mwt.daoImlements.DepartDAO"/>
<!-- 先采用構造器注入 -->
<bean id="userService" class="com.mwt.service.UserService">
<!-- 這里的ref就是引用上面已經配置好的類(也就是要注入的類) -->
<constructor-arg ref="userDao"/>
</bean>
<!-- 下面采用set方式注入 -->
<bean id="departService" class="com.mwt.service.DepartService">
<!-- 這里的property就指的是類中的域,name就是域的名字,ref跟上面的ref一樣即所引用要注入的類 -->
<property name="departDao" ref="departDao"/>
</bean>
2、普通屬性注入
<bean id="user" class="com.mwt.bean.User">
<property name="name" value="馬文濤"/>
<!-- 換種方式注入值 -->
<property name="age">
<value>728</value>
</property>
<property name="list">
<list>
<value>list1</value>
<value>list2</value>
</list>
</property>
<property name="set">
<set>
<value>set1</value>
<value>set2</value>
</set>
</property>
<property name="map">
<map>
<entry key="k1" value="v1"/>
<entry key="k2" value="v2"/>
</map>
</property>
<!-- 數組也用list去注入 -->
<property name="c">
<list>
<value>a</value>
<value>b</value>
</list>
</property>
<!-- 注入Date類型屬性 -->
<property name="date" value="2010-04-16"/>
</bean>
3、注解AOP配置:
/**
* 切面類,此類定義完后要在ioc容器中配置此類和目標類
* @author mawentao
* 類前面這個注解就聲明了我們這是切面
*/
@Aspect
public class Annotation {
/*
* 此方法沒實際意義,不會被調用,只是用它的方法名做個標示
* 此方法是公共的、沒返回值、沒參數
* 用注解聲明切點的描述,第一個*代表返回值可以是任何東西,save*代表方法名以save開頭的(spring的aop只是針對于方法),最后的(..)
* 標示可以帶任何參數
*/
@Pointcut("execution(* save*(..))")
public void markMethod(){}
/**
* 在切點前要加的檢查方法
* 用注解聲明在哪個切入點包括何時織入此方法
*/
@Before("markMethod()")
public void checkMethod(){
System.out.println("spring注解aop實現方法檢查");
}
}
配置文件如下:
<!-- 啟用spring的注解aop實現 -->
<aop:aspectj-autoproxy/>
<!-- 由于上面開啟了aop的注解實現,則當我們在后臺通過ioc獲得此dao時spring會給我們返回一個實現了和userDao相同接口的代理 -->
<bean id="userDao" class="com.mwt.daoImlements.UserDAO"/>
<!-- 下面這個切面類的注入id隨便起名字,因為id用不到,但這個類還必須注入,ioc會自動實例化這個對象 -->
<bean id="annotation" class="aop.annotation.Annotation"/>
4、采用純配置文件配置AOP實現:
package aop.config;
import org.aspectj.lang.JoinPoint;
/**
* 切面類,此類直接在ioc容器中配置
* @author mawentao
*/
public class AopConfig {
/**
* 要給切點織入的方法,在檢查方法中也可以獲得目標方法的名字和參數,它們都封裝在JoinPoint這個對象中。
*
*/
public void checkMethod(JoinPoint joinPoint){
Object[] obj = joinPoint.getArgs();//獲得參數列表
for(Object o:obj){
System.out.println(o);
}
System.out.println("方法名:"+joinPoint.getSignature().getName());
System.out.println("spring配置aop實現方法檢查");
}
}
下面是配置:
<bean id="userDao" class="com.mwt.daoImlements.UserDAO"/>
<!-- 下面這個是切面類 -->
<bean id="aopConfig" class="aop.config.AopConfig"/>
<aop:config>
<aop:aspect id="myAspect" ref="aopConfig">
<!--給切點加個標示即id,expression就是要匹配的表達式(第一個*是返回值,然后再跟上包名,也可以不跟包,緊接著..*代表當前包和子包,然后再.save*(..)代表所有save開頭,任何參數的方法) -->
<aop:pointcut id="markMethod" expression="execution(* com.mwt.daoImlements..*.save*(..))"/>
<!-- 切點應用的時刻和要織入的方法,再還要引用切點 -->
<aop:before method="checkMethod" pointcut-ref="markMethod"/>
</aop:aspect>
</aop:config>
5、屬性編輯器(當我們注入日期時,spring沒法給我們創(chuàng)建出合適的對象):
package com.mwt.util;
import java.beans.PropertyEditorSupport;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* 因為spring在注入java.util.Date,配置文件中的字符串無法進行自動轉換,所以才自己轉換
* 自定義屬性編輯器,繼承java.beans.PropertyEditorSupport此類,然后再在Spring的ioc容器中進行注冊。
* @author mawentao
*
*/
public class PropertyEditor extends PropertyEditorSupport {
@Override
public void setAsText(String text) throws IllegalArgumentException {
System.out.println("傳過來要轉換的字符串為:"+text);
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
try {
Date date = sdf.parse(text);
this.setValue(date);//此方法把轉換后的對象傳過去。
} catch (ParseException e) {
e.printStackTrace();
}
}
}
配置文件:
<!-- Spring提供了屬性編輯器工具類。這里id隨便起名字,不過所有spring配置文件中的id不能重復 -->
<bean id="customEditorConfigurer" class="org.springframework.beans.factory.config.CustomEditorConfigurer">
<property name="customEditors">
<map>
<!-- key值是固定寫法 -->
<entry key="java.util.Date">
<!-- 內部bean只能被外部bean引用,即它只能被注入到外部bean中,因為沒有id,別的bean無法引用 -->
<bean class="com.mwt.util.PropertyEditor"/>
</entry>
</map>
</property>
</bean>
本站僅提供存儲服務,所有內容均由用戶發(fā)布,如發(fā)現有害或侵權內容,請
點擊舉報。