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

 1 package com.wbf.bean;  
 2   
 3 import javax.annotation.PostConstruct;  
 4   
 5 import org.apache.log4j.Logger;  
 6 import org.springframework.stereotype.Service;  
 7   
 8 @Service("bean1")  
 9 public class Bean1 {  
10       
11     private static final Logger log = Logger.getLogger(Bean1.class);  
12       
13     public Bean1() {  
14         log.info(System.currentTimeMillis() + ": Bean1 Constructor");  
15     }  
16       
17     @PostConstruct  
18     public void test() {  
19         log.info(System.currentTimeMillis() + ": bean1-->test()");  
20         Bean2.uniqueInstance().test();  
21           
22     }  
23       
24     @PostConstruct  
25     public void print() {  
26         log.info(System.currentTimeMillis() + ": bean1-->print()");  
27     }  
28 }  

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

 1 package com.wbf.bean;  
 2   
 3 import org.apache.log4j.Logger;  
 4 import org.springframework.stereotype.Service;  
 5   
 6 @Service("bean3")  
 7 public class Bean3 {  
 8       
 9     private static final Logger log = Logger.getLogger(Bean3.class);  
10       
11     public Bean3() {  
12         log.info(System.currentTimeMillis() + ": Bean3 Construtor");  
13     }  
14       
15 }  

5. SpringTest.java

 1 package com.wbf.bean;  
 2   
 3 import org.junit.Test;  
 4 import org.springframework.context.ApplicationContext;  
 5 import org.springframework.context.support.ClassPathXmlApplicationContext;  
 6   
 7 public class SpringTest {  
 8       
 9     @Test  
10     public void test() {  
11         //加载/解析spring.xml, 得到BeanFactory, 实例化所有IOC容器中的Bean  
12         //在实例化每一个Bean之后,如果当前Bean包含@PostConstruct注解的方法则会马上执行该方法,之后才会去实例化其他的Bean  
13         //每一个Bean中可以有多个包含@PostConstruct注解的方法  
14         ApplicationContext ac = new ClassPathXmlApplicationContext(new String[]{"classpath:spring.xml"});  
15     }  
16       
17 }  

 运行结果:

[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

举个例子:

 1    public Class AAA{
 2         @Autowired
 3         private BBB b;
 4         
 5         public AAA() {
 6              System.out.println("此时b还未被注入: b = " + b);
 7         }
 8         @PostConstruct
 9         private void init () {
10              System.out.println("@PostConstruct将在依赖注入完成后被自动调用: b = " + b);
11         }
12     }
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值