亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Java AOP動態(tài)代理詳細介紹

 更新時間:2022年08月25日 16:00:00   作者:青檸果  
AOP是一種設計思想,是軟件設計領域中的面向切面編程,它是面向對象編程的一種補充和完善。本文將用Java實現(xiàn)AOP代理的三種方式,需要的可以參考一下

1.IOC與AOP概念

IOC:控制反轉,把對象創(chuàng)建和對象之間的調用過程,交給Spring進行管理。使用IOC的目的是為了降低耦合度。

AOP:面向切面編程,通過預編譯方式和運行期間動態(tài)代理實現(xiàn)程序功能的統(tǒng)一維護的一種技術。AOP是OOP的延續(xù),是軟件開發(fā)中的一個熱點,也是Spring框架中的一個重要內容,是函數(shù)式編程的一種衍生范型。利用AOP可以對業(yè)務邏輯的各個部分進行隔離,從而使得業(yè)務邏輯各部分之間的耦合度降低,提高程序的可重用性,同時提高了開發(fā)的效率。AOP的底層實現(xiàn)是基于動態(tài)代理(實現(xiàn)方式是當切入接口時,使用JDK原生動態(tài)代理;當切入普通方法時,使用cglib動態(tài)代理)。

2.為何使用動態(tài)代理

隨著業(yè)務的不斷擴展:

(1)日志功能:如果日志代碼修改,需要修改多處。

(2)校驗功能:如果多處需要校驗,需要修改多處。

這時就需要使用動態(tài)代理來解決問題,動態(tài)代理的實現(xiàn)方式有兩種:

[1]JDK原生動態(tài)代理:缺點是必須基于接口完成

[2]cglib動態(tài)代理:他可以不用基于接口完成

2.1 JDK原生動態(tài)代理

?

2.1.1 MathService接口類

public interface MathService {
    //+
    public Double add(double a,double b);
    //-
    public Double sub(double a,double b);
    //*
    public Double mul(double a,double b);
    ///
    public Double div(double a,double b);
}

2.1.2 MathServiceImpl實現(xiàn)接口類

public class MathServiceImpl implements MathService{
    @Override
    public Double add(double a, double b) {
        Double result=a+b;
        return result;
    }
    @Override
    public Double sub(double a, double b) {
        Double result=a-b;
        return result;
    }
    @Override
    public Double mul(double a, double b) {
        Double result=a*b;
        return result;
    }
    @Override
    public Double div(double a, double b) {
        Double result=a/b;
        return result;
    }
}

2.1.3 ProxyFactory動態(tài)代理工廠

public class ProxyFactory {
    //被代理對象
    private Object target;
    public ProxyFactory(Object target) {
        this.target = target;
    }
    //獲取代理對象
    public Object getProxy(){
        /**
         * ClassLoader loader, 被代理對象的類加載器
         * Class<?>[] interfaces, 被代理對象實現(xiàn)的接口
         * InvocationHandler h: 當代理對象執(zhí)行被代理的方法時,會觸發(fā)該對象中的invoke功能
         */
        ClassLoader loader=target.getClass().getClassLoader();
        Class<?>[] interfaces=target.getClass().getInterfaces();
        InvocationHandler h=new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                //可以加上需要的非業(yè)務代碼
                //method.getName()獲取方法名
                // Arrays.asList(args)獲取輸入值
                System.out.println("this is "+method.getName()+" method begin with"+ Arrays.asList(args));
                //method:表示代理對象要代理的方法
                //invoke:回調該函數(shù)
                //args:方法需要的參數(shù)
                Object result = method.invoke(target, args);//代理對象回調該方法
                return result;
            }
        };
        //先寫此處方法,才可找到上述三個方法填寫方式
        Object o = Proxy.newProxyInstance(loader, interfaces, h);
        return o;
    }
}

2.1.4 測試類

public class Test01 {
    public static void main(String[] args) {
        MathServiceImpl target=new MathServiceImpl();
        ProxyFactory proxyFactory=new ProxyFactory(target);
        MathService proxy = (MathService) proxyFactory.getProxy();
        Double add = proxy.add(15.0, 5.0);
        System.out.println(add);
    }
}

2.2 cglib動態(tài)代理

?

2.2.1 MathServiceImpl類

