SSM框架之Spring框架

一臀稚、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)如下圖所示:

image.png

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的作用域或者說范圍主要有五種。

image.png

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

主要是切面定義

image.png
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">
                &lt;!&ndash;配置數(shù)據(jù)庫的4個基本信息&ndash;&gt;
                <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 自動按類型自動裝配

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末初橘,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子充岛,更是在濱河造成了極大的恐慌保檐,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,378評論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件崔梗,死亡現(xiàn)場離奇詭異夜只,居然都是意外死亡,警方通過查閱死者的電腦和手機蒜魄,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,970評論 3 399
  • 文/潘曉璐 我一進店門扔亥,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人谈为,你說我怎么就攤上這事旅挤。” “怎么了伞鲫?”我有些...
    開封第一講書人閱讀 168,983評論 0 362
  • 文/不壞的土叔 我叫張陵粘茄,是天一觀的道長。 經(jīng)常有香客問我榔昔,道長驹闰,這世上最難降的妖魔是什么瘪菌? 我笑而不...
    開封第一講書人閱讀 59,938評論 1 299
  • 正文 為了忘掉前任撒会,我火速辦了婚禮,結(jié)果婚禮上师妙,老公的妹妹穿的比我還像新娘诵肛。我一直安慰自己,他們只是感情好默穴,可當(dāng)我...
    茶點故事閱讀 68,955評論 6 398
  • 文/花漫 我一把揭開白布怔檩。 她就那樣靜靜地躺著,像睡著了一般蓄诽。 火紅的嫁衣襯著肌膚如雪薛训。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,549評論 1 312
  • 那天仑氛,我揣著相機與錄音乙埃,去河邊找鬼闸英。 笑死,一個胖子當(dāng)著我的面吹牛介袜,可吹牛的內(nèi)容都是我干的甫何。 我是一名探鬼主播,決...
    沈念sama閱讀 41,063評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼遇伞,長吁一口氣:“原來是場噩夢啊……” “哼辙喂!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起鸠珠,我...
    開封第一講書人閱讀 39,991評論 0 277
  • 序言:老撾萬榮一對情侶失蹤巍耗,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后跳芳,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體芍锦,經(jīng)...
    沈念sama閱讀 46,522評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,604評論 3 342
  • 正文 我和宋清朗相戀三年飞盆,在試婚紗的時候發(fā)現(xiàn)自己被綠了娄琉。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,742評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡吓歇,死狀恐怖孽水,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情城看,我是刑警寧澤女气,帶...
    沈念sama閱讀 36,413評論 5 351
  • 正文 年R本政府宣布,位于F島的核電站测柠,受9級特大地震影響炼鞠,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜轰胁,卻給世界環(huán)境...
    茶點故事閱讀 42,094評論 3 335
  • 文/蒙蒙 一谒主、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧赃阀,春花似錦霎肯、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,572評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至驮俗,卻和暖如春懂缕,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背王凑。 一陣腳步聲響...
    開封第一講書人閱讀 33,671評論 1 274
  • 我被黑心中介騙來泰國打工搪柑, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留吮蛹,地道東北人。 一個月前我還...
    沈念sama閱讀 49,159評論 3 378
  • 正文 我出身青樓拌屏,卻偏偏與公主長得像潮针,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子倚喂,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,747評論 2 361

推薦閱讀更多精彩內(nèi)容