---恢复内容开始---

今天看了前辈们写的代码用到了afterPropertiesSet()的方法,就好好整理了spring的bean加载

1. InitializingBean.afterPropertiesSet()

Spring中InitializingBean接口类为bean提供了定义初始化方法的方式,它仅仅包含一个方法:afterPropertiesSet()。
Bean实现这个接口,在afterPropertiesSet()中编写初始化代码:

  1 public class AlarmQueue<T> implements InitializingBean, DisposableBean, Component {
  2     private static final CLogger logger = Utils.getLogger(AlarmQueue.class);
  3
  4     @Autowired
  5     ThreadFacade thf;
  6     @Autowired
  7     private CloudBus bus;
  8
  9     private RedisTemplate redisTemplate;
 10     private String key;
 11     private RedisConnectionFactory factory;
 12     private RedisConnection connection;
 13     private Lock lock = new ReentrantLock();//基于底层IO阻塞考虑
 14     private Thread alarmThread;
 15     private boolean isInit = true;
 16     private boolean isClosed;
 17
 18     public void setRedisTemplate(RedisTemplate redisTemplate) {
 19         this.redisTemplate = redisTemplate;
 20     }
 21
 22     public void setKey(String key) {
 23         this.key = key;
 24     }
 25
 26     @Override
 27     public void afterPropertiesSet() throws Exception {//
 28         logger.info("============== afterPropertiesSet =================");
 29         factory = redisTemplate.getConnectionFactory();
 30         connection = RedisConnectionUtils.getConnection(factory);
 31         alarmThread = new AlarmThread();
 32         alarmThread.setDaemon(true);
 33         alarmThread.start();
 34     }
 35
 36     class AlarmThread extends Thread {
 37         @Override
 38         public void run() {
 39             try {
 40                 if (isInit) {
 41                     Thread.sleep(30000);
 42                     isInit = false;
 43                 }
 44
 45                 logger.info("============== AlarmThread Start =================");
 46                 while (true) {
 47                     T value = takeFromTail(0);
 48                     if (value != null) {
 49                         try {
 50                             // listener.onMessage(value);
 51                             HandleAlarmMsg amsg = new HandleAlarmMsg();
 52                             amsg.setAlarmValue(value.toString());
 53                             bus.makeTargetServiceIdByResourceUuid(amsg, AlarmConstant.SERVICE_ID_ALARM_LOG, Platform.getUuid());
 54                             bus.send(amsg);
 55                         } catch (Exception e) {
 56                             logger.error(String.format("fail to handle alarm!Alarm content: %s, Error: %s", value.toString(), e.getMessage()));
 57                         }
 58                     }
 59                 }
 60             } catch (InterruptedException e) {
 61                 throw new RuntimeException(String.format("Alarm thread InterruptedException! Error: %s", e.getMessage()));
 62             }
 63         }
 64     }
 65
 66     public T takeFromTail(int timeout) throws InterruptedException {
 67         lock.lockInterruptibly();
 68         try {
 69             List<byte[]> results = connection.bRPop(timeout, key.getBytes());
 70             if (CollectionUtils.isEmpty(results)) {
 71                 return null;
 72             }
 73             return (T) redisTemplate.getValueSerializer().deserialize(results.get(1));
 74         } catch (Exception e) {
 75             throw new RuntimeException(String.format("fail to take value from queue %s! Error: ", this.key, e.getMessage()));
 76         } finally {
 77             lock.unlock();
 78         }
 79     }
 80
 81     @Override
 82     public void destroy() throws Exception {
 83         if (isClosed) {
 84             return;
 85         }
 86         shutdown();
 87         RedisConnectionUtils.releaseConnection(connection, factory);
 88         isClosed = true;
 89     }
 90
 91     private void shutdown() {
 92         AlarmThread.interrupted();
 93     }
 94
 95     @Override
 96     public boolean start() {
 97         return true;
 98     }
 99
100     @Override
101     public boolean stop() {
102         return true;
103     }
104 }

在xml配置文件中并不需要对bean进行特殊的配置,Spring在在配置文件完成该bean的所有赋值后,会检查该bean是否实现了InitializingBean接口,如果实现就调用bean的afterPropertiesSet方法。

2. init-method配置

Spring虽然可以通过InitializingBean完成一个bean初始化后调用这个bean自定义方法,但是这种方式要求bean实现InitializingBean接口。一但bean实现了InitializingBean接口,那么这个bean的代码就和Spring耦合到一起了。可以使用Spring提供的init-method的功能来执行一个bean自定义的初始化方法。
以下代码中,类MonitorKafka不实现任何Spring的接口,定义一个没有参数的方法monitorKafkaMsg()。

 1 public class AlarmLogManagerImpl extends AbstractService implements ApiMessageInterceptor {
 2
 3     private static final CLogger logger = Utils.getLogger(AlarmLogManagerImpl.class);
 4     @Autowired
 5     private CloudBus bus;
 6     @Autowired
 7     private DatabaseFacade dbf;
 8     @Autowired
 9     private ThreadFacade thf;
10     @Autowired
11     private RESTFacade restf;
12     @Autowired
13     private SmsService smsService;
14     @Autowired
15     private MailService mailService;
16
17   ....
18 }

