Resumo do aprendizado da primavera (oito): introdução ao AOP

1. Introdução ao AOP

1. Introdução básica ao AOP

       Outro ponto importante no Spring é o AOP. O nome completo de AOP é "Programação Orientada a Aspectos", ou seja, programação orientada a aspectos, que isola várias partes da lógica de negócios, para que os desenvolvedores possam se concentrar no negócio principal ao escrever a lógica de negócios, melhorando assim a eficiência do desenvolvimento. Simplificando, significa adicionar novas funções à função principal sem modificar o código-fonte.

       No código de processamento de negócios tradicional, geralmente executamos operações como processamento de transações e registro. No passado, por meio do uso de ideias OOP, a reutilização de código pode ser alcançada em uma combinação ou forma de herança, mas se uma determinada função (como registro) for implementada, o mesmo código será espalhado em cada método neste momento . Quando você deseja fechar ou modificar uma função, você deve modificar todos os métodos relacionados. Isso não apenas aumenta a carga de trabalho dos desenvolvedores, mas também aumenta a taxa de erro do código.

       AOP adota um mecanismo de extração horizontal para substituir o código repetitivo do sistema de herança vertical tradicional . Esse mecanismo de extração horizontal pode encapsular os comportamentos comuns que afetam várias classes em um módulo reutilizável e nomeá-lo "Aspect", que é o que chamamos de aspecto. Aspectos referem-se às lógicas ou responsabilidades que não estão relacionadas ao negócio, mas são comumente chamadas por módulos de negócios. Eles são encapsulados, reduzindo assim o código repetitivo no sistema e reduzindo o acoplamento entre os módulos, o que favorece a operacionalidade e a manutenção subsequentes .

       Por exemplo: em um sistema, o registro é uma função básica e todos os processos de negócios no sistema precisam ser registrados. Se a função de registro for escrita em cada processo de negócios, ela causará redundância de código e aumentará a dificuldade de manutenção. Supondo que a lógica de registro mude neste momento, o código de registro em cada processo de negócios precisa ser modificado, o que obviamente não é aconselhável. Ao contrário, se a função de registro de log for extraída como um módulo independente, quando o processo de negócios exigir, o sistema automaticamente corta a função de registro de log no processo de negócios, o que torna a manutenção muito mais fácil. E este AOP formal pode alcançar. Como mostrado abaixo:

 2. Termos relacionados ao AOP

o termo Descrição

Preocupações transversais

Quais métodos são interceptados e o que fazer após a interceptação, essas questões são chamadas de questões transversais

Aspecto

Geralmente é uma classe na qual os pontos de entrada e notificações podem ser definidos. Um aplicativo pode ter vários aspectos

JointPoint

O ponto claro no processo de execução do programa, ou seja: a localização específica do processo de negócio que precisa ser inserido no aspecto durante o processo de operação, que geralmente é a chamada do método. Como o Spring suporta apenas pontos de conexão de tipos de método, os pontos de conexão no Spring referem-se a métodos que são interceptados.Na verdade, os pontos de conexão também podem ser campos ou construtores.

Conselho

O método de implementação específico do aspecto, o que fazer após interceptar o Joinpoint, ou seja, o conteúdo do aprimoramento do pointcut

Pointcut

É o ponto de conexão com notificação, que é usado para definir quais pontos de conexão a notificação deve cortar. Notificações diferentes geralmente precisam cortar em pontos de conexão diferentes. No programa, isso se reflete principalmente na escrita da expressão do ponto de entrada.

Weave (tecido em)

Indica cut-in, também conhecido como tecelagem. O processo de aplicação de aspectos ao objeto de destino para criar um novo objeto proxy. Este processo pode ocorrer durante a compilação, carregamento de classe e tempo de execução

Introdução

Sob a premissa de não modificar o código, a introdução pode adicionar dinamicamente alguns métodos ou campos à classe em tempo de execução

Proxy