public class MathServiceImpl{
    public Double add(double a, double b) {
        Double result=a+b;
        return result;
    }
    public Double sub(double a, double b) {
        Double result=a-b;
        return result;
    }
    public Double mul(double a, double b) {
        Double result=a*b;
        return result;
    }
    public Double div(double a, double b) {
        Double result=a/b;
        return result;
    }
}

2.2.2 ProxyFactory動態(tài)代理工廠

注意:

(1)引入cglib的jar包.

<dependency>
  <groupId>cglib</groupId>
  <artifactId>cglib</artifactId>
  <version>3.2.5</version>
</dependency>  

(2)創(chuàng)建一個代理類工廠并實現(xiàn)接口MethodInterceptor

public class ProxyFactory implements MethodInterceptor {
    private Object target;
    public ProxyFactory(Object target) {
        this.target = target;
    }
    //獲取代理對象
    public Object getProxy(){
        Enhancer enhancer=new Enhancer();
        //指定被代理對象的父類
        enhancer.setSuperclass(target.getClass());
        //指定回調類
        enhancer.setCallback(this);
        //創(chuàng)建代理對象
        return enhancer.create();
    }
    //當代理對象執(zhí)行代理方法時觸發(fā)的方法
    public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
//        System.out.println("before++++++++++++++++++++");
//        Object result = method.invoke(target, args);
        //可以加上需要的非業(yè)務代碼
        //method.getName()獲取方法名
        // Arrays.asList(args)獲取輸入值
        System.out.println("this is "+method.getName()+" method begin with"+ Arrays.asList(args));
        //method:表示代理對象要代理的方法
        //invoke:回調該函數(shù)
        //args:方法需要的參數(shù)
        Object result = method.invoke(target, args);//代理對象回調該方法
        return result;
    }
}

2.2.3 測試類

public class Test01 {
    public static void main(String[] args) {
        MathServiceImpl target=new MathServiceImpl();
        ProxyFactory proxyFactory=new ProxyFactory(target);
        MathServiceImpl proxy = (MathServiceImpl) proxyFactory.getProxy();
        Double add = proxy.add(1, 2);
        System.out.println(add);
    }
}

3.AOP動態(tài)代理

3.1 添加對應依賴

<dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>5.2.15.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-aspects</artifactId>
      <version>5.2.15.RELEASE</version>
    </dependency>

3.2 配置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: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
       https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd">
    <!--包掃描-->
    <context:component-scan base-package="com.qy151wd.proxy.proxy.aop"/>
    <!--開啟aop注解-->
    <aop:aspectj-autoproxy/>
</beans>

3.3 MathService接口類

public interface MathService {
    public Double add(double a, double b);
    public Double sub(double a, double b);
    public Double mul(double a, double b);
    public Double div(double a, double b);
}

3.4 MathServiceImpl實現(xiàn)接口類

@Service
public class MathServiceImpl implements MathService {
    @Override
    public Double add(double a, double b) {
        Double result=a+b;
        return result;
    }
    @Override
    public Double sub(double a, double b) {
        Double result=a-b;
        return result;
    }
    @Override
    public Double mul(double a, double b) {
        Double result=a*b;
        return result;
    }
    @Override
    public Double div(double a, double b) {
        Double result=a/b;
        return result;
    }
}

3.5 LogAspect類

@Service //若是使用@component也可以
@Aspect //表示該類為切面類
public class LogAspect {
    //任意返回類型 aop包下的所有類都有切面日志 使用通配符
    //第一個*:修飾符和返回值類型
    //第二個*:所有類
    //第三個*:所有方法
    @Before("execution(* com.qy151wd.proxy.proxy.aop.*.*(..))")
    public void before(){
        System.out.println("方法執(zhí)行前的日志");
    }
    @After("execution(* com.qy151wd.proxy.proxy.aop.*.*(..))") //總會被執(zhí)行,不管有沒有異常
    public void after(){
        System.out.println("方法執(zhí)行后的日志");
    }
    @AfterReturning("execution(* com.qy151wd.proxy.proxy.aop.*.*(..))")//只有碰到return后才會執(zhí)行
    public void afterReturning(){
        System.out.println("碰到return后執(zhí)行");
    }
    @AfterThrowing("execution(* com.qy151wd.proxy.proxy.aop.*.*(..))")//異常通知
    public void afterThrowing(){
        System.out.println("出現(xiàn)異常了");
    }
}

