最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Spring框架學習之AOP詳解

 更新時間:2021年05月07日 09:00:29   作者:不善言談者  
這篇文章主要介紹了Spring框架學習之AOP詳解,文中有非常詳細的代碼示例,對正在學習Spring框架的小伙伴們有一定的幫助,需要的朋友可以參考下

一、概念

1.面向切面編程(方面),利用 AOP 可以對業(yè)務邏輯的各個部分進行隔離,從而使得業(yè)務邏輯各部分之間的耦合度降低,提高程序的可重用性,同時提高了開發(fā)的效率。

2.通俗描述:不通過修改源代碼方式,在主干功能里面添加新功能

二、底層原理:動態(tài)代理

有兩種情況動態(tài)代理

2.1 有接口, JDK 動態(tài)代理

1.被代理的對象

public class UserDaoImpl implements UserDao {

    @Override
    public int add(int a, int b) {
        System.out.println("add執(zhí)行");
        return a + b;
    }

    @Override
    public String update(String id) {
        System.out.println("update執(zhí)行");
        return id;
    }

}

2.代理

package cn.zj.proxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Arrays;

import cn.zj.dao.UserDao;
import cn.zj.dao.impl.UserDaoImpl;

public class JDKProxy {

    public static void main(String[] args) {
        // 創(chuàng)建接口實現(xiàn)類代理對象
        Class[] interfaces = { UserDao.class };
        UserDaoImpl userDao = new UserDaoImpl();
        UserDao dao = (UserDao) Proxy.newProxyInstance(JDKProxy.class.getClassLoader(), interfaces,
                new UserDaoProxy(userDao));
        
        int result = dao.add(1, 2);
        System. out .println( "result:"+result);
    }
}

//創(chuàng)建代理對象代碼
class UserDaoProxy implements InvocationHandler {

    private Object target;// 目標類

    public UserDaoProxy(Object target) {
        this.target = target;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        // 方法執(zhí)行之前
        System.out.println("方法執(zhí)行之前.." + method.getName() + ";傳遞的參數(shù):" + Arrays.toString(args));
        // 增強方法
        Object res = method.invoke(target, args);
        // 方法執(zhí)行之后
        System.out.println("方法執(zhí)行之后.." + target);
        return res;
    }

}

3.打印

方法執(zhí)行之前..add;傳遞的參數(shù):[1, 2]
add執(zhí)行
方法執(zhí)行之后..cn.zj.dao.impl.UserDaoImpl@6c629d6e
result:3

2.2 無接口, CGLIB 動態(tài)代理

1.被代理的對象

public class Cat {

    public void eat() {
        System.out.println("貓吃魚");
    }
}

2.代理

public class CglibProxy {

    public static void main(String[] args) {
        Cat c = new CglibProxy().createProxyObject(Cat.class);
        c.eat();
    }

    // JDK代理是對對象做代理,cglib代理是對類做代理
    public Cat createProxyObject(Class clazz) {
        // 1.創(chuàng)建內(nèi)存中的動態(tài)類 Enhance
        // 內(nèi)存中造出一個沒有名稱的動態(tài)類
        Enhancer enhancer = new Enhancer();
        // 2.現(xiàn)在的類最終完成原始類的功能,同時對其進行功能的增強,必須先具有原始類對應的功能————繼承
        enhancer.setSuperclass(clazz);
        // 3.進行功能的增強
        // 設置了方法的調(diào)用攔截
        // 設置具體的回調(diào)操作
        Callback callback = new MethodInterceptor() {
            // proxy:代理對象
            // method:被攔截的方法對象
            // args:調(diào)用參數(shù)
            // methodProxy:
            public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy)
                    throws Throwable {
                // 做增強
                System.out.println("執(zhí)行前");
                // Object obj=method.invoke(proxy, args);//這種執(zhí)行是代理類的方法,而不是目標類的,會造成內(nèi)存溢出
                // 以下的兩種都是執(zhí)行目標類的方法
                // Object obj = methodProxy.invokeSuper(proxy, args);//執(zhí)行目標類的方法
                // Object obj=method.invoke(proxy, args);
                Object res = methodProxy.invokeSuper(proxy, args);
                System.out.println("執(zhí)行后");
                return res;
            }
        };
        enhancer.setCallback(callback);
        // 4.創(chuàng)建內(nèi)存中的全新的類的對象
        Object proxyObj = enhancer.create();
        return (Cat) proxyObj;
    }

}