Representa o objeto proxy. Um objeto que é criado dinamicamente após a notificação ser aplicada ao objeto de destino. Pode ser simplesmente entendido que o objeto proxy é o objeto formado pela função lógica de negócios do objeto de destino mais a superfície de corte. O proxy AOP no Spring pode ser um proxy dinâmico para JDK ou um proxy CGLIB.O primeiro é baseado em interfaces e o último é baseado em subclasses. 

Objeto Alvo

O objeto que contém o ponto de conexão é o objeto notificado por um ou mais aspectos. Também conhecido como objeto notificado ou proxy

3. Tipos de notificações em AOP

 

Tipo de notificação Descrição

Aviso prévio (antes)

Faça o processamento de aprimoramento antes que o método de destino seja chamado, @Before só precisa especificar a expressão pointcut

Notificação após retorno (AfterReturning)

Depois que o método de destino é concluído normalmente, ele é aprimorado. Além de especificar a expressão de pointcut, @AfterReturning também pode especificar um nome de parâmetro de valor de retorno retornando, que representa o valor de retorno do método de destino

Notificação depois que uma exceção é lançada (AfterThrowing)

É usado principalmente para tratar exceções não tratadas no programa.Além de especificar a expressão pointcut, @AfterThrowing também pode especificar um nome de parâmetro de valor de retorno de lançamento, que pode ser usado para acessar o objeto de exceção lançado no método de destino.

Após a notificação (após)

O aprimoramento é feito após a conclusão do método de destino, independentemente de quando o método de destino foi concluído com êxito. @After pode especificar uma expressão de ponto de entrada

Around Notification (Around)

Aprimore o processamento antes e depois da conclusão do método de destino, a notificação surround é o tipo mais importante de notificação, como transações, registros, etc. são notificações surround

4. Expressão do ponto de entrada

Indicador de ponto de corte é usado para indicar o propósito da expressão de ponto de corte Atualmente, há apenas um ponto de conexão do método de execução no Spring AOP. O formato da expressão pointcut é o seguinte:

execução ([visibilidade] tipo de retorno [tipo de declaração]. nome do método (parâmetro) [exceção]), onde [] é opcional , outros também suportam o uso de curingas:

      *: corresponde a todos os caracteres
      ..: geralmente usado para combinar vários pacotes, vários parâmetros
      +: indica a classe e suas subclasses

       Os operadores também podem ser usados ​​em expressões de pointcut, como: &&, || ,!

       Aqui está um exemplo para ilustrar o uso de expressões pointcut:

       (1) Escrita de expressão padrão: public void com.yht.controller.UserController.findUser ()

       (2) Todas as gravações de curinga: * .. *. * (..)

       (3) Omitir modificador de acesso: void com.yht.controller.UserController.findUser ()

       (4) O valor de retorno usa curinga *: * com.yht.controller.UserController.findUser ()

       (5) O nome do pacote usa curingas *: * *. *. *. UserController.findUser () // Se houver vários níveis de pacotes, escreva alguns *

       (6) Use curinga * para o nome da classe e o nome do método: * .. *. * ()

       (7) Lista de parâmetros

       Se houver parâmetros, adicione * —— (*) ao () do método

       Com ou sem parâmetros: adicione o () do método ..—— (..)

       (8) Normalmente escrito: * com.yht.controller.UserController. * (..)

       Para outras introduções sobre expressões pointcut, consulte o seguinte blog:

       https://blog.51cto.com/lavasoft/172292

       https://www.cnblogs.com/sjqq/p/10241781.html

Em segundo lugar, o modo proxy no Spring

       Introduzido anteriormente: O proxy AOP no Spring pode ser um proxy dinâmico para JDK ou um proxy CGLIB.O primeiro é baseado em interfaces e o último é baseado em subclasses. Em seguida, implemente esses dois métodos de proxy.

1. Proxy dinâmico JDK

       (1) Crie a interface IOderDao e sua subclasse OrderDaoImpl.

public interface IOrderDao {
    void addOrder();
    void deleteOrder();
    void updateOrder();
    void searchOrder();
}
public class OrderDaoImpl implements IOrderDao {
    @Override
    public void addOrder() {
        System.out.println("添加订单");
    }

