浅谈Spring框架

一、什么是Spring?

        Spring是一个开源框架,可以降低开发复杂度,提高开发效率,轻量级低耦合的框架。由于Spring的分层架构,可以自己选择整合其他组件,灵活性高

二、什么是IOC?

       IOC 叫做控制反转,指的是通过Spring来管理对象的创建、配置和生命周期,这样相当于把控制权交给了Spring,不需要人工来管理对象之间复杂的依赖关系,这样做的好处就是解耦。在Spring里面,主要提供了 BeanFactory 和 ApplicationContext 两种 IOC 容器,通过他们来实现对 Bean 的管理。

        BeanFactory采用延迟加载机制,初始化时间短,适用于资源有限或需要延迟加载的场景。ApplicationContext在启动时预先加载所有Bean对象,初始化时间较长,但在应用运行时能够更快地获取Bean对象,并提供了更多的功能和特性,适用于大多数应用场景

  1. BeanFactory(Bean工厂,顶层接口): BeanFactory是Spring框架中最基本的IOC容器接口。它是一种轻量级的容器,采用延迟加载(懒加载)机制,即在需要获取Bean时才进行实例化和初始化。由于延迟加载的特性,BeanFactory的初始化时间较短,节约了系统资源。BeanFactory提供了基本的IOC功能,包括Bean的实例化、配置、装配以及管理Bean之间的依赖关系。

  2. ApplicationContext: ApplicationContext是BeanFactory的子接口,也是Spring框架中更高级、功能更丰富的IOC容器。与BeanFactory相比,ApplicationContext在启动时会预先加载所有Bean对象,进行实例化和初始化。这使得ApplicationContext在应用运行时能够更快地获取Bean对象,提高了应用的性能。除了BeanFactory的功能外,ApplicationContext还提供了更多的特性,如国际化支持、事件传播、资源加载、AOP等。

三、什么是AOP?

        AOP即面向切面编程,可以在不改变原有代码的基础上对目标方法进行无侵入式增强。AOP 基于动态代理的方式实现,如果是实现了接口的话就会使用 JDK 动态代理,反之则使用 CGLIB 代理,Spring中 AOP 的应用主要体现在 事务、日志、异常处理等方面,通过在代码的前后做一些增强处理,可以实现对业务逻辑的隔离,提高代码的模块化能力,同时也是解耦。

四、JDK动态代理和CGliB代理区别有哪些?

Spring提供了两种方式来实现动态代理:JDK动态代理和CGLIB代理

JDK动态代理:JDK动态代理是基于接口的代理,通过反射机制动态生成代理类。当目标对象实现了接口时,Spring会使用JDK动态代理来创建代理对象。JDK动态代理通过Proxy类和InvocationHandler接口实现。在运行时,通过Proxy类的newProxyInstance()方法生成代理对象,同时传入一个实现了InvocationHandler接口的代理处理器对象,用于处理代理对象的方法调用。

