這篇文章主要介紹了Spring框架怎么用,具有一定借鑒價值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。
成都創(chuàng)新互聯(lián)公司專注于冷水江企業(yè)網(wǎng)站建設(shè),響應(yīng)式網(wǎng)站開發(fā),商城建設(shè)。冷水江網(wǎng)站建設(shè)公司,為冷水江等地區(qū)提供建站服務(wù)。全流程定制網(wǎng)站,專業(yè)設(shè)計,全程項目跟蹤,成都創(chuàng)新互聯(lián)公司專業(yè)和態(tài)度為您提供的服務(wù)
Spring框架是由于軟件開發(fā)的復雜性而創(chuàng)建的。Spring使用的是基本的JavaBean來完成以前只可能由EJB完成的事情。然而,Spring的用途不僅僅限于服務(wù)器端的開發(fā)。從簡單性、可測試性和松耦合性角度而言,絕大部分Java應(yīng)用都可以從Spring中受益。Spring是一個輕量級控制反轉(zhuǎn)(IoC)和面向切面(AOP)的容器框架。
◆目的:解決企業(yè)應(yīng)用開發(fā)的復雜性
◆功能:使用基本的JavaBean代替EJB,并提供了更多的企業(yè)應(yīng)用功能
◆范圍:任何Java應(yīng)用
控制反轉(zhuǎn)(Inversion of Control,英文縮寫為IoC)把創(chuàng)建對象的權(quán)利交給框架,是框架的重要特征,并非面向?qū)ο缶幊痰膶S眯g(shù)語。它包括依賴注入和依賴查找。傳統(tǒng)的業(yè)務(wù)層,當需要資源時就在該業(yè)務(wù)層new資源,這樣耦合性(程序之間相互依賴關(guān)聯(lián))較高?,F(xiàn)在將new的部分交給spring,做到高內(nèi)聚低耦合。簡而言之:原先是每當調(diào)用dao層或service層方法時,由app來new,現(xiàn)在是將new的權(quán)利交給spring,要什么資源從spring中獲?。?/p>
1.下載框架所需的依賴jar包
spring官網(wǎng)為:http://spring.io/
下載jar包: http://repo.springsource.org/libs-release-local/org/springframework/spring
2.導入基本jar包
其實基本核心jar有beans;context;core;expression包,其他是依賴log4j日志。當然spring的jar不止這些,后期慢慢加上。
3.配置log4j配置文件
日志文件定義在src目錄下
### direct log messages to stdout ### log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.Target=System.err log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n ### direct messages to file mylog.log ### log4j.appender.file=org.apache.log4j.FileAppender log4j.appender.file.File=c\:mylog.log log4j.appender.file.layout=org.apache.log4j.PatternLayout log4j.appender.file.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n ### set log levels - for more verbose logging change 'info' to 'debug' ### log4j.rootLogger=info, stdout
4.測試日志文件是否部署成功
package com.clj.demo1; import org.apache.log4j.Logger; import org.junit.Test; /** * 演示日志用法 * @author Administrator * */ public class Demo1 { //創(chuàng)建日志類 private Logger log=Logger.getLogger(Demo1.class); @Test public void run1(){ //可以將log4j.rootLogger屬性中的info改為off則不會再控制臺顯示 log.info("執(zhí)行了"); } }
5.定義一個接口和實現(xiàn)類
接口:
package com.clj.demo2; public interface UserService { public void sayHello(); }
實現(xiàn)類
package com.clj.demo2; public class UserServiceImpl implements UserService{ private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } public void init(){ System.out.println("初始化。。"); } public void sayHello() { System.out.println("Hello Spring"+"\t"+name); } public void destory(){ System.out.println("銷毀。。"); } }
6.定義spring專屬的配置文件
定義名為applicationContext.xml,位置為src下,與日志文件同目錄,導入相對應(yīng)的約束,并將實現(xiàn)類注入到配置文件中,剛開始入門,使用bean約束
<?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:p="http://www.springframework.org/schema/p" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!-- 使用bean標簽 1.id值唯一(必寫) 2.注意:class為實現(xiàn)類路徑,不是接口(必寫) 3.init-method核心方法執(zhí)行之前初始化工作(選寫) 4.destroy-method核心方法執(zhí)行之后初始化工作(選寫)--> <bean id="userService" class="com.clj.demo2.UserServiceImpl" init-method="init" destroy-method="destory"> <property name="name" value="佳先森"></property> </bean> </beans>
7.測試
public class Demo1 { /** * 原始方式 */ @Test public void run(){ //創(chuàng)建實現(xiàn)類 UserServiceImpl s=new UserServiceImpl(); s.setName("佳先森"); s.sayHello(); } /** * 老的工廠版本BeanFactory * 舊的工廠不會創(chuàng)建配置文件對象 */ @Test public void run2(){ BeanFactory factory=new XmlBeanFactory(new ClassPathResource("applicationContext.xml")); UserService us=(UserService)factory.getBean("userService"); us.sayHello(); } /** * 使用spring框架IOC方式 * 新版本factory創(chuàng)建啟動服務(wù)器會創(chuàng)建配置文件對象,再次調(diào)用時無需加載工廠 */ @Test public void run3(){ //創(chuàng)建工廠,加載核心配置文件(ClassPathXmlApplicationContext從src下找) ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml"); //從工廠中獲取到對象(配置文件中的id值,這里用了多態(tài)) UserService usi=(UserService) ac.getBean("userService"); //調(diào)用對象的方法執(zhí)行 usi.sayHello(); } /** * 演示destroy-method方法 * bean摧毀方法不會自動執(zhí)行 * 除非scope= singleton或者web容器中會自動調(diào)用,但是main函數(shù)或測試用例需要手動調(diào)用(需要使用ClassPathXmlApplicationContext的close()方法) */ @Test public void run4(){ //創(chuàng)建工廠,加載核心配置文件(ClassPathXmlApplicationContext從src下找) ClassPathXmlApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml"); //從工廠中獲取到對象(配置文件中的id值,這里用了多態(tài)) UserService usi=(UserService) ac.getBean("userService"); //調(diào)用對象的方法執(zhí)行 usi.sayHello(); //ApplicationContext實現(xiàn)類提供close方法,將工廠關(guān)閉就可執(zhí)行destory-method方法 ac.close(); } }
其中舊工廠與新工廠的區(qū)別
* BeanFactory和ApplicationContext的區(qū)別
* BeanFactory -- BeanFactory采取延遲加載,第一次getBean時才會初始化Bean
* ApplicationContext -- 在加載applicationContext.xml時候就會創(chuàng)建具體的Bean對象的實例,還提供了一些其他的功能
* 事件傳遞
* Bean自動裝配
* 各種不同應(yīng)用層的Context實現(xiàn)
總結(jié):這是個最基本的demo,是將實現(xiàn)類配置到了spring配置文件中,每次啟動服務(wù)器時,就會加載配置文件,從而實例化了實現(xiàn)類
1、什么是依賴注入?
Spring 能有效地組織J2EE應(yīng)用各層的對象。不管是控制層的Action對象,還是業(yè)務(wù)層的Service對象,還是持久層的DAO對象,都可在Spring的 管理下有機地協(xié)調(diào)、運行。Spring將各層的對象以松耦合的方式組織在一起,Action對象無須關(guān)心Service對象的具體實現(xiàn),Service對 象無須關(guān)心持久層對象的具體實現(xiàn),各層對象的調(diào)用完全面向接口。當系統(tǒng)需要重構(gòu)時,代碼的改寫量將大大減少。依賴注入讓bean與bean之間以配置文件組織在一起,而不是以硬編碼的方式耦合在一起。理解依賴注入
依賴注入(Dependency Injection)和控制反轉(zhuǎn)(Inversion of Control)是同一個概念。具體含義是:當某個角色(可能是一個Java實例,調(diào)用者)需要另一個角色(另一個Java實例,被調(diào)用者)的協(xié)助時,在 傳統(tǒng)的程序設(shè)計過程中,通常由調(diào)用者來創(chuàng)建被調(diào)用者的實例。但在Spring里,創(chuàng)建被調(diào)用者的工作不再由調(diào)用者來完成,因此稱為控制反轉(zhuǎn);創(chuàng)建被調(diào)用者 實例的工作通常由Spring容器來完成,然后注入調(diào)用者,因此也稱為依賴注入。
不管是依賴注入,還是控制反轉(zhuǎn),都說明Spring采用動態(tài)、靈活的方式來管理各種對象。對象與對象之間的具體實現(xiàn)互相透明。
2. IOC和DI的概念
* IOC -- Inverse of Control,控制反轉(zhuǎn),將對象的創(chuàng)建權(quán)反轉(zhuǎn)給Spring?。?/p>
* DI -- Dependency Injection,依賴注入,在Spring框架負責創(chuàng)建Bean對象時,動態(tài)的將依賴對象注入到Bean組件中?。?/p>
3.演示
對于類成員變量,常用的注入方式有兩種
屬性set方法注入和構(gòu)造方法注入
先演示第一種:屬性set方法注入
1)持久層
package com.clj.demo3; public class CustomerDaoImpl { public void save(){ System.out.println("我是持久層的Dao"); } }
2)業(yè)務(wù)層
注意:此時是想將持久層注入到業(yè)務(wù)層,將創(chuàng)建持久層實例權(quán)利交給框架,條件是業(yè)務(wù)層必須提供持久層的成員屬性和set方法
package com.clj.demo3; /** * 依賴注入之將dao 層注入到service層 * @author Administrator * */ public class CustomerServiceImpl{ //提供成員屬相,提供set方法 private CustomerDaoImpl customerDao; public void setCustomerDao(CustomerDaoImpl customerDao) { this.customerDao = customerDao; } public void save(){ System.out.println("我是業(yè)務(wù)層的service..."); //1.原始方式 //new CustomerDaoImpl().save(); //2.spring 之IOC方式 customerDao.save(); } }
3)配置文件配置
<!-- 演示依賴注入 --> <bean id="customerDao" class="com.clj.demo3.CustomerDaoImpl"/> <bean id="customerService" class="com.clj.demo3.CustomerServiceImpl"> <!-- 將Dao注入到service層 --> <property name="customerDao" ref="customerDao"></property> </bean>
4)測試
/** * spring 依賴注入方式 * 將dao層注入到service層 */ @Test public void run2(){ //創(chuàng)建工廠,加載配置文件,customerService被創(chuàng)建,從而也創(chuàng)建了customerDao ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml"); CustomerServiceImpl csi=(CustomerServiceImpl) context.getBean("customerService"); csi.save(); }
第二種:構(gòu)造方法注入
1)pojo類并提供構(gòu)造方法
package com.clj.demo4; /** * 演示的構(gòu)造方法的注入方式 * @author Administrator * */ public class Car1 { private String cname; private Double price; public Car1(String cname, Double price) { super(); this.cname = cname; this.price = price; } @Override public String toString() { return "Car1 [cname=" + cname + ", price=" + price + "]"; } }
2)配置文件配置
<!-- 演示構(gòu)造方法注入方式 --> <bean id="car1" class="com.clj.demo4.Car1"> <!-- 寫法一<constructor-arg name="cname" value="寶馬"/> <constructor-arg name="price" value="400000"/> --> <!--寫法二 --> <constructor-arg index="0" value="寶馬"/> <constructor-arg index="1" value="400000"/> </bean>
3)測試
@Test public void run1(){ ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml"); Car1 car=(Car1) ac.getBean("car1"); System.out.println(car); }
拓展:構(gòu)造方法之將一個對象注入到另一個對象中
1)pojo類:目的:將上列中的車注入到人類,使之成為其中一個屬性,則必須在此類中提供車的成員屬性,并提供有參構(gòu)造方法
package com.clj.demo4; public class Person { private String name; private Car1 car1; public Person(String name, Car1 car1) { super(); this.name = name; this.car1 = car1; } @Override public String toString() { return "Person [name=" + name + ", car1=" + car1 + "]"; } }
2)配置文件
<!-- 構(gòu)造方法之將一個對象注入到另一個對象--> <bean id="person" class="com.clj.demo4.Person"> <constructor-arg name="name" value="佳先森"/> <constructor-arg name="car1" ref="car1"/> </bean>
4.如何注入集合數(shù)組
1)定義pojo類
package com.clj.demo4; import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.Properties; import java.util.Set; /** * 演示集合注入的方式 * @author Administrator * */ public class User { private String[] arrs; private List<String> list; private Set<String> sets; private Map<String,String> map; private Properties pro; public void setPro(Properties pro) { this.pro = pro; } public void setSets(Set<String> sets) { this.sets = sets; } public void setMap(Map<String, String> map) { this.map = map; } public void setList(List<String> list) { this.list = list; } public void setArrs(String[] arrs) { this.arrs = arrs; } @Override public String toString() { return "User [arrs=" + Arrays.toString(arrs) + ", list=" + list + ", sets=" + sets + ", map=" + map + ", pro=" + pro + "]"; } }
2)配置文件
<!-- 注入集合 --> <bean id="user" class="com.clj.demo4.User"> <!-- 數(shù)組 --> <property name="arrs"> <list> <value>數(shù)字1</value> <value>數(shù)字2</value> <value>數(shù)字3</value> </list> </property> <!-- list集合 --> <property name="list"> <list> <value>金在中</value> <value>王杰</value> </list> </property> <!-- set集合 --> <property name="sets"> <set> <value>哈哈</value> <value>呵呵</value> </set> </property> <!-- map集合 --> <property name="map"> <map> <entry key="aa" value="rainbow"/> <entry key="bb" value="hellowvenus"/> </map> </property> <!-- 屬性文件 --> <property name="pro"> <props> <prop key="username">root</prop> <prop key="password">123</prop> </props> </property> </bean>
3)測試
/** * 測試注入集合 */ @Test public void run3(){ ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml"); User user= (User) ac.getBean("user"); System.out.println(user); }
5.怎么分模塊開發(fā)
在主配置文件加入<import>標簽(假如此時在com.clj.test包下定義了一個配置文件applicationContext2.xml)
<!-- 分模塊開發(fā)之引入其他配置文件 --> <import resource="com/clj/test/applicationContext2.xml"/>
1、入門
1).導入jar包
除了先前6個包,玩注解還需一個spring-aop包
2).持久層和實現(xiàn)層(這里忽略接口)
持久層
package com.clj.demo1; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Component; import org.springframework.stereotype.Repository; /** * UserDaoImpl交給IOC的容器管理 * @author Administrator * */ public class UserDaoImpl implements UserDao{ @Override public void save() { System.out.println("保存客戶。。"); } }
業(yè)務(wù)層
package com.clj.demo1; import javax.annotation.PostConstruct; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; public class UserServiceImpl implements UserService{ @Override public void sayHello() { System.out.println("Hello spring"); } }
3).定義配置文件
此時約束條件需添加context約束,并添加組件掃描
<?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" 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"> <!-- bean definitions here --> <!-- 開啟注解掃面 :base-package指定掃面對 包--> <context:component-scan base-package="com.clj.demo1"/> </beans>
4)在實現(xiàn)類中添加注解
/** * 組件注解,可以用來標記當前的類 * 類似<bean id="userService" class="com.clj.demo1.UserServiceImpl"> * value表示給該類起個別名 */ @Component(value="userService") public class UserServiceImpl implements UserService{ //省略 }
5)編寫測試
/** * 注解方式 */ @Test public void run2(){ ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml"); UserService us=(UserService) ac.getBean("userService"); us.sayHello(); }
2.關(guān)于bean管理常用屬性
1. @Component:組件.(作用在類上) 最原始的注解,所有需要注解的類都寫這個沒問題,他是通用的
2. Spring中提供@Component的三個衍生注解:(功能目前來講是一致的)
* @Controller -- 作用在WEB層
* @Service -- 作用在業(yè)務(wù)層
* @Repository -- 作用在持久層
* 說明:這三個注解是為了讓標注類本身的用途清晰,Spring在后續(xù)版本會對其增強
3. 屬性注入的注解(說明:使用注解注入的方式,可以不用提供set方法)
* 如果是注入的普通類型,可以使用value注解
* @Value -- 用于注入普通類型
* 如果注入的是對象類型,使用如下注解
* @Autowired -- 默認按類型進行自動裝配 匹配的是類型,與注入類的類名無關(guān)
* 如果想按名稱注入
* @Qualifier -- 強制使用名稱注入 必須與Autowired一起用,指定類名,與注入的類名有關(guān)
* @Resource -- 相當于@Autowired和@Qualifier一起使用
* 強調(diào):Java提供的注解
* 屬性使用name屬性
4. Bean的作用范圍注解
* 注解為@Scope(value="prototype"),作用在類上。值如下:
* singleton -- 單例,默認值
* prototype -- 多例
5. Bean的生命周期的配置(了解)
* 注解如下:
* @PostConstruct -- 相當于init-method
* @PreDestroy -- 相當于destroy-method
1.演示屬性對象注解
條件:采用掃描的方式將屬性(name)和對象(userDaoImpl)注入到業(yè)務(wù)層中
1)持久層開啟注解掃描Repository
//@Component(value="userDao")通用類注解 @Repository(value="ud") public class UserDaoImpl implements UserDao{ @Override public void save() { System.out.println("保存客戶。。"); } }
2)業(yè)務(wù)層針對屬性和對象提供注解
package com.clj.demo1; import javax.annotation.PostConstruct; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; /** * 組件注解,可以用來標記當前的類 * 類似<bean id="userService" class="com.clj.demo1.UserServiceImpl"> * value表示給該類起個別名 */ //@Scope(value="grototype")多列的(singletype為單列) @Component(value="userService") public class UserServiceImpl implements UserService{ //屬性注解:相當于給name屬性注入指定的字符串,setName方法可以省略不寫 @Value(value="佳先森") private String name; /** * 引用注入方式一:Autowired() * 引用注入方式二:Autowired()+Qualifier * 引用注入方式三:@Resource(name="userDao") java方式,按名稱識別注入 */ //Autowired()按類型自動裝配注入(缺點:因為是按類型匹配,所以不是很準確) @Autowired() @Qualifier(value="ud") //按名稱注入,得與Autowired一起用,兩者一起能指定類 private UserDao userDao; //注意Qualifier中的value是指定UserDaoImpl類名頂上的注解名,也可以指定配置文件中bean的id名 /*public void setName(String name) { this.name = name; }*/ @Override public void sayHello() { System.out.println("Hello spring"+name); userDao.save(); } //@PostConstruct標簽用于action生命周期中初始化的注解 @PostConstruct public void init(){ System.out.println("初始化..."); } }
3)配置文件只需要開啟全部掃描即可
<?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" 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"> <!-- bean definitions here --> <!-- 開啟注解掃面 :base-package指定掃面對 包--> <context:component-scan base-package="com.clj.demo1"/> </beans>
注意:至于集合還是推薦使用配置文件方式
2.Spring框架整合JUnit單元測試
1)添加單元測試所需依賴包spring-test.jar
注意:基于myeclipes自帶Junit環(huán)境,但是有時因為版本問題,可能需要比較新的Junit環(huán)境,這里我在網(wǎng)上下了一個教新的 Junit-4.9的jar包,如果myeclipes較新的話無須考慮
2)編寫測試類,添加相對應(yīng)的注解
@RunWith與@ContextConfiguration(此是用于加載配置文件,因為默認從WebRoot路徑為一級目錄,加上此是認定src為一級目錄)
package com.clj.demo2; import javax.annotation.Resource; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import com.clj.demo1.UserService; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration("classpath:applicationContext.xml") public class Demo2 { @Resource(name="userService") private UserService userService; @Test public void run1(){ userService.sayHello(); } }
六.spring框架之AOP
1.什么是AOP
* 在軟件業(yè),AOP為Aspect Oriented Programming的縮寫,意為:面向切面編程,功能模塊化
* AOP是一種編程范式,隸屬于軟工范疇,指導開發(fā)者如何組織程序結(jié)構(gòu)
* AOP最早由AOP聯(lián)盟的組織提出的,制定了一套規(guī)范.Spring將AOP思想引入到框架中,必須遵守AOP聯(lián)盟的規(guī)范
* 通過預編譯方式和運行期動態(tài)代理實現(xiàn)程序功能的統(tǒng)一維護的一種技術(shù)
* AOP是OOP的延續(xù),是軟件開發(fā)中的一個熱點,也是Spring框架中的一個重要內(nèi)容,是函數(shù)式編程的一種衍生范型
* 利用AOP可以對業(yè)務(wù)邏輯的各個部分進行隔離,從而使得業(yè)務(wù)邏輯各部分之間的耦合度降低,提高程序的可重用性,同時提高了開發(fā)的效率
AOP采取橫向抽取機制,取代了傳統(tǒng)縱向繼承體系重復性代碼(性能監(jiān)視、事務(wù)管理、安全檢查、緩存)
2. 為什么要學習AOP
* 可以在不修改源代碼的前提下,對程序進行增強?。。楣潭ǖ姆椒ㄉ梢粋€代理,在訪問該方法之前,先進入代理,在代理中,可以編寫更多的功能,使之方法的功能更強,使得程序進行增 強)
Aop:面向切面編程,將一切事模塊化,每個模塊比較獨立,模塊可以共用(相同的),不同的格外自定義。用此替代傳統(tǒng)的面向縱向編程,提高程序的可重用性
3.AOP的實現(xiàn)(實現(xiàn)原理)
Aop的實現(xiàn)包含兩種代理方式<1>實現(xiàn)類接口:采用JDK動態(tài)代理<2>未實現(xiàn)類接口:采用CGLIB動態(tài)代理
1.實現(xiàn)JDK動態(tài)代理
1)定義持久層接口實現(xiàn)類
package com.clj.demo3; public interface UserDao { public void save(); public void update(); }
package com.clj.demo3; public class UserDaoImpl implements UserDao { @Override public void save() { System.out.println("保存用戶"); } @Override public void update() { System.out.println("修改用戶"); } }
2)定義JDK動態(tài)代理工具類
此工具類是在執(zhí)行持久層save方法時增加一些功能,在開發(fā)中做到在不更改源碼情況下增強某方法
package com.clj.demo3; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; /** * 使用JDK的方式生成代理對象(演示AOP原理) * @author Administrator * */ public class MyProxyUtils { public static UserDao getProxy(final UserDao dao){ //使用Proxy類生成代理對象 UserDao proxy=(UserDao)Proxy.newProxyInstance(dao.getClass().getClassLoader() , dao.getClass().getInterfaces(),new InvocationHandler() { //只要代理對象一執(zhí)行,invoke方法就會執(zhí)行一次 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { //proxy代表當前代理對象 //method當前對象執(zhí)行的方法 //args封裝的參數(shù) //讓到類的save或者update方法正常執(zhí)行下去 if("save".equals(method.getName())){ System.out.println("執(zhí)行了保存"); //開啟事務(wù) } return method.invoke(dao, args); } }); return proxy; } }
3)測試
package com.clj.demo3; import org.junit.Test; public class Demo1 { @Test public void run1(){ //獲取目標對象 UserDao dao=new UserDaoImpl(); dao.save(); dao.update(); System.out.println("==============="); //使用工具類,獲取到代理對象 UserDao proxy=MyProxyUtils.getProxy(dao); //調(diào)用代理對象的方法 proxy.save(); proxy.update(); } }
2.實現(xiàn)CGLIB技術(shù)
1)定義持久層,此時沒有接口
package com.clj.demo4; public class BookDaoImpl { public void save(){ System.out.println("保存圖書"); } public void update(){ System.out.println("修改圖書"); } }
2)編寫工具類
package com.clj.demo4; import java.lang.reflect.Method; import org.springframework.cglib.proxy.Enhancer; import org.springframework.cglib.proxy.MethodInterceptor; import org.springframework.cglib.proxy.MethodProxy; /** * Cglib代理方式實現(xiàn)原理 * @author Administrator * */ public class MyCglibUtils { /** * 使用CGLIB方式生成代理對象 * @return */ public static BookDaoImpl getProxy(){ Enhancer enhancer=new Enhancer(); //設(shè)置父類 enhancer.setSuperclass(BookDaoImpl.class); //設(shè)置回調(diào)函數(shù) enhancer.setCallback(new MethodInterceptor() { @Override public Object intercept(Object obj, Method method, Object[] objs, MethodProxy methodProxy) throws Throwable { if(method.getName().equals("save")){ System.out.println("我保存了"); System.out.println("代理對象執(zhí)行了"); } return methodProxy.invokeSuper(obj, objs);//是方法執(zhí)行下去 } }); //生成代理對象 BookDaoImpl proxy=(BookDaoImpl) enhancer.create(); return proxy; } }
3)編寫測試類
package com.clj.demo4; import org.junit.Test; public class Demo1 { @Test public void run1(){ //目標對象 BookDaoImpl dao=new BookDaoImpl(); dao.save(); dao.update(); System.out.println("=========="); BookDaoImpl proxy=MyCglibUtils.getProxy(); proxy.save(); proxy.update(); } }
3、Spring基于AspectJ的AOP的開發(fā)(配置文件方式)
1)部署環(huán)境,導入相對應(yīng)的jar包
2)創(chuàng)建配置文件,并引入AOP約束
<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" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
3)創(chuàng)建接口和實現(xiàn)類
package com.clj.demo5; public interface CustomerDao { public void save(); public void update(); }
package com.clj.demo5; /** * 采用配置文件的方式 詮釋AOP * @author Administrator * */ public class CustomerDaoImpl implements CustomerDao { @Override public void save() { //模擬異常 //int a=10/0; System.out.println("保存客戶了啊"); } @Override public void update() { // TODO Auto-generated method stub System.out.println("更新客戶了啊"); } }
4)定義切面類
package com.clj.demo5; import org.aspectj.lang.ProceedingJoinPoint; /** * 切面類:切入點+通知 * @author Administrator * */ public class MyAspectXml { /** * 通知(具體的增強) */ public void log(){ System.out.println("記錄日志"); } /** * 方法執(zhí)行成功或者異常都會執(zhí)行 */ public void after(){ System.out.println("最終通知"); } /** * 方法執(zhí)行之后,執(zhí)行后置通知,如果程序出現(xiàn)異常,后置通知不會執(zhí)行 */ public void afterReturn(){ System.out.println("后置通知"); } /** * 方法執(zhí)行之后,如果程序有異常,才會執(zhí)行異常通知 */ public void afterThrowing(){ System.out.println("異常通知"); } /** * 環(huán)繞通知:方法執(zhí)行之前和方法執(zhí)行之后進行通知, * 默認情況下,目標對象的方法不能執(zhí)行的,需要手動讓目標對象執(zhí)行 */ public void around(ProceedingJoinPoint joinPoint){ System.out.println("環(huán)繞通知1"); //手動讓目標對象的方法執(zhí)行 try { joinPoint.proceed(); } catch (Throwable e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println("環(huán)繞通知2"); } }
5)注入實現(xiàn)類和切面類
<?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:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <!-- bean definitions here --> <!-- 配置客戶的dao --> <bean id="customerDao" class="com.clj.demo5.CustomerDaoImpl"/> <!-- 編寫切面類配置好 --> <bean id="myAspectXml" class="com.clj.demo5.MyAspectXml"/> <!-- 配置AOP --> <aop:config> <!-- 配置切面類:切入點+通知 (類型)--> <aop:aspect ref="myAspectXml"> <!-- 配置前置通知,save方法執(zhí)行之前,增強方法會執(zhí)行 --> <!-- 切入點表達式:execution(public void com.clj.demo5.CustomerDaoImpl.save()) --> <!-- 切入點表達式: 1.execution()固定的,必寫 2.public可以省略不寫 3.返回值 必寫,嚴格根據(jù)切入點方法而定,否則增強方法不會執(zhí)行,可以用*代替,表示任意的返回值 4.包名 必寫,可以用*代替(如:*..*(默認所有包); com.clj.*) 5.類名 必寫,可以部分用*(如*DaoImpl表示以'DaoImpl'結(jié)尾的持久層實現(xiàn)類),但不建議用*代替整個類名 6.方法 必寫,可以部分用*(如save*表示以'save'開頭的方法),但不建議用*代替整個類名 7.方法參數(shù) 根據(jù)實際方法而定,可以用'..'表示有0或者多個參數(shù) --> <!-- <aop:before method="log" pointcut="execution(public void com.clj.*.CustomerDaoImpl.save(..))"/> --> <aop:before method="log" pointcut="execution(* *..*.*DaoImpl.save*(..))"/> </aop:aspect> </aop:config> </beans>
6)測試
package com.clj.demo5; import javax.annotation.Resource; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration("classpath:applicationContext.xml") public class Demo1 { @Resource(name="customerDao") private CustomerDao customerDao; @Test public void run(){ customerDao.save(); customerDao.update(); } }
擴展:切面類升級
<?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:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <!-- bean definitions here --> <bean id="myAspectXml" class="com.clj.demo5.MyAspectXml"/> <aop:config> <aop:aspect ref="myAspectXml"> <!-- 配置最終通知 <aop:after method="after" pointcut="execution(* *..*.*DaoImpl.save*(..))"/>--> <!-- 配置后置通知 <aop:after-returning method="afterReturn" pointcut="execution(* *..*.*DaoImpl.save*(..))"/>--> <!-- 配置異常通知 <aop:after-throwing method="afterThrowing" pointcut="execution(* *..*.*DaoImpl.save*(..))"/>--> <aop:around method="around" pointcut="execution(* *..*.*DaoImpl.update*(..))"/> </aop:aspect> </aop:config> </beans>
4、Spring框架AOP之注解方式
1)創(chuàng)建接口和實現(xiàn)類
package com.clj.demo1; public interface CustomerDao { public void save(); public void update(); }
package com.clj.demo1; public class CustomerDaoImpl implements CustomerDao{ @Override public void save() { // TODO Auto-generated method stub System.out.println("保存客戶.."); } @Override public void update() { // TODO Auto-generated method stub System.out.println("更新客戶"); } }
2)定義切面類
package com.clj.demo1; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.After; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.aspectj.lang.annotation.Pointcut; /** * 注解方式的切面類 * @Aspect表示定義為切面類 */ @Aspect public class MyAspectAnno { //通知類型:@Before前置通知(切入點的表達式) @Before(value="execution(public * com.clj.demo1.CustomerDaoImpl.save())") public void log(){ System.out.println("記錄日志。。"); } //引入切入點 @After(value="MyAspectAnno.fun()") public void after(){ System.out.println("執(zhí)行之后"); } @Around(value="MyAspectAnno.fun()") public void around(ProceedingJoinPoint joinPoint){ System.out.println("環(huán)繞通知1"); try { //讓目標對象執(zhí)行 joinPoint.proceed(); } catch (Throwable e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println("環(huán)繞通知2"); } //自定義切入點 @Pointcut(value="execution(public * com.clj.demo1.CustomerDaoImpl.save())") public void fun(){ } }
3)配置切面類和實現(xiàn)類,并開啟自動代理
<?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: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.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"> <!-- 開啟自動注解代理--> <aop:aspectj-autoproxy/> <!-- 配置目標對象 --> <bean id="customerDao" class="com.clj.demo1.CustomerDaoImpl"/> <!-- 配置切面類 --> <bean id="myAspectAnno" class="com.clj.demo1.MyAspectAnno"/> </beans>
spring提供了JDBC模板:JdbcTemplate類
1.快速搭建
1)部署環(huán)境
這里在原有的jar包基礎(chǔ)上,還要添加關(guān)乎jdbc的jar包,這里使用的是MySQL驅(qū)動
2)配置內(nèi)置連接池,將連接數(shù)據(jù)庫程序交給框架管理,并配置Jdbc模板類
<?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: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.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"> <!-- 先配置連接池(內(nèi)置) --> <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://192.168.174.130:3306/SSH"/> <property name="username" value="root"/> <property name="password" value="root"/> </bean> <!-- 配置JDBC的模板類--> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <property name="dataSource" ref="dataSource"/> </bean> </beans>
3)測試
package com.clj.demo2; import java.sql.ResultSet; import java.sql.SQLException; import java.util.List; import javax.annotation.Resource; import org.apache.commons.dbcp.BasicDataSource; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.cglib.beans.BeanMap; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.RowMapper; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; /** * 測試JDBC的模板類,使用IOC的方式 * @author Administrator * */ @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration("classpath:applicationContext.xml") public class Demo2 { @Resource(name="jdbcTemplate") private JdbcTemplate jdbcTemplate; /** * 插入 */ @Test public void run1(){ String sql="insert into t_account values(null,?,?)"; jdbcTemplate.update(sql,"李釔林",10000); } /** * 更新 */ @Test public void run2(){ String sql="update t_account set name=? where id=?"; jdbcTemplate.update(sql,"李釔林",1); } /** * 刪除 */ @Test public void run3(){ String sql="delete from t_account where id=?"; jdbcTemplate.update(sql,4); } /** * 測試查詢,通過主鍵來查詢一條記錄 */ @Test public void run4(){ String sql="select * from t_account where id=?"; Account ac=jdbcTemplate.queryForObject(sql, new BeanMapper(),1); System.out.println(ac); } /** * 查詢所有 */ @Test public void run5(){ String sql="select * from t_account"; List<Account> ac=jdbcTemplate.query(sql,new BeanMapper()); System.out.println(ac); } } /** * 定義內(nèi)部類(手動封裝數(shù)據(jù)(一行一行封裝數(shù)據(jù),用于查詢所有) * @author Administrator * */ class BeanMapper implements RowMapper<Account>{ @Override public Account mapRow(ResultSet rs, int rowNum) throws SQLException { Account ac=new Account(); ac.setId(rs.getInt("id")); ac.setName(rs.getString("name")); ac.setMoney(rs.getDouble("money")); return ac; } }
2、配置開源連接池
一般現(xiàn)在企業(yè)都是用一些主流的連接池,如c3p0和dbcp
首先配置dbcp
1)導入dbcp依賴jar包
2)編寫配置文件
<!-- 配置DBCP開源連接池--> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://192.168.174.130:3306/SSH"/> &nb網(wǎng)頁題目:Spring框架怎么用
本文來源:http://chinadenli.net/article16/ihggdg.html成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站導航、、做網(wǎng)站、Google、網(wǎng)站營銷、品牌網(wǎng)站制作
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)