Mecanismo de procura de emprego no estágio JAVA e agente dinâmico

1. Introdução

Antes do surgimento da reflexão, quando temos uma classe java, não podemos usar a estrutura privada na classe fora da classe, por exemplo, não podemos chamar o construtor privado, o método privado, etc. Mas, após a reflexão, podemos chamar qualquer estrutura dessa classe, inclusive privada.

import org.junit.Test;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class ReflectionTest {

    @Test
    public void test1(){
        Person p = new Person("tom",23);
        p.show();
    }


    @Test
    public void test2() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
        //1.获取类对象
        Class<Person> personClass = Person.class;
        //2.获取类对象的构造器
        Constructor constructor = personClass.getConstructor(String.class, int.class);
        Object tom = constructor.newInstance("Jerry", 23);
        //3.获取类方法
        Method show = personClass.getDeclaredMethod("show");
        show.invoke(tom);

        //反射的特殊功能,可以调用私有的类结构
        Constructor<Person> cons1 = personClass.getDeclaredConstructor(String.class);
        cons1.setAccessible(true);
        Person wanglei = cons1.newInstance("wanglei");
        wanglei.show();


    }

}

Modo de reflexão e singleton

O padrão singleton privatiza o construtor, e espero que apenas uma instância dessa classe precise ser criada. Nesse momento, a reflexão é resolver o problema de saber se ele pode ser usado.O modo singleton é sugerir sua escrita.Eles não estão em conflito.

Compreensão de java.lang.Class

Classe como fonte de reflexão

(1) Processo de carregamento de classe: Depois que o programa é compilado por javac.exe, um ou mais arquivos de bytecode serão gerados.A classe termina, cada classe java corresponde a um arquivo de bytecode, através da interpretação java.exe para executar um certo O arquivo de bytecode do método mian. Isso é equivalente a carregar esse arquivo de bytecode na memória.Este processo é chamado de carregamento de classe. A classe gravada na memória é chamada de classe de tempo de execução, e essa classe de tempo de execução é usada como uma instância de Class. Em outras palavras, uma instância de Class corresponde a uma classe de tempo de execução.

Quatro maneiras de obter objetos de classe

//方式一:调用运行时类的属性:.class
        Class clazz1 = Person.class;
        System.out.println(clazz1);
        //方式二:通过运行时类的对象,调用getClass()
        Person p1 = new Person();
        Class clazz2 = p1.getClass();
        System.out.println(clazz2);

        //方式三:调用Class的静态方法:forName(String classPath)
        Class clazz3 = Class.forName("com.atguigu.java.Person");
//      clazz3 = Class.forName("java.lang.String");
        System.out.println(clazz3);

        System.out.println(clazz1 == clazz2);
        System.out.println(clazz1 == clazz3);

        //方式四:使用类的加载器:ClassLoader  (了解)
        ClassLoader classLoader = ReflectionTest.class.getClassLoader();
        Class clazz4 = classLoader.loadClass("com.atguigu.java.Person");
        System.out.println(clazz4);

        System.out.println(clazz1 == clazz4);

Três etapas:

Carregar: adicione o arquivo da classe à memória e crie um objeto Class. Esse processo é concluído pelo carregador de classes

Link: Verifique se as informações contidas no fluxo de bytes do arquivo de Classe atendem aos requisitos da máquina virtual atual e não colocam em risco a segurança da própria máquina virtual.

Inicialização: Ao compilar e gerar um arquivo de classe, o compilador gerará dois métodos para adicionar ao arquivo de classe, um é o clinit do método de inicialização de classe e o outro é o método de inicialização da instância init. clinit refere-se ao construtor da classe, o papel principal é desempenhar na fase de inicialização do processo de carregamento da classe, o conteúdo da execução inclui a inicialização estática de variáveis ​​e a execução de blocos estáticos.

 

 

1. Introdução

