详解java代码中init method和destroy method的三种使用方式

 更新时间:2020年03月25日 09:12:55   作者:涂宗勋  
这篇文章主要介绍了详解java代码中init method和destroy method的三种使用方式,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

在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方法中的内容。

例子都是很简单的,而通过简单的例子对比可能能更进一步理解相关的知识,理解了才能在实际应用中更好的进行选择和集成。

到此这篇关于详解java代码中init method和destroy method的三种使用方式的文章就介绍到这了,更多相关java中init method和destroy method内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • SpringBoot跨系统单点登陆的实现方法

    SpringBoot跨系统单点登陆的实现方法

    这篇文章主要介绍了SpringBoot跨系统单点登陆的实现方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-08-08
  • Mybatis自定义SQL的关系映射、分页、排序功能的实现

    Mybatis自定义SQL的关系映射、分页、排序功能的实现

    这篇文章主要介绍了Mybatis自定义SQL的关系映射、分页、排序功能的实现,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-01-01
  • Java实现Redis分布式锁的三种方案汇总

    Java实现Redis分布式锁的三种方案汇总

    setnx、Redisson、RedLock 都可以实现分布式锁,从易到难得排序为:setnx < Redisson < RedLock,本文为大家整理了三种方法的实现,希望对大家有所帮助
    2023-11-11
  • 关于spring aop两种代理混用的问题

    关于spring aop两种代理混用的问题

    这篇文章主要介绍了关于spring aop两种代理混用的问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-11-11
  • Java8中Stream API的peek()方法详解及需要注意的坑

    Java8中Stream API的peek()方法详解及需要注意的坑

    这篇文章主要给大家介绍了关于Java8中Stream API的peek()方法详解及需要注意的坑,Java 中的 peek 方法是 Java 8 中的 Stream API 中的一个方法,它属于中间操作,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2024-06-06
  • java8中Stream的使用示例教程

    java8中Stream的使用示例教程

    Stream是Java8的一大亮点,是对容器对象功能的增强,下面这篇文章主要给大家介绍了关于java8中Stream使用的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2018-10-10
  • Java中的线程ThreadLocal详细解析

    Java中的线程ThreadLocal详细解析

    这篇文章主要介绍了Java中的线程ThreadLocal详细解析,ThreadLocal是线程本地变量,存储在ThreadLocal里面的数据都是线程安全的,一般ThreadLocal适用的场景多是各个线程间没有变量共享需要的同步问题场景,需要的朋友可以参考下
    2023-10-10
  • IDEA新建springboot项目时未生成pom.xml文件的解决操作

    IDEA新建springboot项目时未生成pom.xml文件的解决操作

    这篇文章主要给大家介绍了关于IDEA新建springboot项目时未生成pom.xml文件的解决操作方法,文中通过实例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2023-02-02
  • 深入理解注解与自定义注解的一些概念

    深入理解注解与自定义注解的一些概念

    今天给大家带来的文章是注解的相关知识,本文围绕着注解与自定义注解的一些概念展开,文中详细介绍了这些知识,需要的朋友可以参考下
    2021-06-06
  • rocketmq的AclClientRPCHook权限控制使用技巧示例详解

    rocketmq的AclClientRPCHook权限控制使用技巧示例详解

    这篇文章主要为大家介绍了rocketmq的AclClientRPCHook使用技巧示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-08-08

最新评论