spring注解之@PostConstruct在项目启动时执行指定方法
一、注解解释
Spring的@PostConstruct注解在方法上,表示此方法是在Spring实例化该Bean之后马上执行此方法,之后才会去实例化其他Bean,并且一个Bean中@PostConstruct注解的方法可以有多个。
二、示例代码
1. spring配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
"> <!-- 引入属性文件 -->
<context:property-placeholder location="classpath:config.properties" /> <!-- 自动扫描dao和service包(自动注入) -->
<context:component-scan base-package="com.wbf.bean" /> </beans>
2. Bean1.java
package com.wbf.bean; import javax.annotation.PostConstruct; import org.apache.log4j.Logger;
import org.springframework.stereotype.Service; @Service("bean1")
public class Bean1 { private static final Logger log = Logger.getLogger(Bean1.class); public Bean1() {
log.info(System.currentTimeMillis() + ": Bean1 Constructor");
} @PostConstruct
public void test() {
log.info(System.currentTimeMillis() + ": bean1-->test()");
Bean2.uniqueInstance().test(); } @PostConstruct
public void print() {
log.info(System.currentTimeMillis() + ": bean1-->print()");
}
}
3. Bean2.java
package com.wbf.bean;
import org.apache.log4j.Logger;
public class Bean2 {
private static final Logger log = Logger.getLogger(Bean2.class);
private static Bean2 instance = uniqueInstance();
public static Bean2 uniqueInstance() {
if (instance == null)
instance = new Bean2();
return instance;
}
public Bean2() {
log.info(System.currentTimeMillis() + ": Bean2 Construtor");
}
public void test() {
log.info(System.currentTimeMillis() + ": bean2-->test()");
}
}
4. Bean3.java
package com.wbf.bean; import org.apache.log4j.Logger;
import org.springframework.stereotype.Service; @Service("bean3")
public class Bean3 { private static final Logger log = Logger.getLogger(Bean3.class); public Bean3() {
log.info(System.currentTimeMillis() + ": Bean3 Construtor");
} }
5. SpringTest.java
package com.wbf.bean; import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; public class SpringTest { @Test
public void test() {
//加载/解析spring.xml, 得到BeanFactory, 实例化所有IOC容器中的Bean
//在实例化每一个Bean之后,如果当前Bean包含@PostConstruct注解的方法则会马上执行该方法,之后才会去实例化其他的Bean
//每一个Bean中可以有多个包含@PostConstruct注解的方法
ApplicationContext ac = new ClassPathXmlApplicationContext(new String[]{"classpath:spring.xml"});
} }
运行结果:
[org.springframework.context.support.ClassPathXmlApplicationContext]Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@b0f2b2: startup date [Thu Jun 11 11:51:17 CST 2015]; root of context hierarchy
[org.springframework.beans.factory.xml.XmlBeanDefinitionReader]Loading XML bean definitions from class path resource [spring.xml]
[org.springframework.beans.factory.config.PropertyPlaceholderConfigurer]Loading properties file from class path resource [config.properties]
[org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor]JSR-330 'javax.inject.Inject' annotation found and supported for autowiring
[org.springframework.beans.factory.support.DefaultListableBeanFactory]Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@1b8dc93: defining beans [org.springframework.beans.factory.config.PropertyPlaceholderConfigurer#0,bean1,bean3,org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.context.annotation.internalPersistenceAnnotationProcessor,org.springframework.context.annotation.ConfigurationClassPostProcessor.importAwareProcessor]; root of factory hierarchy
[com.wbf.bean.Bean1]1433994678340: Bean1 Constructor
[com.wbf.bean.Bean1]1433994678347: bean1-->print()
[com.wbf.bean.Bean1]1433994678347: bean1-->test()
[com.wbf.bean.Bean2]1433994678348: Bean2 Construtor
[com.wbf.bean.Bean3]1433994678348: Bean3 Construtor
从运行结果可以看出Spring在实例化Bean1之后马上执行了它的@PostConstruct注解的方法print()和test(),之后才去实例化Bean3。其中Bean2没有被Spring IOC容器管理。
三、补充说明
1.@PostConstruct说明
被@PostConstruct修饰的方法会在服务器加载Servlet(bean)的时候运行,并且只会被服务器调用一次,类似于Serclet的inti()方法。被@PostConstruct修饰的方法会在构造函数之后,init()方法之前运行。
2.@PreDestroy说明
被@PreDestroy修饰的方法会在服务器卸载Servlet(bean)的时候运行,并且只会被服务器调用一次,类似于Servlet的destroy()方法。被@PreDestroy修饰的方法会在destroy()方法之后运行,在Servlet被彻底卸载之前

另外,spring中Constructor、@Autowired、@PostConstruct的顺序
其实从依赖注入的字面意思就可以知道,要将对象p注入到对象a,那么首先就必须得生成对象a和对象p,才能执行注入。所以,如果一个类A中有个成员变量p被@Autowried注解,那么@Autowired注入是发生在A的构造方法执行完之后的。
如果想在生成对象时完成某些初始化操作,而偏偏这些初始化操作又依赖于依赖注入,那么久无法在构造函数中实现。为此,可以使用@PostConstruct注解一个方法来完成初始化,@PostConstruct注解的方法将会在依赖注入完成后被自动调用。
Constructor >> @Autowired >> @PostConstruct
举个例子:
public Class AAA{
@Autowired
private BBB b;
public AAA() {
System.out.println("此时b还未被注入: b = " + b);
}
@PostConstruct
private void init () {
System.out.println("@PostConstruct将在依赖注入完成后被自动调用: b = " + b);
}
}
spring注解之@PostConstruct在项目启动时执行指定方法的更多相关文章
- Java项目启动时执行指定方法的几种方式
很多时候我们都会碰到需要在程序启动时去执行的方法,比如说去读取某个配置,预加载缓存,定时任务的初始化等.这里给出几种解决方案供大家参考. 1. 使用@PostConstruct注解 这个注解呢,可以在 ...
- java项目启动时执行指定方法
想到的就是监听步骤如下: 1.配置web.xml <listener> <listener-class>com.listener.InitListener</listen ...
- 在web项目启动时执行某个方法
在web项目中有很多时候需要在项目启动时就执行一些方法,而且只需要执行一次,比如:加载解析自定义的配置文件.初始化数据库信息等等,在项目启动时就直接执行一些方法,可以减少很多繁琐的操作. 在工作中遇到 ...
- Spring Boot学习--项目启动时执行指定service的指定方法
Springboot给我们提供了两种“开机启动”某些方法的方式:ApplicationRunner和CommandLineRunner. 这两种方法提供的目的是为了满足,在项目启动的时候立刻执行某些方 ...
- Spring Boot学习--项目启动时执行特定方法
Springboot给我们提供了两种"开机启动"某些方法的方式:ApplicationRunner和CommandLineRunner. 这两种方法提供的目的是为了满足,在项目启动 ...
- Spring项目启动时执行初始化方法
一.applicationContext.xml配置bean <bean id="sensitiveWordInitUtil" class ="com.hx.daz ...
- spring boot 项目在启动时执行指定sql文件
参考博客: https://www.jianshu.com/p/88125f1cf91c 1. 启动时执行 当有在项目启动时先执行指定的sql语句的需求时,可以在resources文件夹下添加需要执行 ...
- Spring在Web容器启动时执行初始化方法
需求:在tomcat启动时开启一个定时任务. 想法:容器启动时执行方法,最容易想到的就是servlet中可以配置load-on-startup,设置一个正整数也就可以随容器一起启动. 问题:上面的方法 ...
- SpringBoot项目启动时执行初始化操作
SpringBooot中的CommandLineRunner接口会在所有Spring Beans初始化之后,SpringApplication.run()之前执行. 1.添加pom引用 <?xm ...
随机推荐
- sparkStreaming消费kafka-1.0.1方式:direct方式(存储offset到zookeeper)
版本声明: kafka:1.0.1 spark:2.1.0 注意:在使用过程中可能会出现servlet版本不兼容的问题,因此在导入maven的pom文件的时候,需要做适当的排除操作 <?xml ...
- 065 updateStateByKey的函数API
一:使用场景 1.应用场景 数据的累加 一段时间内的数据的累加 2.说明 每个批次都输出自己批次的数据, 这个时候,可以使用这个API,使得他们之间产生联系. 3.说明2 在累加器的时候,起到的效果和 ...
- Raspberry Camera详解+picamera库+Opencv控制
使用树莓派的摄像头,将树莓派自身提供的picamera的API数据转换为Python Oencv可用图像数据: # import the necessary packages from picamer ...
- Java中的不同遍历方式
已知一个Person类: public class Person implements Comparable<Person>{ String name; String id; public ...
- Remmarguts' Date POJ - 2449 (A*搜索|k短路)
"Good man never makes girls wait or breaks an appointment!" said the mandarin duck father. ...
- 网络编程-线程-3、通过继承Thread类创建线程
知识点:之前第一节介绍创建线程的方法是:通过threading.Thread(target=函数名不要加括号)创建一个对象,通过对象调用start方法创建并启动线程: ...
- 总结mysql的三种外键约束方式
如果表A的主关键字是表B中的字段,则该字段称为表B的外键,表A称为主表,表B称为从表.外键是用来实现参照完整性的,不同的外键约束方式将可以使两张表紧密的结合起来,特别是修改或者删除的级联操作将使得日常 ...
- Elasticsearch 基于 URL 的搜索请求
背景 Elasticsearch 不像关系型数据库,没有简易的 SQL 用来查询数据,只能通过调用 RESTful API 实现查询.大体上查询分为两种,基于 URL 的和基于请求主体的.基于 URL ...
- 在Java中,关于.Class()与.getCalss与.getClass().getName()的区别
** * Java反射 *所谓反射,可以理解为在运行时期获取对象类型信息的操作. *传统的编程方法要求程序员在编译阶段决定使用的类型,但是在反射的帮助下, *编程人员可以动态获取这些信息,从而编写更加 ...
- sudo passwd root输入普通用户密码后显示用户不再sudoers文件中
在写上一篇VirtualBox创建共享文件夹的时候,在运行下图授权时,root密码一直输入错误 然后我就在终端输入 su root,却发现需要密码,但我却不知道密码是什么 于是我就在终端输入如下命令, ...