    @Override
    public void deleteOrder() {
        System.out.println("删除订单");
    }

    @Override
    public void updateOrder() {
        System.out.println("更新订单");
    }

    @Override
    public void searchOrder() {
        System.out.println("查询订单");
    }
}

       (2) Crie uma classe de aspecto MyAspect

public class MyAspect {
    public void before(){
        System.out.println("方法执行之前");
    }
    public void after(){
        System.out.println("方法执行之后");
    }
}

       (3) Crie uma classe de proxy MyBeanFactory

public class MyBeanFactory {

    public static IOrderDao getBean() {
        // 准备目标类
        final IOrderDao customerDao = new OrderDaoImpl();
        // 创建切面类实例
        final MyAspect myAspect = new MyAspect();
        // 使用代理类,进行增强
        //Proxy 的 newProxyInstance() 方法的第一个参数是当前类的类加载器,第二参数是所创建实例的实现类的接口,第三个参数就是需要增强的方法
        return (IOrderDao) Proxy.newProxyInstance(
                MyBeanFactory.class.getClassLoader(),
                new Class[] { IOrderDao.class }, new InvocationHandler() {
                    public Object invoke(Object proxy, Method method,
                                         Object[] args) throws Throwable {
                        myAspect.before(); // 前增强
                        Object obj = method.invoke(customerDao, args);
                        myAspect.after(); // 后增强
                        return obj;
                    }
                });
    }
}

       (4) Faça um teste.

    @Test
    public void test() {
        // 从工厂获得指定的内容(相当于spring获得,但此内容时代理对象)
        IOrderDao orderDao = MyBeanFactory.getBean();
        // 执行方法
        orderDao.updateOrder();
        System.out.println("=====================");
        orderDao.searchOrder();
    }

       Os resultados são os seguintes:

 

2. proxy dinâmico cglib

       (1) Importe o pacote do jar

    <!-- https://mvnrepository.com/artifact/cglib/cglib-nodep -->
    <dependency>
      <groupId>cglib</groupId>
      <artifactId>cglib-nodep</artifactId>
      <version>3.1</version>
    </dependency>

       (2) Crie a classe de destino Bens

public class Goods{

    public void addGoods() {
        System.out.println("添加货物");
    }

    public void deleteGoods() {
        System.out.println("删除货物");
    }

    public void updateGoods() {
        System.out.println("更新货物");
    }

    public void searchGoods() {
        System.out.println("查询货物");
    }
}

       (3) Crie uma classe de proxy GoodsBeanFactory

public class GoodsBeanFactory {
    public static Goods getBean() {
        // 准备目标类
        final Goods goodsDao = new Goods();
        // 创建切面类实例
        final MyAspect myAspect = new MyAspect();
        // 生成代理类,CGLIB在运行时,生成指定对象的子类,增强
        Enhancer enhancer = new Enhancer();
        // 确定需要增强的类
        enhancer.setSuperclass(goodsDao.getClass());
        // 添加回调函数
        enhancer.setCallback(new MethodInterceptor() {
            // intercept 相当于 jdk invoke,前三个参数与 jdk invoke—致
            @Override
            public Object intercept(Object proxy, Method method, Object[] args,
                                    MethodProxy methodProxy) throws Throwable {
                myAspect.before(); // 前增强
                Object obj = method.invoke(goodsDao, args); // 目标方法执行
                myAspect.after(); // 后增强
                return obj;
            }
        });
        // 创建代理类
        Goods goodsDaoProxy = (Goods) enhancer.create();
        return goodsDaoProxy;
    }
}

       (4) Teste

    @Test
    public void testGoods() {
        // 从工厂获得指定的内容(相当于spring获得,但此内容时代理对象)
        Goods goods = GoodsBeanFactory.getBean();
        // 执行方法
        goods.deleteGoods();
        System.out.println("=====================");
        goods.searchGoods();
    }

       Os resultados são os seguintes:

Acho que você gosta

Origin blog.csdn.net/weixin_47382783/article/details/112802200
Recomendado
Clasificación