在java的实际开发过程中,我们可能常常需要使用到init method和destroy method,比如初始化一个对象(bean)后立即初始化(加载)一些数据,在销毁一个对象之前进行垃圾回收等等。
周末对这两个方法进行了一点学习和整理,倒也不是专门为了这两个方法,而是在巩固spring相关知识的时候提到了,然后感觉自己并不是很熟悉这个,便好好的了解一下。
根据特意的去了解后,发现实际上可以有三种方式来实现init method和destroy method。
要用这两个方法,自然先要知道这两个方法究竟是干嘛用的。而从字面意思就很容易理解,一个是加载,一个是销毁。
下边就正式代码演示三种创建方式:
一、@Bean注解方式:
首先要创建一个至少拥有两个方法的类,一个方法充当init method,另一个充当destroy method。
package springTest2;
public class Test1 {
public void init() {
System.out.println("this is init method1");
}
public Test1() {
super();
System.out.println("构造函数1");
}
public void destroy() {
System.out.println("this is destroy method1");
}
}
这里很显然只是一个普通的java类,拥有一个无参构造和另外两个方法。
需要注意的是,这里的init和destroy两个方法名实际上是可以随意取得,不叫这个也没有问题,只不过算是一种约定俗称,一般都是这样叫。
另外我们也知道,这个构造方法也是可以不要的,因为会隐式的自动创建,但是为了更清楚的看到init和destroy是什么时候执行,我们就显示的写出来。
创建好了这个类,我们就可以使用@Bean注解的方式指定两个方法,以让他们生效。
package springTest2;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@ComponentScan("springTest2")
public class ConfigTest {
@Bean(initMethod = "init", destroyMethod = "destroy")
Test1 test1() {
return new Test1();
}
}
这里边的@Configguration注解是告诉spring这个类是一个配置类,相当于我们的xml文件,@ComponentScan则是指定需要spring来扫描的包,相当于xml中的context:component-scan属性。
而@Bean后边的initMethod和destroyMethod就是在声明这是一个baen的同时指定了init和destroy方法,方法名从功能实现上来说可以随意。
到这里我们就已经用第一种方式写好了,为了验证成功与否,再写一个main方法验证一下:
package springTest2;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class MainTest {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ConfigTest.class);
System.out.println("#################################");
context.close();
}
}
运行之后结果如图:
根据打印顺序可以看到,首先是构造函数,也就是创建了bean,紧接着执行了init,然后再context.close要销毁bean之前又执行了destroy。
二、JSR-250注解的方式(需要导入jsr250-api的jar包):
首先依然是创建一个拥有构造方法在内的三个方法的java类:
package springTest2;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
public class Test2 {
@PostConstruct
public void init() {
System.out.println("this is init method2");
}
public Test2() {
super();
System.out.println("构造函数2");
}
@PreDestroy
public void destroy() {
System.out.println("this is destroy method2");
}
}
很显然,这里和上一个类不同的是,在init和destroy方法上加入了两个注解,@PostConstruct和上边@Bean后的initMethod相同,而@PreDestroy则是和destroyMethod做用相同。
既然这里有了区别,已经指定了init method和destroy method,那么后边声明bean的时候自然也会有不同,也就不需要再指定一遍:
package springTest2;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@ComponentScan("springTest2")
public class ConfigTest {
@Bean
Test2 test2() {
return new Test2();
}
}
所以,如上代码中只需要简单的声明这是一个bean就可以了,类上边的两个注解和上一个例子中的意思相同。
再测试一下:
package springTest2;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class MainTest {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ConfigTest.class);
System.out.println("#################################");
context.close();
}
}
结果如下:
三、xml配置的方式:
这种方式实际上是和第一种对应的,只不过细节上略有改变而已,首先,创建的java类完全一样:
package springTest2;
public class Test3 {
public void init() {
System.out.println("this is init method3");
}
public Test3() {
super();
System.out.println("构造函数3");
}
public void destroy() {
System.out.println("this is destroy method3");
}
public void test() {
System.out.println("testttttttt");
}
}
不同的地方就在于,第一个例子中是使用注解告诉spring这个类相当于一个配置文件,而这里则是实实在在的配置文件spring.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="initOrDestroyTest" class="springTest2.Test3" init-method="init" destroy-method="destroy">
</bean>
</beans>
这个配置大概也能算是spring.xml中最简单的一个配置了吧,除开必要的文件头,就只有一个bean,而且bean里边也只有id,calss和init以及destroy方法。
因为简单,所以一目了然,id只是为了其他地方引用,class是指定这个bean对应的类,而后边两个属性则和用@Bean声明时一模一样。
因为这里声明bean和指定两个方法是用的xml配置,因此在测试的时候也就需要稍微有一点点改变:
package springTest2;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MainTest {
public static void main(String[] args) {
ClassPathXmlApplicationContext context1 = new ClassPathXmlApplicationContext("spring.xml");
System.out.println("#################################");
context1.close();
}
}
区别在于这里直接加载了配置文件,而不是java类,使用的是ClassPathxXmlApplicationContext而不是AnnotationConfigApplicationContext。
结果如下:
这里需要说明的一点是,在实际的web应用使用时,可以在web.xml中使用类似下边的配置来加载bean,实现init method:
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
然后启动tomcat结果如下:
这里边没有调用destroy method,原因是spring本身代码就需要我们手动调用销毁bean的方法,像前边的几个例子中的context.close就是。
如果不手动调用这个方法,bean就不会被销毁,也就不会去调用destroy method,这也就是为何这里在web.xml中配置后,启动tomcat 只打印了构造函数和init方法中的内容。
例子都是很简单的,而通过简单的例子对比可能能更进一步理解相关的知识,理解了才能在实际应用中更好的进行选择和集成。
spring init method destroy method的更多相关文章
-
java代码中init method和destroy method的三种使用方式
在java的实际开发过程中,我们可能常常需要使用到init method和destroy method,比如初始化一个对象(bean)后立即初始化(加载)一些数据,在销毁一个对象之前进行垃圾回收等等. ...
-
EurekaClient项目启动报错Invocation of destroy method failed on bean with name &#39;scopedTarget.eurekaClient&#39;: org.springframework.beans.factory.BeanCreationNotAllowedException: Error creating bean with name &#39;e
Disconnected from the target VM, address: '127.0.0.1:51233', transport: 'socket' Eureka Client的使用 使用 ...
-
Invoking destroy method &#39;close&#39; on bean with name &#39;dataSource&#39;
Invoking destroy method 'close' on bean with name 'dataSource' Spring与Mybatis整合时出现的问题,找了一晚上结果是一个属性写错 ...
-
JavaEE开发之Spring中Bean的作用域、Init和Destroy方法以及Spring-EL表达式
上篇博客我们聊了<JavaEE开发之Spring中的依赖注入以及AOP>,本篇博客我们就来聊一下Spring框架中的Bean的作用域以及Bean的Init和Destroy方法,然后在聊一下 ...
-
Invocation of destroy method failed on bean with name ‘XXXX’
项目启动报错问题:Invocation of destroy method failed on bean with name 'scopedTarget.eurekaClient': org.spri ...
-
关于.ToList(): LINQ to Entities does not recognize the method ‘xxx’ method, and this method cannot be translated into a store expression.
LINQ to Entities works by translating LINQ queries to SQL queries, then executing the resulting quer ...
-
『重构--改善既有代码的设计』读书笔记----Replace Method with Method Object
有时候,当你遇到一个大型函数,里面的临时变量和参数多的让你觉得根本无法进行Extract Method.重构中也大力的推荐短小函数的好处,它所带来的解释性,复用性让你收益无穷.但如果你遇到上种情况,你 ...
-
Servlet Filter 中init和destroy问题
测试源码如下: package com.FilterTest.Filter; import java.io.IOException; import javax.servlet.Filter; impo ...
-
org.springframework.expression.spel.SpelEvaluationException: EL1004E: Method call: Method service() cannot be found on com.my.blog.springboot.thymeleaf.util.MethodTest type
前言 本文中提到的解决方案,源码地址在:springboot-thymeleaf,希望可以帮你解决问题. 至于为什么已经写了一篇文章thymeleaf模板引擎调用java类中的方法,又多此一举的单独整 ...
随机推荐
-
hibernate----component-entity (人-地址-学校)
package com.ij34.dao; import javax.persistence.*; @Entity @Table(name="school_inf") public ...
-
【HDOJ】2405 Marbles in Three Baskets
BFS+状态压缩. /* 2405 */ #include <iostream> #include <queue> #include <cstdio> #inclu ...
-
C#总结(2)
有输出,当然有输入.这样才会有人机交互. using System; using System.Collections.Generic; using System.Linq; using System ...
-
Java并发编程实践(读书笔记) 任务执行(未完)
任务的定义 大多数并发程序都是围绕任务进行管理的.任务就是抽象和离散的工作单元. 任务的执行策略 1.顺序的执行任务 这种策略的特点是一般只有按顺序处理到来的任务.一次只能处理一个任务,后来其它任 ...
-
rsync使用指南
考虑到服务器数据的安全,我考虑增加一台备份服务器,通过数据同步,达到较好的冗余. linux下有非常好的一个命令rsync可以实现差异备份,下面就说说它的用法:ubuntu缺省安装的安装中,rsync ...
-
JSP之项目路径问题(${pageContext.request.contextPath},<;%=request.getContextPath()%>;以及绝对路径获取)
本随笔这是作为一个记录使用,以备后查.项目完成之后本地部署OK,本地Linux部署OK,都可以正常的访问,可是当我把它部署到服务器上面的时候,首页可以正常访问,可是当发出请求的时候却报错误了,说找不到 ...
-
【学习】js学习笔记:数组(二)
二维数组 例子:矩形反转: <script> var arr=[[1,1,1,1,1],[2,2,2,2,2],[3,3,3,3,3],[4,4,4,4,4],[5,5,5,5,5]]; ...
-
Linux OpenGL 实践篇-6 光照
经典光照模型 经典光照模型通过单独计算光源成分得到综合光照效果,然后添加到物体表面特定点,这些成分包括:环境光.漫反射光.镜面光. 环境光:是指不是来特定方向的光,在经典光照模型中基本是个常量. 漫反 ...
-
spring mvc数据绑定与表单标签库
Book类为 package org.shaoxiu; public class Book { private String id; private String name; public Book( ...
-
对请求并发数做限制的通用RequestDecorator
使用场景 在开发中,我们可能会遇到一些对异步请求数做并发量限制的场景,比如说微信小程序的request并发最多为5个,又或者我们需要做一些批量处理的工作,可是我们又不想同时对服务器发出太多请求(可能会 ...