Spring初步試探

Spring是一個開放源代碼的設計層面框架,可以解決業務邏輯層和其他各層的鬆耦合問題,是一個分層的JavaEE輕量級的開發框架
可能這樣說太官方了,用我自己理解的話來說:Spring可以讓你的類和類之間的調用更加靈活,以及當老闆想改變業務時,你會很方便的去添加新的方法,貫穿於整個Web項目,使用靈活。
單獨說說其優點吧:
1.方便解耦,簡化開發
2. AOP編程的支持
3. 聲明式事務的支持
4. 方便程序的測試
5. 方便集成各種優秀框架
6. 降低Java EE API的使用難度
7. Java 源碼是經典學習範例

這些可能對於初學者不太容易懂,這是很正常的,這裏只是提一下,等把Spring學完了,便可以領會到Spring的魅力之處。
對了這裏提醒一下:Spring的源碼設計精妙、結構清晰、匠心獨運,處處體現着大師對Java設計模式靈活運用以及對Java技術的高深造詣。Spring框架源碼無疑是Java技術的最佳實踐範例。
想要小編推薦Spring書籍的讀者可以留言噢
下面就可以開始Spring的介紹了,Spring主要分爲三大板塊:IOC DI AOP

1.IOC

IOC是什麼?英文名爲 Inversion of Control,中文意思爲控制翻轉,將對象的創建權交給Spring。
講到這可能有些枯燥,害,,,,我先說他是啥作用吧,他的作用就是你用它以後你想用一個類的方法都不需要new去創建他的對象了,沒錯你沒有聽錯,就是這麼強。
IOC使用:

  1. 添加jar包,這些jar大部分都是Spring框架裏面的,還有些是數據庫驅動jar包,單元測試jar包,druid連接池jar包,相信這些你應該都瞭解,不瞭解或者忘了的可以看看我之前寫的JDBC文章JDBC詳解
    在這裏插入圖片描述

2. 添加配置文件,現在一般框架都離不開配置文件,,,

這是一個Spring的xml配置文件,命名的話最好爲applicationContext.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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    <bean id="userDao" class="com.eh.demo1.UserDaoMysqlImpl" init-method="initUserDao" destroy-method="deleteUserDao">

</beans>

可以看到這裏面有beans這個標籤,沒錯在你學習Spring的過程中你會把bean標籤看吐的,還有好多配置都要寫到該配置文件中
3. 將對象控制權交給Spring
先把我創建的類放出來
在這裏插入圖片描述
這裏我把UserDaoMyImpl實現類以及USerDao接口代碼也搬出來(UserDaoOracleImpl實現類不用管):

USerDao接口

package com.eh.demo1;

public interface UserDao {
    public void save();

    public void delete();
}

UserDaoMysqlImpl實現類

package com.eh.demo1;

public class UserDaoMysqlImpl implements UserDao {
    public String name;
    @Override
    public void save() {
        System.out.println("mysql  save");
    }
    @Override
    public void delete() {
        System.out.println("mysql  delete");
    }
    
    public void initUserDao() {
        System.out.println("UserDao--init");
    }
    public void deleteUserDao() {
        System.out.println("UserDao--destory");
    }
}

首先來看一下傳統模式:
當UserTest類想調用UserDaoMysqlImpl類時,需要new USerDaoMysqlImpl()
但是當你學了Spring後就不需要這樣
可以這樣:
配置文件添加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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
       <!-- class 需要交給Spring管理的類    id 給這個類起個別名,id唯一 -->
    <bean id="userDao" class="com.eh.demo1.UserDaoMysqlImpl"></bean>
</beans>

然後再通過UserTest類調用

public class UserTest {
    @Test
    public void test() {
        //1.加載配置文件
        ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        //2.根據id獲取對象  面向接口編程時 使用父類類型接收
        UserDao userDao = (UserDao) applicationContext.getBean("userDao");
        //調用UserDaoMysqlImpl中的方法
        userDao.save();
        userDao.delete();
    }
   }

沒錯這樣一次通過Spring實現控制反轉的過程就完成了。
這裏我再把控制反轉說一下吧,我怕有的讀者懶得往上翻了,控制反轉,英文名簡稱爲IOC,可以把你要new的對象交給Spring去管理(通過配置文件實現),然後去根據當時配置的id獲取交給Spring管理的對象,獲取到之後就可以直接調用其裏面的方法了。每個類交給Spring管理時,都要創建一個自己的bean標籤。
這就是IOC最基本的操作。其實你也可以不用添加配置文件,可以使用註解的方式,就像Servlet的學習一樣,這個先放後面和DI一起講解

