spring (反射+代理+DI+AOP)

spring  https://baijiahao.baidu.com/s?id=1620606848227713760&wfr=spider&for=pc

反射 https://blog.csdn.net/ritterliu/article/details/7764849

1. 反射

反射属于动态编译,就是在编译期并不确定是哪个类被加载了,而是在程序运行的时候才加载,所以我们可以动态的解剖一个类,获取这个类的任意属性和方法。

  1.1获取类对象

      类名.class

      对象.getClass()

      Class.forName("全类名")

2、Spring是什么?

Spring是一个轻量级的IoC和AOP容器框架。是为Java应用程序提供基础性服务的一套框架,目的是用于简化企业应用程序的开发,它使得开发者只需要关心业务需求。常见的配置方式有三种:基于XML的配置、基于注解的配置、基于Java的配置。

主要由以下几个模块组成:

Spring Core:核心类库,提供IOC服务;

Spring Context:提供框架式的Bean访问方式,以及企业级功能(JNDI、定时任务等);

Spring AOP:AOP服务;

Spring DAO:对JDBC的抽象,简化了数据访问异常的处理;

Spring ORM:对现有的ORM框架的支持;

Spring Web:提供了基本的面向Web的综合特性,例如多方文件上传;

Spring MVC:提供面向Web应用的Model-View-Controller实现。

3、Spring 的优点?

(1)spring属于低侵入式设计,代码的污染极低;

(2)spring的DI机制将对象之间的依赖关系交由框架处理,减低组件的耦合性;

(3)Spring提供了AOP技术,支持将一些通用任务,如安全、事务、日志、权限等进行集中式管理,从而提供更好的复用。

(4)spring对于主流的应用框架提供了集成支持。

(5)独立于各种应用服务器

4、什么是DI机制

依赖注入(Dependecy Injection)和控制反转(Inversion of Control)是同一个概念,具体的讲:当某个角色需要另外一个角色协助的时候,在传统的程序设计过程中,

通常由调用者来创建被调用者的实例。但在spring中创建被调用者的工作不再由调用者来完成,因此称为控制反转。创建被调用者的工作由spring来完成,然后注入调用者
因此也称为依赖注入。
spring以动态灵活的方式来管理对象 , 注入的两种方式,设置注入和构造注入。
设置注入的优点:直观,自然
构造注入的优点:可以在构造器中决定依赖关系的顺序。

5. 什么是 Spring AOP?

  或许你可以给面试官举个例子:歌星都有好多助理,歌星最重要的一件事就是唱歌,其他事他不用关注,比如唱歌前可能需要和其他人谈合作,还要布置场地,唱歌后还要收钱等等,这些统统交给他对应的助理去做。

也许哪一天,这个歌星做慈善,免费唱歌了,不收钱了,那么就可以把收钱这个助力给辞退了。这就是 AOP,每个人各司其职,灵活组合,达到一种可配置的、可插拔的程序结构。AOP 的实现原理就是代理模式。

在程序中也是如此,通过代理,可以详细控制访问某个或者某类对象的方法,在调用这个方法前做前置处理,调用这个方法后做后置处理。

https://blog.csdn.net/qq_32317661/article/details/82878679  aop 

https://blog.csdn.net/q982151756/article/details/80513340  aop

6. 谈谈你对代理模式(Spring AOP用的就是这种设计模式)的理解

代理模式的核心作用就是通过代理,控制对对象的访问。它的设计思路是:定义一个抽象角色,让代理角色和真实角色分别去实现它。

真实角色:实现抽象角色,定义真实角色所要实现的业务逻辑,供代理角色调用。它只关注真正的业务逻辑,比如歌星唱歌。

代理角色:实现抽象角色,是真实角色的代理,通过真实角色的业务逻辑方法来实现抽象方法,并在前后可以附加自己的操作,比如谈合同,布置场地,收钱等等。

