想做外贸做哪些网站好,服装商城网站模板,电商seo是什么意思,“设计网站”文章目录前言一、Spring 容器警告产生的场景二、Spring 容器未关闭后果分析2.1、肉眼可见的警告2.2、导致的内存泄漏2.2.1、什么是内存泄漏#xff1f;2.2.2、如何判断内存泄漏#xff1f;2.2.3、Java 中的 GC#xff08;垃圾回收#xff09;2.2.4、Java 中会导致内存泄漏的…
文章目录前言一、Spring 容器警告产生的场景二、Spring 容器未关闭后果分析2.1、肉眼可见的警告2.2、导致的内存泄漏2.2.1、什么是内存泄漏2.2.2、如何判断内存泄漏2.2.3、Java 中的 GC垃圾回收2.2.4、Java 中会导致内存泄漏的情况2.2.5、Spring 容器未关闭导致的内存泄漏问题三、如何手动关闭 Spring 容器3.2 最常用3.1、context.close();3.2、((ConfigurableApplicationContext) context).close();3.2.1、导入 org.springframework.context.support.AbstractApplicationContext 包3.2.2、删掉多余的导包3.3、使用获取对象公开声明的方法3.3.1、Method Class.getMethod(String name, Class?... parameterTypes)3.3.2、如何使用该方法关闭 Spring 容器总结前言 我们在初始化了 Spring IoC 的容器 ApplicationContext并加载完配置文件之后如果不对容器进行处理首先我们直观上看到的就是 IDE 的警告Resource leak: context is never closed。其次还有什么其他层次的问题这类问题我们如何去解决本文就这类问题提出了三种不同的解决方式让你通过一个问题解决一类问题。 一、Spring 容器警告产生的场景
我们初始化了 Spring IoC 的容器 ApplicationContext并加载完配置文件创建了一个 Bean 的实例代码如下
public class Test {public static void main(String[] args) {// 初始化Spring容器applicationContext加载配置文件ApplicationContext context new ClassPathXmlApplicationContext(applicationContext.xml);// 通过容器获取test实例TestDao dao (TestDao) context.getBean(test);// test为配置文件中的iddao.sayHello();}
}可以看得到这里我们在使用完容器之后并没有对容器进行处理然后 IDE 就发出了如下警告
Resource leak: context is never closed提示我们容器没有关闭警告内容具体如下图所示 二、Spring 容器未关闭后果分析
2.1、肉眼可见的警告
对于强迫症来说这不是要了老命吗我好好的一个项目你给我来个感叹号不行我一定要解决 使用快捷键快速定位光标行出现的问题根据提示添加如下代码什么意思呢忽略警告。如果你仅仅就是为了去掉警告你就不必继续往下看了。这个方式完全可以满足你。
SuppressWarnings(resource)2.2、导致的内存泄漏
容器未关闭可能会导致内存泄漏说到这里可能会有人有疑问 Java 不是有 GC垃圾回收机制吗怎么会导致内存泄漏呢别急我们来一步一步分析。
2.2.1、什么是内存泄漏 内存泄漏是指不再被使用的对象或变量一直占据在内存中。 2.2.2、如何判断内存泄漏 检查 Java 中的内存泄漏一定要将程序各个分支情况都完成执行至结束然后看其是否被使用过如果没有才能判定这个对象属于内存泄漏。 2.2.3、Java 中的 GC垃圾回收 Java 虚拟机 JVM 会将不再使用的对象或变量从内存中回收来释放内存。 关于 Java 中 GC 的内容这里不做赘述可以移步我的相关 Java 专栏查看 2.2.4、Java 中会导致内存泄漏的情况
当长生命周期的对象持有短生命周期的对象的引用就很可能发生内存泄漏。尽管短生命周期的对象已经不再需要但是长生命周期的对象一直持有它的引用导致其无法被回收。例如缓存系统加载一个对象放在缓存系统中一直不去使用这个对象但是它一直被缓存引用所以不会被回收导致缓存泄漏。当一个对象被存储进 HashSet 集合中就不可修改这个对象中用于计算哈希值的属性了。否则对象修改后的哈希值与刚添加进 HashSet 集合时的哈希值不一样此时如果将当前对象的引用作为参数用 contains 方法判断对象是否存在则会返回找不到对象的结果。这会导致无法从 HashSet 单独删除当前对象造成内存泄漏。
2.2.5、Spring 容器未关闭导致的内存泄漏问题
Spring IoC 容器在我们开启之后JVM 无法像回收对象或者变量的那种来进行回收。Spring 容器的生命周期是比较长的因为它用于管理所有初始化的 Bean其生命周期在 Bean 之后具体关于 Spring 的生命周期我们后面会讲到如果我们不及时关闭它就会占用内存导致 JVM 效率降低同时造成内存泄漏。当然这也不符合我们的开发规范。
三、如何手动关闭 Spring 容器3.2 最常用
我们该如何解决关闭容器、流的一类问题呢下面整理了 3 种方法第一种最为方便第二种是我们开发中最常使用的方法第三种是最为简单粗暴的方法大家可以根据自己需求来使用。
3.1、context.close();
处理 Spring 容器类似于 Scanner 流我们按照关闭 Scanner 流的思路打点调用 close() 方法添加关闭代码如下所示
context.close();这时仍然还是报错。根据提示The method close() is undefined for the type ApplicationContext我们会得知 close() 方法并未直接定义在 Spring IoC 容器中使用快捷键快速定位光标行出现的问题我们对 context 进添加类型转换如下图所示 这个时候就添加了如下一行代码
((AbstractApplicationContext) context).close();这样是可以关闭掉 Spring 容器。其解决的就是context.close();的问题。
3.2、((ConfigurableApplicationContext) context).close();
在 Spring 中定义了关闭掉 Spring 容器的方法 close()该方法定义在 ApplicationContext 的子类 ConfigurableApplicationContext 中。那我们该如何快速调出它关闭容器呢
3.2.1、导入 org.springframework.context.support.AbstractApplicationContext 包
我们使用快捷键先进行 3.1 的步骤然后删掉 3.1 的关闭代码((AbstractApplicationContext) context).close();重写一次关闭代码context.close();这个时候我们就可以看到强转的时候多了一个类型 ConfigurableApplicationContext我们选择这个即可如下图所示 注意一定要导入 org.springframework.context.support.AbstractApplicationContext 包才会出现 ConfigurableApplicationContext 的强转类型。
这个时候我们的关闭代码就是下面这样的
((ConfigurableApplicationContext) context).close();3.2.2、删掉多余的导包
这个时候我们就可以根据提示将多余的导包删掉了包括上面的 org.springframework.context.support.AbstractApplicationContext。
小结这个写法是我们在开发中最常用的手动关闭 Spring 容器的方法。
3.3、使用获取对象公开声明的方法
3.3.1、Method Class.getMethod(String name, Class?… parameterTypes)
补充的这个方法的作用是获得对象所声明的公开方法这也是我们在开发中获取对象方法的常用方法
Method Class.getMethod(String name, Class?... parameterTypes)参数说明
参数 name 获得当前方法的名字。参数 parameterTypes 是按声明顺序标识该方法形参类型。如果对象内的方法的形参是 int 类型的则 parameterTypes 是 int.class。
举例如下
person.getClass().getMethod(Speak, null);
//获得person对象的Speak方法因为Speak方法没有形参所以parameterTypes为nullperson.getClass().getMethod(run, String.class);
//获得person对象的run方法因为run方法的形参是String类型的所以parameterTypes为String.class3.3.2、如何使用该方法关闭 Spring 容器
根据 3.3.1 中的内容我们可以通过获取 context 对象的方法 close() 并 invoke 掉 context 容器对象null 值省略代码如下
context.getClass().getMethod(close).invoke(context);但是需要注意如果使用这个方法就需要对异常进行处理我这里对异常进行捕获完整代码如下
package cn.bailu.ch1.test;import java.lang.reflect.InvocationTargetException;import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;import cn.bailu.ch1.dao.TestDao;public class Test {public static void main(String[] args) {// 初始化Spring容器applicationContext加载配置文件ApplicationContext context new ClassPathXmlApplicationContext(applicationContext.xml);// 通过容器获取test实例TestDao dao (TestDao) context.getBean(test);// test为配置文件中的idtry {context.getClass().getMethod(close).invoke(context);} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException| SecurityException e) {// TODO Auto-generated catch blocke.printStackTrace();}dao.sayHello();}
}总结 本文就如何关闭 Spring IoC 容器给大家带来了三种常见的解决方式其中第一种方式是最为简单的第二种方式是我们在开发中最为常用的这个方式很大程度上考察了你对于 Spring 源码的了解程度你了解源码才能知道里面的方法而第三种方式是最为简单粗暴的同时也是我们在获取对象其他方法时较为常用的这个方法考察的就是你对于 Java 基本代码的了解程度对于使用就根据你自己的需求来了。一个简单的案例足见你的基本功扎实基础多看源码 我是白鹿一个不懈奋斗的程序猿。望本文能对你有所裨益欢迎大家的一键三连若有其他问题、建议或者补充可以留言在文章下方感谢大家的支持