2. DI

沒錯你又接觸到一個沒有聽過的英文簡寫,說的高大上,其實很簡單,DI中文名屬性依賴注入。就是當你將某一個類交給Spring管理時,可以向該類中的變量注入一些屬性,當然這些屬性都是你這個類中創建好的。
使用方式是建立在IOC的基礎之上,如果你IOC搞的不太懂,那麼這個你會不容易理解。
1.將類交給Spring管理(這個步驟和IOC中的一樣)

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       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">
       <!-- class 需要交給Spring管理的類    id 給這個類起個別名,id唯一 -->
    <bean id="userDao" class="com.eh.demo1.UserDaoMysqlImpl"></bean>
</beans>

2. 給將被注入屬性的類添加set方法
如果不給想注入的屬性添加set方法,就不能實現注入,當然也可以通過構造器方法注入,以及註解注入,這裏小編怕都寫出來讀者一會就混淆了,所以就介紹比較簡單常用的set方法實現注入。
給實現類的屬性添加set方法:

package com.eh.demo1;

public class UserDaoMysqlImpl implements UserDao {
    public String name;
    public void setName(String name) {
        this.name = name;
    }
    @Override
    public void save() {
        System.out.println("mysql  save");
    }
    @Override
    public void delete() {
        System.out.println("mysql  delete");
    }
    public void initUserDao() {
        System.out.println("UserDao--init");
    }
    public void deleteUserDao() {
        System.out.println("UserDao--destory");
    }
}

3.注入屬性
你想注入哪個類的屬性,就在哪個類的bean文件裏面寫
我就直接在1步驟的基礎上寫

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       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">
       <!-- class 需要交給Spring管理的類    id 給這個類起個別名,id唯一 -->
    <bean id="userDao" class="com.eh.demo1.UserDaoMysqlImpl">
		<property name="name" value="小明"/>
	</bean>
</beans>

4.使用單元測試進行測試

import org.springframework.context.support.ClassPathXmlApplicationContext;

public class UserTest {
    @Test
    public void test2() {
//        依賴注入:給Spring管理類當中依賴的屬性,通過配置文件進行賦值的過程
 		//1.加載配置文件
        ClassPathXmlApplicationContext ApplicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        UserDaoMysqlImpl userDao = (UserDaoMysqlImpl)ApplicationContext.getBean("userDao");
        System.out.println(userDao.name);
    }
 }

控制檯打印的結果是 : 小明
上面注入的屬性是基本數據類型的,如果注入的屬性是一個對象的話,那麼會有一點區別
這裏再創建一個將用於注入的對象,Dog類

package com.eh.demo1;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
public class Dog {
    public String name;
    public void setName(String name) {
        this.name = name;
    }
}

用於注入的對象也需要將其交給Spring管理,同時將給其注入屬性name
配置文件

<?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 id="userDao" class="com.eh.demo1.UserDaoMysqlImpl">
		<property name="name" value="小明"/>
		<!-- 注入對象屬性-->
		<property name="dog" ref="dog"/>
	</bean>
	 <bean id="dog" class="com.eh.demo1.Dog">
	 <!-- 給注入基本屬性-->
		<property name="name" value="旺財"/>
	</bean>
</beans>

測試方法:

public class StudentTest {
    @Test
    public void test1() {
          ClassPathXmlApplicationContext ApplicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        UserDaoMysqlImpl userDao = (UserDaoMysqlImpl)ApplicationContext.getBean("userDao");
        System.out.println(userDao.name);
        System.out.println(userDao.dog.name);
    }
}

於是便實現了不通過new 對象便可以使用該類中的方法

這裏Spring 的IOC以及DI最基本介紹就講的差不多了,然後我覺得我可以開始講解下其註解的使用,如果你連配置文件的方式還沒有掌握的話,我建立你把配置文件的方法掌握了再掌握註解的方式。
這裏一起將吧IOC與DI的註解一併講了
1.aop的jar包介紹
在這裏插入圖片描述

在Spring4之後,想要使用註解形式,就必須得引用aop的包
2.配置文件
在配置文件中需要引入一個context約束,關於約束主要有dtd以及xsd兩種形式的約束,這裏就不過多介紹
引入之後就是這樣:

<?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">
</beans>

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">
<context:component-scan base-package="com.eh.demo1"></context:component-scan>
</beans>

