Maison > Java > javaDidacticiel > Qu'est-ce que le proxy dynamique Java AOP ?

Qu'est-ce que le proxy dynamique Java AOP ?

WBOY
Libérer: 2023-04-24 19:43:05
avant
1511 Les gens l'ont consulté

    1. Concepts IOC et AOP

    IOC : Inversion du contrôle, transfert de la création d'objets et du processus d'appel entre objets à Spring pour la gestion. Le but de l’utilisation de l’IOC est de réduire le couplage.

    AOP : programmation orientée aspect, une technologie qui permet une maintenance unifiée des fonctions du programme grâce à la précompilation et aux proxys dynamiques pendant l'exécution. AOP est la continuation de la POO, un point chaud du développement logiciel, un contenu important dans le framework Spring et un paradigme dérivé de la programmation fonctionnelle. AOP peut être utilisé pour isoler diverses parties de la logique métier, réduisant ainsi le couplage entre les différentes parties de la logique métier, améliorant la réutilisabilité du programme et améliorant l'efficacité du développement. L'implémentation sous-jacente d'AOP est basée sur un proxy dynamique (la méthode d'implémentation consiste à utiliser le proxy dynamique natif du JDK lors du passage à l'interface ; lors du passage à la méthode ordinaire, à utiliser le proxy dynamique cglib).

    2. Pourquoi utiliser un proxy dynamique

    Avec l'expansion continue de l'activité :

    (1) Fonction de journalisation : Si le code du journal est modifié, de nombreuses modifications doivent être apportées.

    (2) Fonction de vérification : si plusieurs lieux doivent être vérifiés, plusieurs modifications doivent être apportées.

    À l'heure actuelle, vous devez utiliser un proxy dynamique pour résoudre le problème. Il existe deux façons d'implémenter un proxy dynamique :

    [1] Proxy dynamique natif du JDK : l'inconvénient est qu'il doit être complété en fonction de l'interface

    [2] Proxy dynamique cglib : il ne peut pas l'utiliser Complété en fonction de l'interface

    2.1 Proxy dynamique natif du JDK

    Quest-ce que le proxy dynamique Java AOP ?

    2.1.1 Classe d'interface 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);
    }
    Copier après la connexion
    2.1.2 Classe d'interface d'implémentation MathServiceImpl
    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;
        }
    }
    Copier après la connexion
    2.1.3 Usine de proxy dynamique ProxyFactory
    public class ProxyFactory {
        //被代理对象
        private Object target;
        public ProxyFactory(Object target) {
            this.target = target;
        }
        //获取代理对象
        public Object getProxy(){
            /**
             * ClassLoader loader, 被代理对象的类加载器
             * Class<?>[] interfaces, 被代理对象实现的接口
             * InvocationHandler h: 当代理对象执行被代理的方法时,会触发该对象中的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 {
                    //可以加上需要的非业务代码
                    //method.getName()获取方法名
                    // Arrays.asList(args)获取输入值
                    System.out.println("this is "+method.getName()+" method begin with"+ Arrays.asList(args));
                    //method:表示代理对象要代理的方法
                    //invoke:回调该函数
                    //args:方法需要的参数
                    Object result = method.invoke(target, args);//代理对象回调该方法
                    return result;
                }
            };
            //先写此处方法,才可找到上述三个方法填写方式
            Object o = Proxy.newProxyInstance(loader, interfaces, h);
            return o;
        }
    }
    Copier après la connexion
    2.1.4 Classe de test
    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);
        }
    }
    Copier après la connexion

    2.2 Usine de proxy dynamique cglib

    Quest-ce que le proxy dynamique Java AOP ?

    2.2.1 Classe 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;
        }
    }
    Copier après la connexion
    2.2.2 Usine de proxy dynamique ProxyFactory

    Remarque :

    (1) Présentation de cglib jar.


    cglib
    cglib
    3.2.5

    (2) Créer une fabrique de classes proxy et implémenter l'interface 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);
            //创建代理对象
            return enhancer.create();
        }
        //当代理对象执行代理方法时触发的方法
        public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
    //        System.out.println("before++++++++++++++++++++");
    //        Object result = method.invoke(target, args);
            //可以加上需要的非业务代码
            //method.getName()获取方法名
            // Arrays.asList(args)获取输入值
            System.out.println("this is "+method.getName()+" method begin with"+ Arrays.asList(args));
            //method:表示代理对象要代理的方法
            //invoke:回调该函数
            //args:方法需要的参数
            Object result = method.invoke(target, args);//代理对象回调该方法
            return result;
        }
    }
    Copier après la connexion
    2.2.3 Classe de test
    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);
        }
    }
    Copier après la connexion

    3.AOP proxy dynamique

    Quest-ce que le proxy dynamique Java AOP ?

    3.1 Ajouter la dépendance correspondante

    <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>
    Copier après la connexion

    3.2 Configurer le fichier 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>
    Copier après la connexion

    3.3 Classe d'interface 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);
    }
    Copier après la connexion

    3.4 MathService Impl implémente la classe d'interface

    @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;
        }
    }
    Copier après la connexion

    3.5 Classe LogAspect

    @Service //若是使用@component也可以
    @Aspect //表示该类为切面类
    public class LogAspect {
        //任意返回类型 aop包下的所有类都有切面日志 使用通配符
        //第一个*:修饰符和返回值类型
        //第二个*:所有类
        //第三个*:所有方法
        @Before("execution(* com.qy151wd.proxy.proxy.aop.*.*(..))")
        public void before(){
            System.out.println("方法执行前的日志");
        }
        @After("execution(* com.qy151wd.proxy.proxy.aop.*.*(..))") //总会被执行,不管有没有异常
        public void after(){
            System.out.println("方法执行后的日志");
        }
        @AfterReturning("execution(* com.qy151wd.proxy.proxy.aop.*.*(..))")//只有碰到return后才会执行
        public void afterReturning(){
            System.out.println("碰到return后执行");
        }
        @AfterThrowing("execution(* com.qy151wd.proxy.proxy.aop.*.*(..))")//异常通知
        public void afterThrowing(){
            System.out.println("出现异常了");
        }
    }
    Copier après la connexion

    3.6 Classe de test

    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);
        }
    }
    Copier après la connexion

    Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

    Étiquettes associées:
    source:yisu.com
    Déclaration de ce site Web
    Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
    Tutoriels populaires
    Plus>
    Derniers téléchargements
    Plus>
    effets Web
    Code source du site Web
    Matériel du site Web
    Modèle frontal