O padrão de proxy é um dos 23 padrões de design, o que é um conhecimento mais importante.A AOP (Programação Orientada a Aspectos) mais importante na estrutura Spring também é baseada em proxy dinâmico.

Entendimento do agente

Quanto à compreensão dos agentes, deixe-me dar um exemplo: há 20 anos, a forma como queríamos comprar um computador Lenovo era: fomos à fábrica da Lenovo e a fábrica nos vendeu computadores e fornecemos serviços pós-venda.

No desenvolvimento dessas décadas, alguns revendedores apareceram. Eles compraram produtos da fábrica da Lenovo e os venderam para nós. Quando o computador quebrou, também fomos à loja do revendedor para encontrá-lo, e então ele foi à fábrica. A conexão com a fábrica estava realmente quebrada.

Em 2020, se quisermos comprar um laptop, iremos diretamente a grandes distribuidores como Tmall, Suning e JD.com para comprar um computador.Se houver algum problema, devolveremos o produto sem motivo por 7 dias.

Aqui somos o cliente Cliente, esses revendedores também são chamados de agentes e as fábricas da Lenovo são chamadas de agentes. Esse processo é um agente.

Proxy dinâmico

As características do proxy dinâmico: o código de bytes é criado e carregado a qualquer momento e carregado a qualquer momento

O papel dos agentes dinâmicos: aprimore o método sem modificar o código fonte

Classificação de agentes dinâmicos: 2 tipos, um é agente dinâmico com base na interface e o outro é agente dinâmico com base na subclasse

Proxy dinâmico baseado em interface

A implementação da classe Proxy fornecida pelo JDK requer que a classe proxy implemente pelo menos uma interface. O processo de implementação é o seguinte

(1) Primeiro crie a classe Lenovo e implemente uma interface

package com.alibaba200408.动态代理;

public class Lenovo implements ILenovo {
    @Override
    public void sale(Double money) {
        System.out.println("拿到"+money+"元,电脑发货");
    }

    @Override
    public void afterService(Double money) {
        System.out.println("拿到"+money+"元,售后服务开始");

    }
}

O código é muito simples, apenas dois métodos estão envolvidos, um é vender o computador e o outro é reparar o computador.

O código da interface é o seguinte

package com.alibaba200408.动态代理;

public interface ILenovo {

    void sale(Double money);

    void afterService(Double money);
}

(2) Instanciar um objeto proxy dinâmico e chamar métodos por meio do objeto proxy

package com.alibaba200408.动态代理;

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

public class Client {
    public static void main(String[] args) {

        //联想厂家
        ILenovo lenovo = new Lenovo();


        //创建代理对象
        ILenovo proxyInstance = (ILenovo) Proxy.newProxyInstance(lenovo.getClass().getClassLoader(),
                lenovo.getClass().getInterfaces(),
                new InvocationHandler() {
                    /**
                     * invoke方法的作用是调用任何被代理对象的方法都会被这个invoke方法拦截
                     *  proxy:表示当前代理对象的引用
                     *  method:表示当前正在执行的方法
                     *  args:表示当前执行的方法的参数
                     *
                     *  返回值就是当前方法的返回值
                     */

                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        //提供增强的代码
                        Double money = (Double) args[0];
                        if ("sale".equals(method.getName())){
                            method.invoke(lenovo, money * 0.8);
                        }else {
                            method.invoke(lenovo,args);
                        }

                        return null;
                    }
                });

        proxyInstance.afterService(10000.0);

    }
}

Agente dinâmico baseado na subclasse

Essa implementação requer que a classe proxy não possa ser final, porque a classe final modificada não pode ter subclasses e, em segundo lugar, esse método requer um cglib de terceiros. Não vou repeti-los aqui.

Publicado 111 artigos originais · Gosto 60 · 70.000 + visualizações

Acho que você gosta

Origin blog.csdn.net/Haidaiya/article/details/105512739
Recomendado
Clasificación