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 默认使用动态代理机制,具体选择如下:
-
JDK 动态代理:
-
条件:目标类实现了至少一个接口。
-
实现:通过
java.lang.reflect.Proxy
创建代理对象,代理类实现相同接口并将调用转发给目标对象。
-
-
CGLIB 代理:
-
条件:目标类未实现任何接口。
-
实现:通过生成目标类的子类来创建代理对象,子类重写父类方法并加入切面逻辑。
-
选择规则
-
若目标类实现了接口,默认使用 JDK 动态代理。
-
若未实现接口,则使用 CGLIB 代理。
-
可通过配置强制使用 CGLIB 代理,即使目标类实现了接口。
强制使用 CGLIB
在 Spring 配置中设置 proxy-target-class="true"
即可强制使用 CGLIB 代理:
<aop:config proxy-target-class="true">
<!-- AOP 配置 -->
</aop:config>
或使用注解:
@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 等)。
-
最终,代理对象会调用原始目标方法。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix