Rumah  >  Artikel  >  Java  >  Apakah proksi dinamik Java AOP?

Apakah proksi dinamik Java AOP?

WBOY
WBOYke hadapan
2023-04-24 19:43:051421semak imbas

    1. Konsep IOC dan AOP

    IOC: Penyongsangan kawalan, yang memisahkan penciptaan objek dan proses panggilan antara objek. Biarkan Spring menguruskannya. Tujuan penggunaan IOC adalah untuk mengurangkan gandingan.

    AOP: Pengaturcaraan berorientasikan aspek, teknologi yang mencapai penyelenggaraan bersepadu fungsi program melalui pra-penyusunan dan proksi dinamik semasa masa jalan. AOP ialah kesinambungan OOP, tempat hangat dalam pembangunan perisian, kandungan penting dalam rangka kerja Spring, dan paradigma terbitan pengaturcaraan berfungsi. AOP boleh digunakan untuk mengasingkan pelbagai bahagian logik perniagaan, dengan itu mengurangkan gandingan antara pelbagai bahagian logik perniagaan, meningkatkan kebolehgunaan semula program, dan meningkatkan kecekapan pembangunan. Pelaksanaan asas AOP adalah berdasarkan proksi dinamik (kaedah pelaksanaan adalah menggunakan proksi dinamik asli JDK apabila bertukar kepada antara muka; apabila beralih kepada kaedah biasa, gunakan proksi dinamik cglib).

    2. Mengapa menggunakan proksi dinamik

    Dengan pengembangan perniagaan yang berterusan:

    (1) Fungsi pengelogan: Jika kod log diubah, banyak pengubahsuaian perlu dibuat .

    (2) Fungsi pengesahan: Jika berbilang tempat perlu disahkan, berbilang perubahan perlu dibuat.

    Pada masa ini, anda perlu menggunakan proksi dinamik untuk menyelesaikan masalah Terdapat dua cara untuk melaksanakan proksi dinamik:

    [1] Proksi dinamik asli JDK: Kelemahannya ialah ia mesti. dilengkapkan berdasarkan antara muka

    [2]proksi dinamik cglib: Ia boleh dilengkapkan tanpa berasaskan antara muka

    2.1 proksi dinamik asli JDK

    Apakah proksi dinamik Java AOP?

    2.1.1 Kelas antara muka 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 Kelas antara muka pelaksanaan 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;
        }
    }
    2.1.3 Kilang proksi dinamik 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;
        }
    }
    2.1.4 Kelas ujian
    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 proksi dinamik

    Apakah proksi dinamik Java AOP?

    2.2.1 MathServiceImpl kelas
    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 Kilang proksi dinamik ProxyFactory

    Nota:

    (1) Import pakej balang cglib.



    cglib
    cglib artifactId>
    3.2.5

    sebuah kilang kelas proksi dan melaksanakan antara muka 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;
        }
    }
    2.2.3 Kelas ujian
    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 proksi dinamik

    Apakah proksi dinamik Java AOP?

    3.1 Tambah kebergantungan yang sepadan

    <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 Konfigurasikan fail 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 Kelas antara muka 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 Kelas pelaksanaan Impl MathService

    @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;
        }
    }

    Kelas 3.5 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("出现异常了");
        }
    }

    Kelas Ujian 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);
        }
    }

    Atas ialah kandungan terperinci Apakah proksi dinamik Java AOP?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

    Kenyataan:
    Artikel ini dikembalikan pada:yisu.com. Jika ada pelanggaran, sila hubungi admin@php.cn Padam