base-package標籤屬性填爲需要掃描註解的包
4.添加註解
這些前期工作做好後便可以開始添加註解了
先把我的包目錄放出來
在這裏插入圖片描述
關於註解整理了半天思路不知道如何以文字的形式講解出來,而且註解的方式原理其實與配置文件的方式一樣,想着不如代碼註釋一起使用:
User類

@Component("user") //將User類交給Spring管理
@Scope("prototype") //多例模式,在默認情況下交給Spring管理的類調用時都是單例模式
public class User {
    @Value("n1")//注入屬性
    public String name;
//    @Autowired          //根據類型注入
//    @Qualifier("dog")   //兩個一起使用時是根據名稱進行注入
    @Resource(name="dog")//相當於上面兩個註解一起使用
    public Dog dog;
    @PostConstruct
    public void init() {
        System.out.println("init");
    }
    @PreDestroy
    public void destory() {
        System.out.println("destory");
    }
}

Dog類

@Component("dog")//將dog交給Spring管理
public class Dog {
    @Value("d1")//向Dog的name屬性注入屬性值
    public String name;
}

UserTest類

package com.eh.demo1;

import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class UserTest {
    @Test
    public void test() {
    //加載配置文件
        ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        User user = (User)applicationContext.getBean("user");
        System.out.println(user.name);
        System.out.println(user.dog.name);
        applicationContext.close();
    }
}

注:向類注入屬性時,必須要在將該類交給Spring管理的基礎上
上述便差不多將IOC控制轉換以及DI依賴注入的配置文件方式和註解方式簡單的介紹完了,可以有人會覺得註解的方式相對比較簡單,但是不利於維護,結構沒有配置文件清晰,所以在正常開發情況下,是XML配置文件與註解結合使用開發,XML用於管理Bean,註解用於屬性注入。這種方式就不需要在配置文件中添加掃描器(掃描器的作用是爲了掃描類上的註解),但是需要添加另一種配置文件<context:annotation-config/>
該配置文件用於激活那些已經在spring容器裏註冊過的bean上面的註解,也就是顯示的向Spring註冊。

3.AOP

AOP爲Aspect Oriented Programming的縮寫
意爲:面向切面編程,
AOP是OOP的延續,是軟件開發中的一個熱點,也是Spring框架中的一個重要內容,是函數式編程的一種衍生範型。利用AOP可以對業務邏輯的各個部分進行隔離,從而使得業務邏輯各部分之間的耦合度降低,提高程序的可重用性,同時提高了開發的效率。
在傳統的開發中,當想向某類中增添方法時,需要縱向繼承,會破壞原有類,但是AOP採取了橫向抽取機制。簡單來說,開發時,整個過程就像一條線,當你覺得線上的某一點需要添加新的方法(這個點就是一個方法)時,可以使用AOP,就像一個面,去從這個點切下去,至於這個面上寫的內容是什麼,就是你想再添加的方法。
AOP機制中有兩種動態代理:JDK動態代理和cglib動態代理

1.JDK動態代理

創建的類目錄(一個接口,一個接口實現類,一個JDK動態代理類,一個測試文件)
在這裏插入圖片描述

GoodsDao接口

package com.eh.demo1;

public interface GoodsDao {
    public void save();

    public void update();
}

GoodsDaoImpl實現類

package com.eh.demo1;

public class GoodsDaoImpl implements GoodsDao {
    @Override
    public void save() {
        System.out.println("保存操作");
    }
    @Override
    public void update() {
        System.out.println("更新操作");
    }
}

GoodsJDKProxy代理類

package com.eh.demo1;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class GoodsJDKProxy {
    public GoodsDao createProxy(GoodsDao goodsDao) {
        //增強
        GoodsDao goodsDaoProxy = (GoodsDao) Proxy.newProxyInstance(goodsDao.getClass().getClassLoader(), goodsDao.getClass().getInterfaces(), new InvocationHandler() {
            @Override//當調用GoodsDao對象的時候,所有的方法都會來到這裏
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            //增強GoodsDao類中的save方法
                if ("save".equals(method.getName())) {
                    //save方法執行前的操作
                    System.out.println("權限校驗");
                    GoodsDao goodsDao1 = (GoodsDao) method.invoke(goodsDao, args);
                    //save方法執行後的操作
                    System.out.println("日誌添加");
                    return goodsDao1;
                }
                return method.invoke(goodsDao, args);
            }
        });
        return goodsDaoProxy;
    }
}

GoodsDaoTest測試類

package com.eh.demo1;

import org.junit.Test;