三、術語

1.連接點(Joinpoint)

類中的任意方法的運行時表示,可以簡單理解為類中的方法,也就是可以被增強的方法

2.切入點(Pointcut)

具有共性功能的方法的運行時表示,可以簡單理解為具有共性功能的方法,也就是實際被增強的方法

注意:切入點對應的是被挖去了共性功能后的方法執(zhí)行時匹配斷言(格式)

3.通知/增強(Advice)

共性功能模塊化,可以簡單理解為將共性功能抽取出來制作成獨立的方法,實際增強的邏輯部分

類型:前置,后置,異常,最終,環(huán)繞

4.切面(Aspect)

切入點與通知的對應關系,可以簡單理解為被抽取的共性功能與共性功能被抽取位置對應的方法之間的關系,把通知應用到切入點的過程

5.目標對象(Target Object)

包含切入點的運行時對象,開發(fā)階段制作的是目標對象對應的類

6.AOP代理(AOP Proxy)

使用AOP的代理機制創(chuàng)建目標對象運行時代理對象,完成原始的功能

注意:原始目標對象已經(jīng)被挖去了共性功能,此時使用目標對象執(zhí)行任務無法完成原始任務,使用AOP代理機制,創(chuàng)建一個代理對象來完成原始目標對象的功能

7.織入(Weaving)

是一個將通知功能加入原始字節(jié)碼的動態(tài)過程,將增強添加對目標類具體連接點上的過程

Spring使用的是運行時織入機制

8.引入(Introduction)

一種特殊的機制,可以為一個類的字節(jié)碼動態(tài)的加入變量或方法

四、操作

4.1 Spring 框架一般都是基于 AspectJ 實現(xiàn) AOP

AspectJ 不是 Spring 組成部分,獨立 AOP 框架,一般把 AspectJ 和 Spirng 框架一起使

用,進行 AOP 操作

4.2 實踐

 1.jar包引入

<dependencies>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>5.3.6</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
            <version>5.3.6</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.3.6</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.springframework/spring-expression -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-expression</artifactId>
            <version>5.3.6</version>
        </dependency>



        <!-- https://mvnrepository.com/artifact/org.springframework/spring-aop -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
            <version>5.3.6</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/commons-logging/commons-logging -->
        <dependency>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
            <version>1.2</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/com.alibaba/druid -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.2.6</version>
        </dependency>

        <!-- @Resource注解需要 -->
        <dependency>
            <groupId>javax.annotation</groupId>
            <artifactId>javax.annotation-api</artifactId>
            <version>1.3.1</version>
        </dependency>


        <!-- https://mvnrepository.com/artifact/org.springframework/spring-aspects -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aspects</artifactId>
            <version>5.3.6</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/net.sourceforge.cglib/com.springsource.net.sf.cglib -->
        <dependency>
            <groupId>net.sourceforge.cglib</groupId>
            <artifactId>com.springsource.net.sf.cglib</artifactId>
            <version>2.2.0</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.aopalliance/com.springsource.org.aopalliance -->
        <dependency>
            <groupId>org.aopalliance</groupId>
            <artifactId>com.springsource.org.aopalliance</artifactId>
            <version>1.0.0</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.aspectj/com.springsource.org.aspectj.weaver -->
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>com.springsource.org.aspectj.weaver</artifactId>
            <version>1.6.8.RELEASE</version>
        </dependency>



    </dependencies>

2.切入點表達式

作用:知道對哪個類里面的哪個方法進行增強

語法結(jié)構: execution([權限修飾符] [返回類型] [類全路徑] 方法名稱 )

舉例 1:對 com.zj.dao.BookDao 類里面的 add 進行增強