这就是代理模式的设计思路。代理模式分为静态代理和动态代理。静态代理是我们自己创建一个代理类,而动态代理是程序自动帮我们生成一个代理,我们就不用管了。下面我详细介绍一下这两种代理模式。

动态代理和静态代理的区别

  静态:由程序员创建代理类对其编译。在程序运行前代理类的.class文件就已经存在了。

  动态:在程序运行时运用反射机制动态创建而成。

7. 静态代理

  静态代理需要创建真实角色和代理角色,分别实现唱歌这个接口,真实角色很简单,直接实现即可,因为真实角色的主要任务就是唱歌。

代理类就需要做点工作了,我们思考一下,代理只是在明星唱歌前后做一些准备和收尾的事,唱歌这件事还得明星亲自上阵,代理做不了。所以代理类里面是肯定要将真实的对象传进来。

8. JDK 动态代理

  既然动态代理不需要我们去创建代理类,那我们只需要编写一个动态处理器就可以了。真正的代理对象由 JDK 在运行时为我们动态的来创建。

  具体实现:

  1.定义接口类
  2.定义接口实现类

  3.定义动态代理类,实现 InvocationHandler 主要是实现 其中的invoke 其中是利用反射技术获取代理类的方法,然后对方法加强
  4. 客户端调用
// 1.定义接口类
public interface IPerson
{
    void say();
}
//2.定义接口实现类 public class Person implements IPerson { @Override public void say() { System.out.println("我是个人"); } }
//3.定义动态代理类,实现 InvocationHandler 主要是实现 其中的invoke 其中是利用反射技术获取代理类的方法,然后对方法加强
public class ProxyForPerson implements InvocationHandler
{

    IPerson person = null;

    // 关联代理类和接口
    public IPerson getProxyInterface(IPerson person) {
        this.person = person;
        return (IPerson) Proxy.newProxyInstance(person.getClass()
                .getClassLoader(),
                person.getClass()
                        .getInterfaces(),
                this);
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        if("say".equals(method.getName())){
            method.invoke(person, args);
        }
        return null;
    }
}
// 4. 客户端调用
public class Client
{
    public static void main(String[] args) {

        Person person = new Person();
        ProxyForPerson proxy = new ProxyForPerson();
        // 获得代理类
        IPerson iperson = proxy.getProxyInterface(person);

        iperson.say();
    }
}

  

9.CGLIB 动态代理

CGLIB 采用了非常底层的字节码技术,其原理是通过字节码技术为一个类创建子类,并在子类中采用方法拦截的技术拦截所有父类方法的调用,顺势织入横切逻辑。但因为采用的是继承,所以不能对final修饰的类进行代理

JDK动态代理和CGLIB动态代理的区别

  JDK动态代理只能对实现了接口的类生成代理,而不能针对类 (缺点:也就是说它始终无法摆脱仅支持 interface 代理的桎梏,因为它的设计就注定了这个遗憾。)

  CGLIB是针对类实现代理,主要是对指定的类生成一个子类,覆盖其中的方法(继承),(缺点: 对于final修饰的方法无法进行代理)

10.Spring AOP 采用哪种代理?

  在spring5 的源码中,对于使用JDK的动态代理还是CHLIB的代理,他会进行一个判断hasNoUserSuppliedProxyInterfaces(config)  

就是在判断代理的对象是否有实现接口,有实现接口的话直接走 JDK 分支,即使用 JDK 的动态代理。

所以基本上可以总结出 Spring AOP 中的代理使用逻辑了:如果目标对象实现了接口,默认情况下会采用 JDK 的动态代理实现 AOP;如果目标对象没有实现了接口,则采用 CGLIB 库,Spring 会自动在 JDK 动态代理和 CGLIB 动态代理之间转换。

我们也可以强制使用CGlib(在spring配置中加入<aop:aspectj-autoproxy proxy-target-class="true"/>)

原文地址:https://www.cnblogs.com/xiaowangbangzhu/p/10755337.html