public class GoodsDaoTest {
    @Test
    public void test1() {
        GoodsDaoImpl goodsDao = new GoodsDaoImpl();
        
        GoodsJDKProxy goodsJDKProxy = new GoodsJDKProxy();
        //獲取代理對象
        GoodsDao proxy = goodsJDKProxy.createProxy(goodsDao);
        proxy.save();
    }
}

注:只有當使用切面編程的類是某個接口的實現類時,纔會使用JDK動態代理

2.cglib動態代理

創建的類的目錄:
在這裏插入圖片描述
User類

public class UserDao {
    public void save() {
        System.out.println("保存");
    }
    public void update() {
        System.out.println("更新");
    }
}

UserDaoCglibProxy代理類

import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

public class UserDaoCglibProxy implements MethodInterceptor {
    public UserDao createCglibProxy(UserDao userDao) {
        //創建核心類
        Enhancer enhancer = new Enhancer();
        //設置父類  繼承方式  創建一個子類 自動繼承UserDao
        enhancer.setSuperclass(userDao.getClass());
        //設置回調
        enhancer.setCallback(this);
        //創建代理對象
        UserDao obj = (UserDao) enhancer.create();
        return obj;
    }
    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
    //對save方法進行增強
        if ("save".equals(method.getName())) {
            System.out.println("權限操作");
            return methodProxy.invokeSuper(o,objects);
        }
        return methodProxy.invokeSuper(o,objects);
    }
}

UserDaoTest測試類

import org.junit.Test;

public class UserDaoTest {
    @Test
    public void test() {
        UserDao userDao = new UserDao();
        UserDaoCglibProxy userDaoCglibProxy = new UserDaoCglibProxy();
        UserDao cglibProxy = userDaoCglibProxy.createCglibProxy(userDao);
        cglibProxy.save();
        cglibProxy.update();
    }
}

注:當使用切面編程的類不是某接口的實現類時會調用cglib動態代理

AOP思想是最早由AOP聯盟組織提出的,Spring是使用這種思想最好的框架,其實Spring的AOP有自己的實現方式,但是這種方式非常繁瑣,AspectJ是一個AOP的框架,於是Spring放棄了自己傳統方式,引入AspectJ作爲自身AOP的開發
這裏先介紹下AOP相關術語:
Joinpoint:連接點,可以被增強的方法,也就是能夠被增強的方法可以稱爲連接點

Pointcut:切入點,真正被攔截的方法,也就是真正被增強的方法。

Advice:通知,增添的內容,通常是被封裝成一個方法,這個方法也被稱之爲通知。

Introduction:引介,內層面的增加,給原有類添加一些新的屬性方法。

Target:被增加的對象。

Weaving:織入,將通知(也就是增添的方法)應用到目標對象的過程。

Proxy:代理對象。

Aspect:切面,多個通知和多個切入點的集合。

下面就可以開始Spring中AOP的使用了(害,,,太難了,做了這麼多鋪墊):

1.導入Spring開發的基本jar包(前面已經給出)以及aop開發的相關jar包
下圖爲aop開發的相關jar包
在這裏插入圖片描述
2.配置文件中引入AOP約束

<?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">
        
</beans>

3.引入Spring測試
由於在前面大家可以看到,每次測試時都要獲取工廠,代碼又多,寫着挺麻煩的,所有這裏就引進了Spring測試,先導入jar包
在這裏插入圖片描述
之後就不需要通過 new ClassPathXmlApplicationContext對象來加載配置文件以及獲取工廠了,也不需要在Spring配置文件中添加註解掃描包(很方便),當然你也可以忽略這一步,依舊用以前的方式
只需要在測試類上添加這兩行代碼:
在這裏插入圖片描述
4.編寫切面類

public class Myaspect {
    public void check() {
        System.out.println("權限校驗");
    }
    public void log(Object res) {
        System.out.println("日誌記錄");
        System.out.println(res);
    }
    public Object arround(ProceedingJoinPoint joinPoint) throws Throwable {
        System.out.println("環繞前通知");
        Object proceed = joinPoint.proceed();
        System.out.println("環繞前通知");
        return proceed;
    }
    //異常拋出通知
    public void exceptionM(Throwable ex) {
        System.out.println("有異常" + ex.getMessage());
    }
    public void after() {
        System.out.println("結果通知");
    }
}

5.編寫接口以及對應實現類

GoodsDao接口

public interface GoodDao {
    public void save();

    public String update();

    public void delete();

    public void find();
}

GoodsDaoImpl實現類

public class GoodDaoImpl implements GoodDao {
    @Override
    public void save() {
        System.out.println("保存操作");
    }

    @Override
    public String update() {
        System.out.println("更新操作");
        return "update--res";
    }