execution(* com.zj.dao.BookDao.add(…))

舉例 2:對 com.zj.dao.BookDao 類里面的所有的方法進行增強

execution(* com.zj.dao.BookDao.* (…))

舉例 3:對 com.zj.dao 包里面所有類,類里面所有方法進行增強

execution(* com.zj.dao.. (…))

3.xml方式

1.創(chuàng)建類

package cn.zj.aop.xml;

public class Book {
    public void buy() {
        System.out.println("buy.............");
    }
}

2.增強類

package cn.zj.aop.xml;

public class BookProxy {
    public void before() {
        System.out.println("before.........");
    }
}

3.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:context="http://www.springframework.org/schema/context"
       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/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">
    <!--創(chuàng)建對象-->
    <bean id="book" class="cn.zj.aop.xml.Book"></bean>
    <bean id="bookProxy" class="cn.zj.aop.xml.BookProxy"></bean>

    <!--配置aop增強-->
    <aop:config>
        <!--切入點-->
        <aop:pointcut id="p" expression="execution(* cn.zj.aop.xml.Book.buy(..))"/>
        <!--配置切面-->
        <aop:aspect ref="bookProxy">
            <!--增強作用在具體的方法上-->
            <aop:before method="before" pointcut-ref="p"/>
        </aop:aspect>
    </aop:config>
</beans>

4.注解方式

1.創(chuàng)建類

public class User {
    public void add() {
        System.out.println("add.......");
    }

}

2.創(chuàng)建增強類

package cn.zj.aop.an;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

//增強的類
@Component
@Aspect  //生成代理對象

public class UserProxy {

    //前置通知
    @Before(value = "execution(* cn.zj.aop.an.User.add(..))")
    public void before() {
        System.out.println("before.........");
    }

    //后置通知(返回通知)
    @AfterReturning(value = "execution(* cn.zj.aop.an.User.add(..))")
    public void afterReturning() {
        System.out.println("afterReturning.........");
    }

    //最終通知
    @After(value = "execution(* cn.zj.aop.an.User.add(..))")
    public void after() {
        System.out.println("after.........");
    }

    //異常通知
    @AfterThrowing(value = "execution(* cn.zj.aop.an.User.add(..))")
    public void afterThrowing() {
        System.out.println("afterThrowing.........");
    }

    //環(huán)繞通知
    @Around(value = "execution(* cn.zj.aop.an.User.add(..))")
    public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        System.out.println("環(huán)繞之前.........");

        //被增強的方法執(zhí)行
        proceedingJoinPoint.proceed();

        System.out.println("環(huán)繞之后.........");
    }
}

3.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:context="http://www.springframework.org/schema/context"
       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/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">
    <!-- 開啟注解掃描 -->
    <context:component-scan base-package="cn.zj.aop.an"></context:component-scan>

    <!-- 開啟Aspect生成代理對象-->
    <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
</beans>

4.測試

ApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml");
        User user = context.getBean("user", User.class);
        user.add();

5.相同點抽取

//相同切入點抽取
    @Pointcut(value = "execution(* cn.zj.aop.an.User.add(..))")
    public void pointdemo() {

    }

    //前置通知
    //@Before注解表示作為前置通知
    @Before(value = "pointdemo()")
    public void before() {
        System.out.println("before.........");
    }

6.有多個增強類多同一個方法進行增強,設置增強類優(yōu)先級

在增強類上面添加注解 @Order(數(shù)字類型值),數(shù)字類型值越小優(yōu)先級越高

@Component
@Aspect 
@Order(1)
public class PersonProxy {

     //后置通知(返回通知)
    @Before(value = "execution(* cn.zj.aop.an.User.add(..))")
    public void afterReturning() {
        System.out.println("Person Before.........");
    }
}
//增強的類
@Component
@Aspect  //生成代理對象
@Order(2)
public class UserProxy {

到此這篇關于Spring框架學習之AOP詳解的文章就介紹到這了,更多相關Spring框架AOP內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • java N皇后實現(xiàn)問題解析

    java N皇后實現(xiàn)問題解析

