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 ...
随机推荐
- Codeforces 877F Ann and Books 莫队
转换成前缀和, 预处理一下然后莫队. #include<bits/stdc++.h> #define LL long long #define fi first #define se se ...
- gitlab之五: gitlab之webhook
webhook(网络钩子),一般与jenkins联合使用,gitlab的某个项目的代码更新了后就触发 webhook中配置的 url ,这个url一般是某一个jienkins中某一个job的url.即 ...
- VM VirtualBox – Cannot register the hard disk
第一打开VirtualBox 文件夹,在地址栏输入cmd 第二, 仔细读下面 VBoxManage.exe internalcommands sethduuid "F:\Virtual ...
- 修改注册表.exe的文件目录
文件打开方式不能选择默认打开文件 cmd >regedit 以sublime_text为例 HKEY_CLASSES_ROOT/Applications/sublime_text.exe/she ...
- UOJ#23. 【UR #1】跳蚤国王下江南 仙人掌 Tarjan 点双 圆方树 点分治 多项式 FFT
原文链接https://www.cnblogs.com/zhouzhendong/p/UOJ23.html 题目传送门 - UOJ#23 题意 给定一个有 n 个节点的仙人掌(可能有重边). 对于所有 ...
- Practice| 类型转换| 逻辑运算
类型转换 class Pratice1{ public static void main(String[] args){ int a = 3; //float f = 4.5;//TypeChange ...
- php(apache)切换版本
php(apache)切换版本 1.brew link php@7.1 2.上两行写入 ~/.bash_profile文件 3.source ~/.bash_profile 4.sudo vi /et ...
- js根据银行卡号进行判断属于哪个银行并返回银行卡类型
在做绑定银行卡,输入银行卡的时候,产品有这么一个需求,需要用户输入银行卡号的时候,显示对应的银行卡名称及简称.于是苦苦寻觅,终于找到了支付宝的开放API,银行卡校验接口 https://ccdcapi ...
- NN:神经网络实现识别手写的1~9的10个数字—Jason niu
import numpy as np from sklearn.datasets import load_digits from sklearn.metrics import confusion_ma ...
- B - Glider Gym - 101911B(二分)
output standard output A plane is flying at a constant height of hh meters above the ground surface. ...