    @Override
    public void delete() {
        System.out.println("刪除");
    }

    @Override
    public void find() {
        System.out.println("查找");
    }
}

6.Spring配置文件中配置AOP

<?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"> <!--添加aop的xsd約束 -->

    <bean id="goodDao" class="com.eh.demo3.GoodDaoImpl"></bean>
    <bean id="myaspect" class="com.eh.demo3.Myaspect"></bean>

<!--    配置AOP-->
    <aop:config>
<!--        配置切點:給那個方法增強  expression參數:切入點表達式 -->
        <aop:pointcut id="savepoint1" expression="execution(* com.eh.demo3.GoodDaoImpl.save(..))"/>
        <aop:pointcut id="savepoint2" expression="execution(* com.eh.demo3.GoodDaoImpl.update(..))"/>
        <aop:pointcut id="savepoint3" expression="execution(* com.eh.demo3.GoodDaoImpl.update(..))"/>
        <aop:pointcut id="savepoint4" expression="execution(* com.eh.demo3.GoodDaoImpl.find(..))"/>
		<!--配置切面-->
        <aop:aspect ref="myaspect">
        
        <!--前置通知  目標方法執行之前  進行操作-->
            <aop:before method="check" pointcut-ref="savepoint1"/>
            
		<!--後置通知  目標方法執行之後  進行操作-->
            <aop:after-returning method="log" pointcut-ref="savepoint2" returning="res"/>
            
		<!--環繞通知 目標方法執行之前和之後執行的操作 -->
            <aop:around method="arround" pointcut-ref="savepoint3"/>
            
		<!-- 異常拋出通知 程序出現異常時進行的操作-->
            <aop:after-throwing method="exceptionM" pointcut-ref="savepoint4" throwing="ex"/>
            
		<!--最終通知  無論代碼是否有異常,都會執行-->
            <aop:after method="after" pointcut-ref="savepoint4"/>
        </aop:aspect>
    </aop:config>
</beans>

expression參數基於execution函數完成

public com.eh.demo2.GoodsDaoImpl.save(..)  
* com.eh.demo2.GoodsDaoImpl.save(..)   //類的修飾符爲任意參數
* com.eh.demo2.GoodsDaoImpl+.save(..)   // 當前類和子類
* com.demo..*.*(..)  		//	com.demo包以及子包下面所有類的所有方法

AOP註解方式ApsectJ開發

配置文件

<?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"> <!--添加aop的xsd約束 -->
<!--開啓aop註解-->
    <aop:aspectj-autoproxy/>
    <!-- 將實現類交給Spring管理 -->
    <bean id="goodsDao" class="com.eh.demo1.GoodsDaoImpl"></bean>
    <!-- 將切面交給Spring管理 -->
    <bean id="goodsAspect" class="com.eh.demo1.GoodsDaoAspect"></bean>
</beans>

編寫切面類

//切面註解
@Aspect
public class GoodsDaoAspect {
//前置通知
    @Before(value = "GoodsDaoAspect.pointcut1()")
    public void log() {
        System.out.println("前置通知");
    }
    @Pointcut(value = "execution(* com.eh.demo1.GoodsDaoImpl.save(..))")
    private void pointcut1(){}


    @AfterReturning(value="execution(* com.eh.demo1.GoodsDaoImpl.update(..))", returning = "res")
    public void afterreturning(Object res) {
        System.out.println("後置通知");
        System.out.println(res);
    }

    @Around(value="execution(* com.eh.demo1.GoodsDaoImpl.delete(..))")
    public Object arround(ProceedingJoinPoint joinPoint) throws Throwable {
        System.out.println("delete之前");
        Object proceed = joinPoint.proceed();
        System.out.println("delete之後");
        return proceed;
    }

    @After(value="execution(* com.eh.demo1.GoodsDaoImpl.find(..)))")
    public void after() {
        System.out.println("最終執行");
    }
}

GoodsSDaoImpl實現類

package com.eh.demo1;

public class GoodsDaoImpl implements GoodsDao {
    @Override
    public void save() {
        System.out.println("save");
    }

    @Override
    public String update() {
        System.out.println("update");
        return "update-res";
    }

    @Override
    public void delete() {
        System.out.println("delete");
    }

    @Override
    public void find() {
        System.out.println("find");
    }
}

這裏AOP切面編程就大概介紹到這裏,其實這個裏面的知識點還是有很多的,這裏就是對IOC,DI,AOP進行一個初步的介紹。如果需要jar或者Spring框架源碼的可私信

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章