<bean id="AlarmLogManager" class="com.syscxp.alarm.log.AlarmLogManagerImpl"init-method="AlarmLogManager" destroy-method="destroy"> .... 
</bean>

注:destroy-method是该bean销毁前调用指定的方法。
init-method配置中的monitorKafkaMsg()方法将会在该bean初始化完成后被调用,Spring要求init-method是一个无参数的方法,否则会抛出异常,Spring将中止这个Bean的后续处理,并且抛出一个 org.springframework.beans.factory.BeanCreationException异常。

总结:
1. InitializingBean和init-method可以一起使用,Spring会先处理InitializingBean再处理init-method。init-method是通过反射执行的,而afterPropertiesSet是直接执行的,所以 afterPropertiesSet的执行效率比init-method要高,不过init-method消除了bean对Spring依赖,推荐使用init-method。
2. 如果一个bean被定义为非单例的,那么afterPropertiesSet和init-method在bean的每一个实例被创建时都会执行。单例bean的afterPropertiesSet和init-method只在bean第一次被实例时调用一次。一般情况下afterPropertiesSet和init-method都应用在单例的bean上。
3. @PostConstruct和@PreDestory可以通过在类方法上注解方式实现类似的功能。

转载于:https://www.cnblogs.com/zqyanywn/p/9019911.html

spring中afterPropertiesSet方法与init-method配置描述相关推荐

  1. Spring中RedisTemplate方法中,redis相关操作笔记。[redis生成指定长度自增批次号,删除、设置过期时间等]

    Spring中RedisTemplate方法中,redis相关操作笔记. redis获取自增批次号 // opsForValue()生成long UUID = redisTemplate.opsFor ...

  2. Spring中ApplicationContext加载机制和配置初始化

    转自:http://liuwei1578.blog.163.com/blog/static/495803642007116111923195/ Spring中ApplicationContext加载机 ...

  3. Spring中@Value注解获取不到配置值

    @Value注解必须要在spring的bean中才能使用,不能自己new一个对象调用 产生原因: 在SpringBoot中使用@Value只能给普通变量赋值,不能给静态变量赋值 解决方法: 给静态变量 ...

  4. Java中Spring中的方法加上try catch后事务管理器失效无法回滚的情况

    beab.xml配置 <bean id="dataSource" class="org.springframework.jdbc.datasource.Driver ...

  5. 详解Spring中getBean()方法

    我们日常会经常使用getBean()方法从spring容器中获取我们需要的bean.那么,getBean()方法是怎么一步步完成从spring容器中获取bean的呢? 下面我们就通过源码分析一下. 一 ...

  6. Java中introduce方法,Introduce Foreign Method (引入外加函数)

    Summary: 你需要为提供服务的类增加一个函数.但你无法修改这个类.在客户类中建立一个函数,并以第一参数形式传入一个服务类实例. Motivation: 你正在使用一个类,它提供了所有需要的服务, ...

  7. Spring中getBean方法

    Spring源码阅读 : package com.example.riskm.core.common;import org.apache.commons.lang3.StringUtils; impo ...

  8. spring datasource oracle,spring中2种oracle数据源的配置

    value="${proxool.maxConnCount}" /> value="${proxool.minConnCount}" /> valu ...

  9. Spring中Quartz的最精简的配置

    为什么80%的码农都做不了架构师?>>>    Cron表达式(cronExpression)参见: http://www.bejson.com/cronCreator/index. ...

  10. spring中使用scala的maven打包配置

    <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://mave ...

最新文章

  1. 图像处理和图像识别中常用的matlab函数
  2. CentOS 7最小安装之后应该尽快做好的几件事情
  3. Java笔记14:泛型初探
  4. 企业高层对IT部门的需求
  5. 嵌入式 Linux 入门(四、Linux 下的编辑器 — 让人爱恨交加的 vi )
  6. 软件开发学什么编程语言好
  7. 基本流水线与记分牌算法和Tomasulo算法
  8. LPMS-CU2 IMU在 Nvidia Xavier安装配置
  9. html5 video标签实现手机端视频播放全屏显示
  10. python关于列表去重和删除的方法
  11. 使用七牛云上传图片时出现Network error during preQuery和运行时出现okhttp的问题
  12. 为什么你们说好的程序在我的海思开发板上就是不行呢,难道真的是人品有问题
  13. java使用三目运算符来判断成绩
  14. Android shortcut的使用及源码分析
  15. Nacos 2.1.0 正式发布!堪称最强!
  16. 51Nod——T 1631 小鲨鱼在51nod小学
  17. SecureCRT$SecureFX的安装方法
  18. java中jcl,spring-jcl 日志源码分析
  19. simulink搭建永磁同步电机
  20. 常见DOS命令集合与文件路径

热门文章

  1. 【Filter】基础知识
  2. 三、Linux常用命令——权限管理命令
  3. IntelliJ IDEA上创建Maven Spring MVC项目
  4. LayaAir 屏幕适配-分辨率、对齐模式
  5. Java 序列化漏洞多到修不完
  6. 阶段5 3.微服务项目【学成在线】_day02 CMS前端开发_09-webpack研究-webpack介绍
  7. 利用VS自带发布功能实现web项目快速部署
  8. docker-compose.yml(2)
  9. Vue2.0 的漫长学习ing-2-1
  10. 第二阶段冲刺(第十天)