// 定义UserService接口,包含addUser方法
public interface UserService {void addUser();
}// UserServiceImpl实现了UserService接口,实现了addUser方法
public class UserServiceImpl implements UserService {@Overridepublic void addUser() {System.out.println("Add user");}
}// MyInvocationHandler实现了JDK动态代理的InvocationHandler接口,用于对目标方法进行增强
public class MyInvocationHandler implements InvocationHandler {private Object target; // 目标对象public MyInvocationHandler(Object target) {this.target = target; // 初始化目标对象}@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println("Before method call"); // 在方法调用前输出信息Object result = method.invoke(target, args); // 调用目标对象的原始方法System.out.println("After method call"); // 在方法调用后输出信息return result;}
}public class Main {public static void main(String[] args) {UserService target = new UserServiceImpl(); // 创建目标对象MyInvocationHandler handler = new MyInvocationHandler(target); // 创建代理处理器UserService proxy = (UserService) Proxy.newProxyInstance(target.getClass().getClassLoader(), // 类加载器target.getClass().getInterfaces(), // 目标对象实现的接口handler // 代理处理器);proxy.addUser(); // 调用代理对象的方法,实际会执行增强后的逻辑}
}

CGLIB代理:CGLIB代理是基于继承的代理,当目标对象没有实现接口时,Spring会使用CGLIB代理来创建代理对象。CGLIB代理通过字节码技术生成目标对象的子类,并重写父类的方法来实现增强功能。

// UserService类定义了一个简单的方法 addUser
public class UserService {public void addUser() {System.out.println("Add user");}
}// MyMethodInterceptor实现了CGLIB的MethodInterceptor接口,用于对目标方法进行增强
public class MyMethodInterceptor implements MethodInterceptor {@Overridepublic Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {System.out.println("Before method call"); // 在方法调用前输出信息Object result = proxy.invokeSuper(obj, args); // 调用被代理对象的原始方法System.out.println("After method call"); // 在方法调用后输出信息return result;}
}public class Main {public static void main(String[] args) {Enhancer enhancer = new Enhancer(); // 创建Enhancer对象,用于生成代理类enhancer.setSuperclass(UserService.class); // 设置父类为UserService,生成的代理类会继承UserServiceenhancer.setCallback(new MyMethodInterceptor()); // 设置方法拦截器,用于对目标方法进行增强UserService proxy = (UserService) enhancer.create(); // 创建代理对象proxy.addUser(); // 调用代理对象的方法,实际会执行增强后的逻辑}
}

五、Spring中有哪些设计模式?

1.代理模式:

        所谓代理,是指它与被代理对象实现了相同的接口,客户端必须通过代理才能与被代理的目标类进行交互,而代理一般在交互的过程中(交互前后),进行某些特定的处理,比如在调用这个方法前做前置处理,调用这个方法后做后置处理。代理又分为静态代理和动态代理两种方式,Spring 的 AOP 采用的是动态代理的方式Spring 通过动态代理对类进行方法级别的切面增强,动态生成目标对象的代理类,并在代理类的方法中设置拦截器,通过执行拦截器中的逻辑增强了代理方法的功能,从而实现 AOP。

2.单例模式:

        单例模式是指一个类在整个系统运行过程中,只允许产生一个实例。在Spring中,Bean 可以被定义为两种模式:Prototype(多例)和Singleton(单例),Spring 默认是单例模式。那么Spring是如何实现单例模式的呢?答案是通过单例注册表的方式,具体来说就是使用了HashMap

public class DefaultSingletonBeanRegistry {//使用了线程安全容器ConcurrentHashMap,保存各种单实例对象private final Map singletonObjects = new ConcurrentHashMap;protected Object getSingleton(String beanName) {//先到HashMap中拿ObjectObject singletonObject = singletonObjects.get(beanName);//如果没拿到通过反射创建一个对象实例,并添加到HashMap中if (singletonObject == null) {singletonObjects.put(beanName,Class.forName(beanName).newInstance());}//返回对象实例return singletonObjects.get(beanName);}
}

3.模板模式:

        主要是一些对数据库操作的类用到,比如 JdbcTemplate、JpaTemplate,因为查询数据库的建立连接、执行查询、关闭连接几个过程,非常适用于模板方法。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/760886.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何在 Java 中造成内存泄漏?

如何在 Java 中造成内存泄漏? 应用程序创建一个长时间运行的线程(或使用线程池来更快地泄漏)。线程通过(可选自定义)加载类ClassLoader。该类分配一大块内存(例如new byte[1000000])&#xff0…

Python PEP 8 代码风格指南

Python PEP 8 代码风格指南 0. 引言1. 空白字符2. 命名3. 表达式和语句4. 导入5. Pylint工具6. 要点总结 0. 引言 Python增强提案#8,也称作 PEP 8,是关于如何格式化Python代码的风格指南。 你可以按自己的方式编写Python代码,只要符合有效的语法规则。 然而,使用一致的风格可…

运维篇SHELL脚本实战案例

统计出每个IP的访问量有多少? 检查是否提供了日志文件的路径作为参数。使用awk从日志文件的每行中提取第一个字段(假设这是IP地址)。使用sort对提取的IP地址进行排序。使用uniq -c统计每个唯一IP地址的出现次数。最后,使用sort -…

一次消谐器在电力系统中的作用分析

一次消谐器是一种专门用于消除电力系统中的高次谐波的装置。它通过实时监测和分析系统中的谐波成分,采用先进的滤波技术,将谐波分量从系统中滤除,从而保持电力系统的稳定运行。 一次消谐器的主要作用体现在以下几个方面: 1. 保护电…

复习斐波那契(用C++写)

或者这样写: 斐波那契数列 题目描述 斐波那契数列是指这样的数列:数列的第一个和第二个数都为 1 1 1,接下来每个数都等于前面 2 2 2 个数之和。 给出一个正整数 a a a,要求斐波那契数列中第 a a a 个数是多少。 输入格式…

Java基础---IO流

1. File类 1.1 File的介绍 File是java.io.包下的类, File类的对象,用于代表当前操作系统的文件(可以是文件、或文件夹)。 注意:File类只能对文件本身进行操作,不能读写文件里面存储的数据。 1.2 File类…

Python模块-基础知识

Python模块-基础知识 1.模块分类: (1)自定义模块: 如果你自己写一个py文件,在文件内写入一堆函数,则它被称为自定义模块,即使用python编写的.py文件 (2)第三方模块&…

python初始化二维数据

1.遇到的问题 突然不知道什么原因,想起来实现一个矩阵的乘法,于是用python代码实现一下。 def matrix_multiply():a [[1, 2], [3, 4]]b [[5, 6, 7], [8, 9, 10]]m, n len(a[0]), len(b)if m ! n:print(we need a column equal b row!)m, t len(a),…

javaSE练习题(一)

1、BMI是根据体重测量健康的方式。通过以千克为单位的体重除以以米为单位的身高的平方计算出BMI。下面是16 岁以上人群的BMI图表: 编写一个java程序,提示用户输人以磅为单位的体重和以英寸为单位的身高,然后显示BMI值。注意: 1磅是0.453592 37千克而1英寸…

【工具类】adb常用命令

1. adb常用命令 1. adb常用命令 1.1. 常用命令1.2. 命令解析1.3. 参考资料 为了描述方便,假设需要通过 adb 操作 android 系统,本机是 ubuntu 系统 1.1. 常用命令 上传下载,/data/log 目录是手机上的目录,~/Downloads/log 是…

9大变频电源模块的测试参数及其重要性

变频电源是将交流电经过交流-直流-交流变换,从而得到输出为正弦波的交流电,广泛应用于家电、电机、电脑设备、测试单位、航空等领域。变频电源测试是确保系统稳定运行的重要步骤。 变频电源测试的重要参数 1. 输出电压和电流 可用万用表、电流表或者示波…

解决 Jupyter Notebook 中没有显示想要的内核的问题

如果在 Jupyter Notebook 的 “Kernel” 菜单中没有显示你想要的内核(kernel),可能是因为该内核没有正确安装或配置到 Jupyter Notebook 中。在这种情况下,你可以尝试以下几个方法: 重新安装内核:首先&…

企业电脑如何管控(高效管控企业电脑的小技巧)

员工企业管理一直以来都是一个难题,难在人员多管理费劲。 因此高效管理一直都是企业最头疼的问题。 而使用一款软件辅助管理是很多企业发现的最有效的方法,如域智盾软件。 域智盾软件是一款专业的文件加密和数据安全软件,适用于各种企业和个…

C++异常处理

C异常处理 try和catch 在C中,try 是异常处理的关键字,用于定义一个代码块,该代码块中可能抛出异常。如果在 try 块中发生了异常,程序会立即停止当前块的执行,并查找与之匹配的 catch 块来处理异常。 下面是一个基本…

4.1 用源文件写汇编代码

汇编语言 1. 源程序 1.1 伪指令 汇编指令是有对应的机器码的指令,可以被编译为机器指令,最终为CPU所执行伪指令没有对应的机器指令,最终不被CPU所执行伪指令是由编译器来执行的指令,编译器根据伪指令来进行相关的编译工作 1.2…

【LeetCode每日一题】2312. 卖木头块(DFS记忆化搜索+动态规划)

文章目录 [2312. 卖木头块](https://leetcode.cn/problems/selling-pieces-of-wood/)思路1:用DFS进行记忆化搜索代码:思路2:动态规划代码: 2312. 卖木头块 思路1:用DFS进行记忆化搜索 1.要用DFS深度优先遍历每一种情况。在递归的同时,不断更…

【什么是Internet?网络边缘,网络核心,分组交换 vs 电路交换,接入网络和物理媒体】

文章目录 一、什么是Internet?1.从具体构成角度来看2.从服务角度来看 二、网络结构1.网络边缘1.网络边缘:采用网络设施的面向连接服务1.1.目标:在端系统之间传输数据1.2.TCP服务 2.网络边缘:采用网络设施的无连接服务2.1目标&…

unicloud快速上手,unicloud项目创建以及项目创建注意事项

uniCloud快速上手 本项目地址https://gitee.com/qayrup/unicloud-demo 创建unicloud项目 新建一个uni项目,并选择启用unicloud,选择阿里云或腾讯云 阿里云和支付宝云都支持一个月免费的云,如果只想体验啥的,可以选择这两个, 但是需要注意,支付宝云需要配置跨域,否则很多云函…

XCode升级错误:Command CompileC failed with a nonzero exit code 解决办法

升级完XCode之后,bulid失败,出现如下错误: 问题1: xcrun: error: invalid active developer path (/Library/Developer/CommandLineTools), missing xcrun at: /Library/Developer/CommandLineTools/usr/bin/xcrunCommand Compi…

网络编程面试题

一、什么是IP地址 1.IP地址是主机在网路中的唯一标识,,当主机从一个网络切换到另一个网络时,会更改IP地址,同样的IP地址也是路由器进行路由选择的标识 2.IP地址的分类 IPV4:采用4字节无符号整数存储 IPV6&#xff…