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)独立于各种应用服务器

 

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

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

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

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

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

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

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

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

7. 静态代理

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

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

8. JDK 动态代理

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

  具体实现:

1
1.定义接口类
1
2.定义接口实现类<br><br>  3.定义动态代理类,实现 InvocationHandler  主要是实现 其中的invoke 其中是利用反射技术获取代理类的方法,然后对方法加强
1
4. 客户端调用

i

 

复制代码
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

// 接口
interface Subject {
    void request();
}

// 被代理类
class RealSubject implements Subject {
    public void request() {
        System.out.println("RealSubject: Handling request.");
    }
}

// 动态代理处理器
class DynamicProxyHandler implements InvocationHandler {
    private Object target;

    public DynamicProxyHandler(Object target) {
        this.target = target;
    }

    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("DynamicProxy: Pre-processing.");
        Object result = method.invoke(target, args);
        System.out.println("DynamicProxy: Post-processing.");
        return result;
    }
}

// 测试类
class Main {
    public static void main(String[] args) {
        RealSubject realSubject = new RealSubject();
        Subject proxy = (Subject) Proxy.newProxyInstance(
            RealSubject.class.getClassLoader(),
            new Class[]{Subject.class},
            new DynamicProxyHandler(realSubject)
        );
        proxy.request();
    }
}
复制代码

 

 

9.CGLIB 动态代理

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

10.Spring AOP 采用哪种代理?

  

Spring AOP 默认使用动态代理机制,具体选择如下:

  1. JDK 动态代理

    • 条件:目标类实现了至少一个接口。

    • 实现:通过 java.lang.reflect.Proxy 创建代理对象,代理类实现相同接口并将调用转发给目标对象。

  2. CGLIB 代理

    • 条件:目标类未实现任何接口。

    • 实现:通过生成目标类的子类来创建代理对象,子类重写父类方法并加入切面逻辑。

选择规则

  • 若目标类实现了接口,默认使用 JDK 动态代理。

  • 若未实现接口,则使用 CGLIB 代理。

  • 可通过配置强制使用 CGLIB 代理,即使目标类实现了接口。

强制使用 CGLIB

在 Spring 配置中设置 proxy-target-class="true" 即可强制使用 CGLIB 代理:

xml
复制
<aop:config proxy-target-class="true">
    <!-- AOP 配置 -->
</aop:config>

或使用注解:

java
复制
@EnableAspectJAutoProxy(proxyTargetClass = true)

总结

  • JDK 动态代理:适用于有接口的目标类。

  • CGLIB 代理:适用于无接口的目标类,或强制使用 CGLIB 时。

Spring 根据目标类是否实现接口自动选择合适的代理方式,也可手动配置强制使用 CGLIB。

 

 动态代理的实现方式

Spring AOP 使用两种动态代理技术来实现代理对象:

  • JDK 动态代理:基于接口的代理。

  • CGLIB 动态代理:基于子类的代理。

(1)JDK 动态代理

  • 适用场景:如果目标对象实现了接口,Spring 会默认使用 JDK 动态代理。

  • 原理:Spring 会动态生成一个实现了目标接口的代理类,并在代理类中调用目标方法前后插入通知逻辑。

  • 特点:只能代理接口中的方法。

(2)CGLIB 动态代理

  • 适用场景:如果目标对象没有实现接口,Spring 会使用 CGLIB 动态代理。

  • 原理:Spring 会动态生成一个目标类的子类,并重写目标方法,在重写的方法中插入通知逻辑。

  • 特点:可以代理普通类的方法,但无法代理 final 方法或类。

·很多人会对比 JDK和Cglib的性能,jdk动态代理生成类速度快,调用慢,cglib生成类速度慢,但后续调用快,在老版本CGLIB的速度是JDK速度的10倍左右,但是实际上JDK的速度在版本升级的时候每次都提高很多性能,而CGLIB仍止步不前.

在对JDK动态代理与CGlib动态代理的代码实验中看,1W次执行下,JDK7及8的动态代理性能比CGlib要好20%左右。

 

5. 什么是 Spring AOP?

  通过动态代理技术在目标方法执行前后插入额外的逻辑。Spring AOP 的核心思想是“代理模式”,它不会直接修改原始类的代码,而是通过生成一个代理对象来间接增强目标方法的行为。

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

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

https://zhuanlan.zhihu.com/p/460412492 spring aop

Spring的 Aop的完整实现流程?

(1)定义切面(Aspect)

  • 切面是一个类,包含通知(Advice)和切点(Pointcut)。

  • 通知定义了在目标方法执行前后要执行的逻辑。

  • 切点定义了哪些方法需要被拦截。

(2)生成代理对象

  • Spring 在启动时,会根据配置的切面和切点,为目标对象生成一个代理对象。

  • 如果目标对象实现了接口,使用 JDK 动态代理;如果没有实现接口,使用 CGLIB 动态代理。

(3)调用代理对象

  • 当调用目标方法时,实际上调用的是代理对象的方法。

  • 代理对象会根据切点的配置,决定是否在目标方法执行前后插入通知逻辑。

(4)执行通知逻辑

  • 如果目标方法匹配切点,代理对象会依次执行通知逻辑(如 @Before、@After、@Around 等)。

  • 最终,代理对象会调用原始目标方法。

 

posted @   好记性不如烂笔头=>  阅读(2273)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
点击右上角即可分享
微信分享提示