    將 n 個皇后擺放在一個 n x n 的棋盤上,使得每一個皇后都無法攻擊到其他皇后,N皇后問題是一個典型的約束求解問題,利用遞歸機制,可以很快的得到結(jié)果,本文將詳細介紹,需要了解的朋友可以參考下
    2012-11-11
  • java validation 后臺參數(shù)驗證的使用詳解

    java validation 后臺參數(shù)驗證的使用詳解

    本篇文章主要介紹了java validation 后臺參數(shù)驗證的使用詳解,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-10-10
  • SpringBoot視圖解析實現(xiàn)原理深入分析

    SpringBoot視圖解析實現(xiàn)原理深入分析

    視圖解析其實就是SpringBoot某一個controller的方法執(zhí)行完成之后,它是跳轉(zhuǎn)到那個頁面。由于我們springboot項目默認打包為jar包,是形成壓縮包的形式,而jsp又不支持壓縮,所以我們SpringBoot不知JSP的,需要引入第三方模板引擎才可以處理
    2022-10-10
  • Spring實戰(zhàn)之容器中的工程Bean用法示例

    Spring實戰(zhàn)之容器中的工程Bean用法示例

    這篇文章主要介紹了Spring實戰(zhàn)之容器中的工程Bean用法,結(jié)合實例形式分析了Sring框架容器中的工程Bean相關配置、使用操作技巧,需要的朋友可以參考下
    2019-11-11
  • SpringBoot實現(xiàn)的Mongodb管理工具使用解析

    SpringBoot實現(xiàn)的Mongodb管理工具使用解析

    這篇文章主要介紹了SpringBoot實現(xiàn)的Mongodb管理工具使用解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2019-09-09
  • 關于在Java中使用預定義類

    關于在Java中使用預定義類

    這篇文章主要介紹了關于在Java中使用預定義類,預定義類就是Java類庫(或第三方庫)中已經(jīng)定義好的類,例如,Math 類和 Date 類,需要的朋友可以參考下
    2023-05-05
  • SpringBoot中讀取配置的七種方法總結(jié)

    SpringBoot中讀取配置的七種方法總結(jié)

    在Spring Boot應用中,讀取配置是一項基礎且重要的任務,Spring Boot提供了多種靈活的方式來讀取配置,以滿足不同場景下的需求,本文將詳細介紹Spring Boot中讀取配置的幾種常用方法,需要的朋友可以參考下
    2024-08-08
  • SpringBoot Starter機制及整合tomcat的實現(xiàn)詳解

    SpringBoot Starter機制及整合tomcat的實現(xiàn)詳解

    這篇文章主要介紹了SpringBoot Starter機制及整合tomcat的實現(xiàn),我們知道SpringBoot自己在“后臺”幫我們配置了很多原本需要我們手動去的東西,至于這個“后臺”是啥,就是Starter機制
    2022-09-09
  • 什么是Spring Boot

    什么是Spring Boot

    Spring是一個非常受歡迎的Java框架,它用于構建web和企業(yè)應用。本文介紹將各種Spring的配置方式,幫助您了解配置Spring應用的復雜性
    2017-08-08
  • JMagick實現(xiàn)基本圖像處理的類實例

    JMagick實現(xiàn)基本圖像處理的類實例

    這篇文章主要介紹了JMagick實現(xiàn)基本圖像處理的類,實例分析了java圖像處理的相關技巧,需要的朋友可以參考下
    2015-06-06

最新評論

盱眙县| 河源市| 喀喇| 马关县| 彝良县| 高阳县| 同仁县| 鲜城| 日土县| 六枝特区| 宣城市| 拉萨市| 和平县| 鄂伦春自治旗| 休宁县| 泗水县| 乌兰浩特市| 东平县| 南安市| 瑞昌市| 新津县| 黔南| 五华县| 云阳县| 重庆市| 河东区| 龙州县| 宣武区| 嘉祥县| 大英县| 西峡县| 辽宁省| 康马县| 林西县| 青铜峡市| 桃园市| 电白县| 绥宁县| 桦甸市| 武川县| 句容市|