一臀稚、Spring框架
1吝岭、簡介
spring最大的功能就是控制反轉(zhuǎn)(IOC)、面向切面編程(AOP)吧寺!
支持事務(wù)的處理窜管,對框架整合的支持!
2稚机、組成
Spring是一個分層框架,它有七個模塊組成;每個模塊可以相互獨立存在于項目中,同時每個模塊又可以被其他第三方的框架兼容使用;
Spring的7大模塊分別為:spring Core幕帆、Spring Context、Spring AOP赖条、Spring ORM失乾、Spring Dao、Spring MVC纬乍、spring web碱茁,其框架結(jié)構(gòu)如下圖所示:
3、拓展
Spring Boot
- 一個快速開發(fā)的腳手架
- 基于spring boot可以快速的開發(fā)單個微服務(wù)
- 約定大于配置仿贬!
Spring cloud
- springcloud是基于spring boot實現(xiàn)的
因為大多數(shù)公司都在使用spring boot進行快速開發(fā)纽竣,學(xué)習(xí)spring boot前提,需要完全掌握spring及Spring MVC茧泪!承上啟下的作用蜓氨!
4、spring入門案例
1队伟、創(chuàng)建項目穴吹、導(dǎo)入spring依賴
2、配置spring配置文件
<?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">
<!--配置user對象創(chuàng)建-->
<bean id="user" class="com.dao.userDao" abstract="true"></bean>
</beans>
3缰泡、測試代碼編寫
@Test
public void test(){
ApplicationContext context=new ClassPathXmlApplicationContext("spring.xml");
userDaoImpl userDaoImpl=context.getBean("user", com.dao.userDaoImpl.class);
userDaoImpl.getUser();
}
二刀荒、IOC理論推導(dǎo)
1、userDao接口
2棘钞、userDaoImpl實現(xiàn)類缠借,實現(xiàn)類可能會有多個
3、userService業(yè)務(wù)接口
4宜猜、userServicrImpl業(yè)務(wù)實現(xiàn)類
在我們之前的業(yè)務(wù)中泼返,用戶的需求可能會影響我們原來的代碼,我們需要根據(jù)用戶的需求去修改代碼姨拥,如果代碼量大绅喉。修改一次成本很大渠鸽。
使用了set注入后,程序不用在主動性柴罐,而是變成了被動的對象
public class mytest {
public static void main(String[] args) {
userService users=new userServicrImpl();
((userServicrImpl) users).setuserDao(new userDaoImpl());
users.getUser();
}
}
Ioc工程
第一步:創(chuàng)建spring的配置文件
id:唯一標(biāo)識
class:創(chuàng)建對象類的全路徑(包類路徑)
<!--配置創(chuàng)建-->
<bean id="user" class="com.dao.userDaoImpl"></bean>
第二步:有service類和dao類徽缚,創(chuàng)建工廠類
class userFactory{
pub;ic static userDao getDao(){
String classValue=class.屬性值 //xml解析
Class class=Class.forName(classValue) //通過反射創(chuàng)建對象
return (UserDao)class.newInstance()
}
}
Spring 提供IOC容器實現(xiàn)兩種方式:(兩個接口)
BeanFactory:IOC容器基本實現(xiàn),是spring內(nèi)部的使用
ApplicationContext:是BeanFactory的子接口革屠,比其功能更加強大凿试,常用
也就是我們徹底不用再程序中去改動代碼了,要實現(xiàn)不同的操作似芝,只需要在xml文件中進行修改那婉,
IOC就是將對象有spring來創(chuàng)建、管理和裝配党瓮。
三详炬、spring配置說明
別名
<!--別名,添加了別名之后寞奸,可以使用別名獲取到這個對象-->
<alias name="user" alias="userssss"></alias>
bean的配置
id:唯一標(biāo)識
class:創(chuàng)建對象類的全路徑(包類路徑)
<!--配置創(chuàng)建-->
<bean id="user" class="com.dao.userDaoImpl"></bean>
import
import一般用于團隊開發(fā)使用呛谜,可以將多個配置文件,導(dǎo)入合并為一個
四枪萄、依賴 注入
構(gòu)造器注入
<bean id="hello1" class="com.app.Hello">
<constructor-arg index="0" value="arg1"/>
<constructor-arg index="1" value="2"/><!-- arg2 -->
<constructor-arg index="2" ref="world"/><!-- arg3 -->
</bean>
set注入
依賴注入:set注入呻率,bean對象的創(chuàng)建依賴于容器,bean對象的所有屬性由容器注入
使用property完成屬性注入
name:類里面屬性名稱
value:向?qū)傩宰⑷氲闹?/p>
<bean id="student" class="com.bean.Student">
<!--普通注入--><!-- bean注入用ref-->
<property name="name" value="莉莉"/>
<property name="adress" value="福建"/>
<!--數(shù)組注入-->
<property name="books">
<array>
<value>紅樓夢</value>
<value>西游記</value>
</array>
</property>
<!--list注入-->
<property name="hobbys">
<list>
<value>聽歌</value>
<value>打代碼</value>
</list>
</property>
<!--map注入-->
<property name="card">
<map>
<entry key="身份證" value="123"></entry>
<entry key="信用卡" value="456"></entry>
</map>
</property>
<!--set注入-->
<property name="games">
<set>
<value>斗地主</value>
<value>王者榮耀</value>
</set>
</property>
</bean>
student
public class Student {
String name;
String address;
String[] books;
List<String> hobbys;
Map<String,String> card;
Set<String> games;
}
測試
@Test
public void test2(){
ApplicationContext context=new ClassPathXmlApplicationContext("spring.xml");
Student student= (Student) context.getBean("student");
System.out.println(student.toString());
}
其他方法注入
c命名空間和p命名空間
p命名空間注入可以直接注入屬性的值
1呻引、引入
xmlns:p="http://www.springframework.org/schema/p"
2礼仗、使用
p命名空間注入可以直接注入屬性的值,相當(dāng)于property
<bean id="student" class="com.bean.Student" p:name="莉莉" p:address="福建">
<!--普通注入--><!-- bean注入用ref
--<property name="name" value="莉莉"/>
--<property name="adress" value="福建"/>
-->
</bean>
1逻悠、導(dǎo)入
xmlns:c=”http://www.springframework.org/schema/c”
2元践、使用c命名空間并且是使用構(gòu)造參數(shù)的索引作為屬性來通過構(gòu)造方法注入的bean定義
<!-- 傳統(tǒng)的使用constructor-arg通過構(gòu)造方法注入的bean定義 -->
<bean id="hello1" class="com.app.Hello">
<constructor-arg index="0" value="arg1"/>
<constructor-arg index="1" value="2"/><!-- arg2 -->
<constructor-arg index="2" ref="world"/><!-- arg3 -->
</bean>
<!-- 使用c命名空間并且是使用構(gòu)造參數(shù)的索引作為屬性來通過構(gòu)造方法注入的bean定義 -->
<bean id="hello2" class="com.app.Hello" c:_0="c_arg1" c:_1="2" c:_2-ref="world"/>
bean的作用域
目前Spring Bean的作用域或者說范圍主要有五種。
1童谒、單例模式(spring默認)
<bean id="student" class="com.bean.Student" scope="singleton"></bean>
2单旁、原型模式-prototype:每次從容器中g(shù)et的時候,都會產(chǎn)生一個新對象饥伊!
3象浑、其余的,只能在web開發(fā)中使用到
五琅豆、Bean自動裝配
自動裝配是spring 滿足bean依賴一種方式愉豺!
-
spring 會在上下文中自動尋找,并自動給bean裝配屬性
在spring有三種裝配屬性
1茫因、xml中顯示的配置
2蚪拦、在java中顯示配置
3、隱射的自動裝配bean
byName和byType
byname:會字段在容器上下文件中查找,和自己對象set方法后面相對應(yīng)的beanid
<bean id="cat" class="com.bean.Cat"></bean>
<bean id="dog" class="com.bean.Dog"></bean>
<bean id="people" class="com.bean.People" autowire="byName">
</bean>
byType:會字段在容器上下文件中查找驰贷,和自己對象屬性類型相同的beanid
<bean class="com.bean.Cat"></bean>
<bean class="com.bean.Dog"></bean>
<bean id="people" class="com.bean.People" autowire="byType">
</bean>
注意:
byname的時盛嘿,需要保證所有的bean的id唯一,并且bean需要和自動注入的屬性的set方法的值一致括袒;
bytype的時次兆,需要保證所有的bean的class唯一,并且bean需要和自動注入的屬性類型一致锹锰;
注解實現(xiàn)自動裝配
jdk1.5支持的注解类垦,spring2.5就支持注解了!
使用須知:
public class People {
String name;
@Autowired
Dog dog;
@Autowired
Cat cat;
}
1城须、導(dǎo)入約束,context約束
2米苹、配置注解的支持**<context:annotation-config/>**
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
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-4.2.xsd">
<!--開啟注解的支持-->
<context:annotation-config/>
<bean id="dog" class="com.bean.Dog"></bean>
<bean id="cat" class="com.bean.Cat"></bean>
<bean id="people" class="com.bean.People">
</bean>
</beans>
3糕伐、測試
public class test {
public static void main(String[] args) {
ApplicationContext context=new ClassPathXmlApplicationContext("spring-config.xml");
People people = context.getBean("people", People.class);
people.getDog().shout();
}
}
@Autowired
直接在屬性上使用即可,也可以在set方式上使用蘸嘶!
使用Autowired我們可以不用編寫set方法了良瞧,前提是你這個自動裝配的屬性在IOC(spring)容器中存在,且符合名字byname训唱!
科普:
@Nullable:字段標(biāo)記了這個注解褥蚯,說明這個字段可以為null
如果@Autowired自動裝配的環(huán)境比較復(fù)雜,自動裝配無法通過一個注解【Autowired】完成的時候况增,我們可以使用@Qualifier(value="XXX")去配置Autowired的使用赞庶,使用唯一的bean對象注入。
小結(jié):
@Resource 和@Autowired的區(qū)別:
- 都是用來自動裝配的澳骤,都可以放在屬性字段上
- @Autowired 通過byType的方式實現(xiàn)歧强,而且必須要求這個對象存在!
- @Resource默認通過byname的方式實現(xiàn),如果找不到名字为肮,則通過byType實現(xiàn)摊册!如果兩個都找不到的情況下就報錯!
- 執(zhí)行順序不同:@AutoWired通過byType的方式實現(xiàn)
六颊艳、使用注解開發(fā)
在spring4之后茅特,要使用注解開發(fā),必須要求aop的包導(dǎo)入了
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
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-4.2.xsd">
<!--指定要掃描的包棋枕,這個包下的注解就會生效-->
<context:component-scan base-package="com.pojo"/>
<!--開啟注解的支持-->
<context:annotation-config/>
<bean id="dog" class="com.bean.Dog" scope="prototype"></bean>
<bean id="cat" class="com.bean.Cat"></bean>
<bean id="people" class="com.bean.People">
<property name="name" value="楠楠"></property>
</bean>
</beans>
1白修、bean
@Component:組件,放在類上面重斑,說明這個類被spring管理了熬荆,就是bean
2、屬性如何注入
@Value("楠楠") //相當(dāng)于<property name="name" value="楠楠"></property>
String name;
3、衍生的注解
@Component有幾個衍生的注解卤恳,我們在web開發(fā)中累盗,會按照mvc三層架構(gòu)分層!
dao @Repository
@Repository
public class Dog {
String shout;
}
service @Service
controller @Controller
這四個注解的功能都是一樣的突琳,都是代表將某個類注解到spring中若债,bean!
4拆融、自動裝配置
@Autowired:自動裝配通過類型名字
如果@Autowired不能尾牙自動裝配上屬性蠢琳,則需要通過@Qualifier(value="XXX")
@Nullable:字段標(biāo)記了這個注解,說明這個字段可以為null
@Resource:自動裝配通過名字镜豹,類型
5傲须、作用域
@Scope("singleton") 單例模式
@Scopr(" prototype") 原型模式
@Component
@Scope("prototype")
public class People {
@Value("hahaha")
String name;
@Autowired
Dog dog;
@Autowired
Cat cat;
}
小結(jié):
xml與注解:
- xml更加萬能,適用于任何場合趟脂,維護簡單方便
- 注解不是自己類的話使用不了泰讽,維護相對復(fù)雜
xml與注解的最佳實踐
- xml用來管理bean
- 注解只負責(zé)完成屬性的注入
- 我們在使用的過程中,只需要注意一個問題:必須讓注解生效昔期,就要開啟注解的支持
<!--指定要掃描的包已卸,這個包下的注解就會生效-->
<context:component-scan base-package="com.pojo"/>
<!--開啟注解的支持-->
<context:annotation-config/>
七、使用java的方式配置spring
在這種java的配置方式硼一,在spring boot方式中隨處可見
javaconfig是spring的一個子項目累澡,在spring4之后,它成為了一個新功能
user.class
@Component
public class User {
@Value("康康")
String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
'}';
}
}
MyConfig.class
//這個也會被注冊到spring容器般贼,因為這個也是個組件Component
//@Configuration 代表這是一個配置類愧哟,和我們之前看的spring.xml一樣
@Configuration
@ComponentScan("com.dao") //可以進行掃描
public class MyConfig {
//注冊一個bean,就相當(dāng)于我們之前寫的bean標(biāo)簽哼蛆,這個方法的名字羞反,就是相當(dāng)于bean標(biāo)簽中的id屬性
//這個方法的返回值就相當(dāng)于bean標(biāo)簽的class
@Bean
public User getUser(){
return new User();
}
}
測試:
public class Mytest {
public static void main(String[] args) {
//如果完全使用了配置方式去做我們可以通過ApplicationContext上下文來獲取容器
ApplicationContext Context =new AnnotationConfigApplicationContext(MyConfig.class);
User get= (User) Context.getBean("getUser");
System.out.println(get.getName());
}
}
八芒涡、代理模式
為什么要學(xué)習(xí)代理模式,因為這個就是spring AOP的底層
代理模式的方式:
動態(tài)代理
靜態(tài)代理
靜態(tài)代理
角色分析:
- 抽象角色:一般會使用接口或抽象類來解決
- 真實角色:被代理的角色
- 代理角色:代理真實角色,代理真實角色后哈垢,我們一般會做一些附屬操作
- 客戶:訪問代理對象的人禽笑!
操作步驟:
1阎毅、接口
public interface Rent {
public void rent();
}
2蜜笤、真實角色
public class Host implements Rent{
public void rent() {
System.out.println("房東要出租房子");
}
}
3、代理角色
public class Proxy {
Host host;
public Proxy(Host host) {
seeHouse();
writehtong();
fare();
this.host = host;
}
public Proxy() {
}
public void rent(){
host.rent();
}
public void seeHouse(){
System.out.println("中介帶你看房子");
}
public void fare(){
System.out.println("收中介費用");
}
public void writehtong(){
System.out.println("簽合同");
}
}
4惕味、客戶端訪問代理角色
public class Client {
public static void main(String[] args) {
Host host=new Host();
Proxy xy=new Proxy(host);
xy.rent();
}
}
代理模式的好處:
- 可以使真實角色的操作更加純碎楼誓,不用去關(guān)注一些公共的業(yè)務(wù)
- 公共的就是交給代理角色!實現(xiàn)了業(yè)務(wù)的分工
- 公共業(yè)務(wù)發(fā)生擴展的時候名挥,方便集中管理疟羹!
缺點:
一個真實角色就會產(chǎn)生一個代理角色,代碼量會翻倍,開發(fā)效率會低
加深理解
動態(tài)代理:
動態(tài)代理和靜態(tài)代理的角色一樣
動態(tài)代理的代理類是動態(tài)生成的榄融,不是我們直接寫好的
-
動態(tài)代理分為兩大類:基于接口的動態(tài)代理参淫,基于類的動態(tài)代理
基于接口---JDK動態(tài)代理(在這里使用)
基于類:cglib
java字節(jié)碼實現(xiàn):javasist
需要了解兩個類:Proxy代理 InvocationHandler:調(diào)用處理程序
JDK動態(tài)代理
使用JDK動態(tài)代理需要使用:
Proxy.newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h)
參數(shù)說明:
- ClassLoader loader: the class loader to define the proxy class,用于定義代理類的類加載器
- Class<?>[] interfaces: the list of interfaces for the proxy class愧杯,代理類的接口列表
- InvocationHandler h: to implement涎才,由代理實例的調(diào)用處理程序?qū)崿F(xiàn)的接口
出租的接口:
public interface Rent {
public void rent();
}
房東:
public class Host implements Rent {
public void rent() {
System.out.println("房東要出租房子");
}
}
代理
//會使用這個類,自動生成代理類
public class ProxyInvocationHandler implements InvocationHandler {
//被代理的接口
Rent rent;
public void setRent(Rent rent) {
this.rent = rent;
}
//生成的到代理類
public Object getProxy(){
return Proxy.newProxyInstance(this.getClass().getClassLoader(), rent.getClass().getInterfaces(),this);
}
//處理代理實例力九,并返回結(jié)果
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//動態(tài)代理的本質(zhì)耍铜,就是使用反射機制實現(xiàn)!
Object result=method.invoke(rent,args);
seehouse();
fare();
return result;
}
public void seehouse(){
System.out.println("中介帶去看房子");
}
public void fare(){
System.out.println("中介收取費用");
}
}
測試
public class Client {
public static void main(String[] args) {
//真實角色
Host host=new Host();
/*代理角色*/
ProxyInvocationHandler pih=new ProxyInvocationHandler();
//通過調(diào)用程序處理角色來處理我們要調(diào)用的接口對象跌前!
pih.setRent(host);
Rent proxy=(Rent) pih.getProxy();
proxy.rent();
}
}
動態(tài)代理的好處:
可以使真實角色的操作更加純碎棕兼,不用去關(guān)注一些公共的業(yè)務(wù)
公共的就是交給代理角色!實現(xiàn)了業(yè)務(wù)的分工
公共業(yè)務(wù)發(fā)生擴展的時候抵乓,方便集中管理伴挚!
一個動態(tài)代理類代理的是一個接口,一般就是對應(yīng)一類業(yè)務(wù)
九臂寝、AOP
什么是AOP
AOP(Aspect Oriented Programming)意為:面向切面編程,通過預(yù)編譯方式和運行期動態(tài)代理實現(xiàn)程序功能的統(tǒng)一維護的一種技術(shù)摊灭。利用AOP可以對業(yè)務(wù)邏輯的各個部分進行隔離咆贬,從而使得業(yè)務(wù)邏輯各部分之間的耦合度降低,提高程序的可重用性帚呼,同時提高了開發(fā)的效率掏缎。
AOP在Spring中的作用
提供聲明式事務(wù);允許用戶自定義切面
以下名詞需要了解下:
橫切關(guān)注點:跨越應(yīng)用程序多個模塊的方法或功能煤杀。即是眷蜈,與我們業(yè)務(wù)邏輯無關(guān)的,但是我們需要關(guān)注的部分沈自,就是橫切關(guān)注點酌儒。如日志 , 安全 , 緩存 , 事務(wù)等等 …
切面(ASPECT):橫切關(guān)注點 被模塊化 的特殊對象。即枯途,它是一個類忌怎。
通知(Advice):切面必須要完成的工作。即酪夷,它是類中的一個方法榴啸。
目標(biāo)(Target):被通知對象。
代理(Proxy):向目標(biāo)對象應(yīng)用通知之后創(chuàng)建的對象晚岭。
切入點(PointCut):切面通知 執(zhí)行的 “地點”的定義鸥印。
連接點(JointPoint):與切入點匹配的執(zhí)行點。
即 Aop 在 不改變原有代碼的情況下 , 去增加新的功能 .
在springAOP中,通過advice定義橫切邏輯库说,spring中支持5中類型的advice:
前置通知狂鞋、后置通知、環(huán)繞通知(方法前后)璃弄、異常拋出通知要销、引介通知(類中增加新的方法屬性)
即AOP在不改變原有代碼的情況下,去增加新的功能夏块。
使用Spring實現(xiàn)aop
導(dǎo)入依賴(使用AOP織入需要導(dǎo)入依賴)
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.1</version>
</dependency>
方式一:使用spring的接口
主要是spring aop接口實現(xiàn)
UserService
public interface UserService {
public void add();
public void delete();
public void find();
public void query();
}
UserServiceImpl
public class UserServiceImpl implements UserService {
public void add() {
System.out.println("增加了一個用戶");
}
public void delete() {
System.out.println("刪除了一個用戶");
}
public void find() {
System.out.println("找到了一個用戶");
}
public void query() {
System.out.println("查詢了一個用戶");
}
}
springconfig.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: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-->
<bean id="userService" class="com.service.UserServiceImpl"/>
<bean id="log" class="com.log.Log"/>
<bean id="afterlog" class="com.log.Afterlog"/>
<!--方式一:使用原生spring 接口-->
<!--配置aop:需要導(dǎo)入aop的約束-->
<aop:config>
<!--切入點 expression表達式疏咐,execution(要執(zhí)行的位置!)-->
<aop:pointcut id="pointcut" expression="execution(* com.service.*.*(..))"/>
<!--分別將log 和afterlog切入到其中-->
<aop:advisor advice-ref="log" pointcut-ref="pointcut"/>
<aop:advisor advice-ref="afterlog" pointcut-ref="pointcut"></aop:advisor>
</aop:config>
</beans>
測試類
public class Mytest {
private static UserService userService;
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("springconfig.xml");
userService= (UserService) context.getBean("userService");
userService.add();
}
}
方式二:自定義類來實現(xiàn)aop
主要是切面定義
public class DiyPoinCut {
public void before(){
System.out.println("執(zhí)行前");
}
public void after(){
System.out.println("執(zhí)行后");
}
}
<!--方式二:自定義類-->
<bean id="diy" class="com.diy.DiyPoinCut"></bean>
<aop:config>
<!--自定義切面 ref要引用的類-->
<aop:aspect ref="diy">
<!--切入點-->
<aop:pointcut id="point" expression="execution(* com.service.UserServiceImpl.*(..))"/>
<!--通知-->
<aop:before method="before" pointcut-ref="point"/>
<aop:after method="after" pointcut-ref="point"/>
</aop:aspect>
</aop:config>
測試不變
方式三:使用注解實現(xiàn)
@Aspect //標(biāo)注這個類是一個切面
public class AnotPoint {
@Before("execution(* com.service.UserServiceImpl.*(..))")
public void Tbefore(){
System.out.println("執(zhí)行前——---");
}
@After("execution(* com.service.UserServiceImpl.*(..))")
public void Tafter(){
System.out.println("執(zhí)行后——---");
}
@Around("execution(* com.service.UserServiceImpl.*(..))")
public void Tter(ProceedingJoinPoint pjp) throws Throwable {
System.out.println("環(huán)繞前");
pjp.proceed();
System.out.println("環(huán)繞后");
}
}
<bean id="anotPoint" class="com.diy.AnotPoint"></bean>
<!-- 開啟注解支持脐供! JDK(默認)-proxy-target-class="false" cglib-proxy-target-class="true"-->
<aop:aspectj-autoproxy proxy-target-class="false"/>
十浑塞、整合Mybatis
回憶Mybatis
1、導(dǎo)入相關(guān)jar包
junit政己、mybatis酌壕、mysql數(shù)據(jù)庫、spring相關(guān)的歇由、aop織入卵牍、mybatis-spring
2、編寫配置文件
3沦泌、測試
注意:Maven:src/main/resources中xml文件不加載到classpath中
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
<include>**/*.xls</include>
<include>**/*.xlsx</include>
</includes>
<filtering>true</filtering>
</resource>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>true</filtering>
</resource>
</resources>
</build>
Mybatis-spring
1糊昙、編寫數(shù)據(jù)源配置
2、sqlSessionFactory
3谢谦、sqlSessionTemplate
4释牺、需要給接口加實現(xiàn)類
5、將自己寫的實現(xiàn)類注入到spring中
6回挽、測試使用即可
Mybatis.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<!--mybatis的主配置文件-->
<configuration>
<typeAliases>
<typeAlias type="com.dao.User" alias="User"></typeAlias>
</typeAliases>
<!--
<environments default="mysql">
<environment id="mysql">
<transactionManager type="jdbc"></transactionManager>
<dataSource type="POOLED">
<!–配置數(shù)據(jù)庫的4個基本信息–>
<property name="driver" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/myweb" />
<property name="username" value="root" />
<property name="password" value="root" />
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="com/mapper/UserMapper.xml"></mapper>
</mappers>-->
</configuration>
spring.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: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">
<!-- dataresource:使用spring的數(shù)據(jù)源替換mybatis的配置
我們這里屬于spring 提供的jdbc:org.springframework.jdbc.datasource-->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/myweb"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</bean>
<!--sqlSessionFactory-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property>
<!--綁定mybatis的配置文件-->
<property name="configLocation" value="classpath:Mybatis.xml"/>
<property name="mapperLocations" value="classpath:com/mapper/*.xml"/>
</bean>
<!-- SqlSessionTemplate:就是我們使用的sqlsession-->
<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
<!--只能使用構(gòu)造器注入sqlSessionFactory没咙,因為它沒有set方法-->
<constructor-arg index="0" ref="sqlSessionFactory"/>
</bean>
<bean id="userDao" class="com.dao.UserDaoImp">
<property name="sessionTemplate" ref="sqlSession"/>
</bean>
</beans>
接口實現(xiàn)UserDaoImp
public class UserDaoImp implements UserDao {
SqlSessionTemplate sessionTemplate;
public UserDaoImp() {
}
public void setSessionTemplate(SqlSessionTemplate sessionTemplate) {
this.sessionTemplate = sessionTemplate;
}
public List<User> findAll() {
UserDao userDao = (UserDao)this.sessionTemplate.getMapper(UserDao.class);
return userDao.findAll();
}
}
測試
@Test
public void Test(){
ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
UserDao userDao=context.getBean("userDao",UserDao.class);
for(User user:userDao.findAll()){
System.out.println(user);
}
}
十一、聲明式事務(wù)
回顧事務(wù)
- 把一組業(yè)務(wù)當(dāng)成一個業(yè)務(wù)來做千劈,要么都成功祭刚,要么都失敗
- 事務(wù)在項目開發(fā)中,十分重要墙牌,涉及到數(shù)據(jù)的一致性問題袁梗,不能馬虎
- 確保完整性和一致性
事務(wù)的四大特性
原子性
事務(wù)是數(shù)據(jù)庫的邏輯工作單位,事務(wù)中包含的各操作要么都做憔古,要么都不做
一致性
事務(wù)執(zhí)行的結(jié)果必須是使數(shù)據(jù)庫從一個一致性狀態(tài)變到另一個一致性狀態(tài)遮怜。
隔離性
一個事務(wù)的執(zhí)行不能被其它事務(wù)干擾。即一個事務(wù)內(nèi)部的操作及使用的數(shù)據(jù)對其它并發(fā)事務(wù)是隔離的鸿市,并發(fā)執(zhí)行的各個事務(wù)之間不能互相干擾锯梁。
持續(xù)性
也稱永久性即碗,指一個事務(wù)一旦提交,它對數(shù)據(jù)庫中的數(shù)據(jù)的改變就是永久性的陌凳。接下來的其它操作或故障不應(yīng)該對其執(zhí)行結(jié)果有任何影響剥懒。
spring聲明式事務(wù)
聲明式事務(wù):AOP
編程式事務(wù):需要再代碼中,進行事務(wù)的管理
<?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"
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/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">
<!-- dataresource:使用spring的數(shù)據(jù)源替換mybatis的配置
我們這里屬于spring 提供的jdbc:org.springframework.jdbc.datasource-->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/myweb"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</bean>
<!--sqlSessionFactory-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property>
<!--綁定mybatis的配置文件-->
<property name="configLocation" value="classpath:Mybatis.xml"/>
<property name="mapperLocations" value="classpath:com/mapper/*.xml"/>
</bean>
<!-- SqlSessionTemplate:就是我們使用的sqlsession-->
<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
<!--只能使用構(gòu)造器注入sqlSessionFactory合敦,因為它沒有set方法-->
<constructor-arg index="0" ref="sqlSessionFactory"/>
</bean>
<bean id="userDao" class="com.dao.UserDaoImp">
<property name="sessionTemplate" ref="sqlSession"/>
</bean>
<!--配置聲明式事務(wù)---------------------------------------------------->
<!--配置聲明式事務(wù)-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<constructor-arg ref="dataSource"/>
</bean>
<!--結(jié)合AOP實現(xiàn)事務(wù)的織入-->
<!--配置事務(wù)的通知-->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<!--給哪些方法配置事務(wù)-->
<!--配置事務(wù)的傳播特性-->
<tx:attributes>
<tx:method name="add"/>
<tx:method name="delete"/>
<tx:method name="update"/>
<tx:method name="query"/>
<tx:method name="*"/>
</tx:attributes>
</tx:advice>
<!-- 配置事務(wù)切入-->
<aop:config>
<aop:pointcut id="txPointCut" expression="execution(* com.dao.*.*(..))"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="txPointCut"/>
</aop:config>
</beans>
spring主要注解
@Autowired 自動按類型自動裝配