3.6 測試類

public class Test01 {
    public static void main(String[] args) {
        //從spring容器中獲取
        ApplicationContext app=new ClassPathXmlApplicationContext("spring.xml");
        MathService mathService = (MathService) app.getBean("mathServiceImpl");
        Double add = mathService.add(10, 5);
        System.out.println(add);
    }
}

到此這篇關于Java AOP動態(tài)代理詳細介紹的文章就介紹到這了,更多相關Java AOP動態(tài)代理內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • Java樹形結構數(shù)據(jù)生成導出excel文件方法記錄

    Java樹形結構數(shù)據(jù)生成導出excel文件方法記錄

    最近好像得罪了poi,遇到的都是導出word、Excel、pdf的問題,下面這篇文章主要給大家介紹了關于Java樹形結構數(shù)據(jù)生成導出excel文件的相關資料,文中通過示例代碼介紹的非常詳細,需要的朋友可以參考下
    2021-10-10
  • Java8新特性 StreamAPI實例詳解

    Java8新特性 StreamAPI實例詳解

    這篇文章主要為大家介紹了Java8新特性 StreamAPI實例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-11-11
  • Java并發(fā)編程之ConcurrentLinkedQueue解讀

    Java并發(fā)編程之ConcurrentLinkedQueue解讀

    這篇文章主要介紹了Java并發(fā)編程之ConcurrentLinkedQueue解讀,非阻塞的實現(xiàn)方式則可以使用循環(huán)CAS的方式來實現(xiàn),而ConcurrentLinkedQueue就是juc包中自帶的經(jīng)典非堵塞方式實現(xiàn)的工具類,需要的朋友可以參考下
    2023-12-12
  • Android開發(fā)中實現(xiàn)用戶注冊和登陸的代碼實例分享

    Android開發(fā)中實現(xiàn)用戶注冊和登陸的代碼實例分享

    這篇文章主要介紹了Android開發(fā)中實現(xiàn)用戶注冊和登陸的代碼實例分享,只是實現(xiàn)基本功能,界面華麗度就請忽略啦XD 需要的朋友可以參考下
    2015-12-12
  • Mybatis攔截器打印sql問題

    Mybatis攔截器打印sql問題

    這篇文章主要介紹了Mybatis攔截器打印sql問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-03-03
  • Java實現(xiàn)冒泡排序與雙向冒泡排序算法的代碼示例

    Java實現(xiàn)冒泡排序與雙向冒泡排序算法的代碼示例

    這篇文章主要介紹了Java實現(xiàn)冒泡排序與雙向冒泡排序算法的代碼示例,值得一提的是所謂的雙向冒泡排序并不比普通的冒泡排序效率來得高,注意相應的時間復雜度,需要的朋友可以參考下
    2016-04-04
  • springboot后端配置多個數(shù)據(jù)源、Mysql數(shù)據(jù)庫的便捷方法

    springboot后端配置多個數(shù)據(jù)源、Mysql數(shù)據(jù)庫的便捷方法

    實現(xiàn)springboot 后端配置多個數(shù)據(jù)源、Mysql數(shù)據(jù)庫,只需要新建 Mapper、實體類 相應的文件夾,將不同數(shù)據(jù)源的文件保存到對應的文件夾下,添加綁定數(shù)據(jù)庫配置Config,就可以輕松完成
    2021-08-08
  • Java中的方法內聯(lián)介紹

    Java中的方法內聯(lián)介紹

    大家好,本篇文章主要講的是Java中的方法內聯(lián)介紹,感興趣的同學趕快來看一看吧,對你有幫助的話記得收藏一下
    2022-01-01
  • Java通過jersey實現(xiàn)客戶端圖片上傳示例

    Java通過jersey實現(xiàn)客戶端圖片上傳示例

    本篇文章主要介紹了Java通過jersey實現(xiàn)客戶端圖片上傳示例,具有一定的參考價值,感興趣的小伙伴們可以參考一下。
    2017-03-03
  • Java如何獲取Cookie和Session

    Java如何獲取Cookie和Session

    Cookie?和?Session之間主要是通過?SessionId?關聯(lián)起來的,?SessionId是?Cookie?和?Session?之間的橋梁,這篇文章主要介紹了Java獲取Cookie和Session的方法,需要的朋友可以參考下
    2024-01-01

最新評論