解决spring懒加载以及@PostConstruct结合的坑

网友投稿 2190 2022-11-13

解决spring懒加载以及@PostConstruct结合的坑

解决spring懒加载以及@PostConstruct结合的坑

目录spring懒加载及@PostConstruct的坑下面是一个初始化数据的组件遗留问题 @PostConstruct注入不成功直接先说原因吧1.忽略ssm本身对注解是通过扫包才让注解有效的2.忽略@Service的注解3.注意扫包区间4.@PostCoustruct注解用于

spring懒加载及@PostConstruct的坑

举例说明:

下面是一个初始化数据的组件

@Component

public class InitData {

/**

* 初始化加载bean

*/

@PostConstruct

public void init() {

Map map = new HashMap();

for (int i=0;i<10;i++) {

map.put(i+"", i+"");

}

//模拟加载一些别单例模式bean的数据初始化

ErrorMsgUtil1.getInstance().setMap(map);

ErrorMsgUtil2.getInstance().setMap(map);

}

好了,如果你开启了spring的懒加载模式,而且 InitData这个bean只是被扫描而没有被注入,那么ErrorMsgUtil里的map永远是空的。

@PostConstruct实在bean初始化的时候被创建的,开启了懒加载显然如果InitData没有被用到那么就一直不执行了。

此坑已踩,小弟还是对spring理解不深,继续学习。

ps:如何开启spring的懒加载模式,在spring.xml中加上下面的代码中最后一句即可

xmlns:xsi="http://w3.org/2001/XMLSchema-instance" xmlns:p="http://springframework.org/schema/p"

xmlns:context="http://springframework.org/schema/context"

xmlns:mvc="http://springframework.org/schema/mvc" xmlns:tx="http://springframework.org/schema/tx"

xsi:schemaLocation="

http://springframework.org/schema/beans

http://springframework.org/schema/beans/spring-beans-3.0.xsd

http://springframework.org/schema/context

http://springframework.org/schQJEAcSMdema/context/spring-context-3.0.xsd

" default-lazy-init="true">

遗留问题 @PostConstruct注入不成功

前两天做了个纯java代码的rabbitMQ监听多个ip的客户端功能,由于用的不是配置方式的listener方式—博文中有这一节,无法自动启动。就用@PostConstruct来项目启动时运行监听mq,但是老遇到调用业务逻辑层方法时,注入不成功导致空指针异常。今天排查了一下,发现主要问题是框架扫包忽略了。

直接先说原因吧

1.忽略ssm本身对注解是通过扫包才让注解有效的

2.忽略@Service的注解

由于扫包是扫service层和action层(相当于service层),common工具层。所以在api层(相当于controller层)用@Service和不用注解都是错误的,都会导致注入失败。

3.注意扫包区间

出了这个范围@PostConstruct是无效的。应用在启动时是不会走带有这个注解的方法的。

4.@PostCoustruct注解用于

在依赖关系注入完成之后需要执行的方法上,以执行任何初始化。此方法所在的类必须放入服务之前调用。也就是该注解的类上不能随便注解:经验总结是能用@Service注解,不能用@Controller注解,否则启动不会走这个方法。这个类定位为服务层/业务层。而不是控制层(web层)

有了上面说的注意点。我重新在工具类包common包中写了个测试类。然后spring配置文件上扫包范围增加了这个common包。代码如下:com.zhanglf.common.cache.CommonCacheMap.java

package com.zhanglf.common.cache;

import javax.annotation.PostConstruct;

import javax.annotation.Resource;

import org.springframework.stereotype.Service;

import com.zlf.bo.StaffBo;

import com.zlf.service.IStaffService;

@Service("CommonCacheMap")

public class CommonCacheMap {

@Resource

private IStaffService staffService;

@PostConstruct

public void getOneStaff(){

StaffBo staffBo = staffService.selectByPrimaryKey("s01");

System.out.println(staffBo.getName());

}

}

结果是注入成功,运行结果如下:

这样@PostConstruct注入问题就解决了。

xmlns:xsi="http://w3.org/2001/XMLSchema-instance" xmlns:p="http://springframework.org/schema/p"

xmlns:context="http://springframework.org/schema/context"

xmlns:mvc="http://springframework.org/schema/mvc" xmlns:tx="http://springframework.org/schema/tx"

xsi:schemaLocation="

http://springframework.org/schema/beans

http://springframework.org/schema/beans/spring-beans-3.0.xsd

http://springframework.org/schema/context

http://springframework.org/schQJEAcSMdema/context/spring-context-3.0.xsd

" default-lazy-init="true">

遗留问题 @PostConstruct注入不成功

前两天做了个纯java代码的rabbitMQ监听多个ip的客户端功能,由于用的不是配置方式的listener方式—博文中有这一节,无法自动启动。就用@PostConstruct来项目启动时运行监听mq,但是老遇到调用业务逻辑层方法时,注入不成功导致空指针异常。今天排查了一下,发现主要问题是框架扫包忽略了。

直接先说原因吧

1.忽略ssm本身对注解是通过扫包才让注解有效的

2.忽略@Service的注解

由于扫包是扫service层和action层(相当于service层),common工具层。所以在api层(相当于controller层)用@Service和不用注解都是错误的,都会导致注入失败。

3.注意扫包区间

出了这个范围@PostConstruct是无效的。应用在启动时是不会走带有这个注解的方法的。

4.@PostCoustruct注解用于

在依赖关系注入完成之后需要执行的方法上,以执行任何初始化。此方法所在的类必须放入服务之前调用。也就是该注解的类上不能随便注解:经验总结是能用@Service注解,不能用@Controller注解,否则启动不会走这个方法。这个类定位为服务层/业务层。而不是控制层(web层)

有了上面说的注意点。我重新在工具类包common包中写了个测试类。然后spring配置文件上扫包范围增加了这个common包。代码如下:com.zhanglf.common.cache.CommonCacheMap.java

package com.zhanglf.common.cache;

import javax.annotation.PostConstruct;

import javax.annotation.Resource;

import org.springframework.stereotype.Service;

import com.zlf.bo.StaffBo;

import com.zlf.service.IStaffService;

@Service("CommonCacheMap")

public class CommonCacheMap {

@Resource

private IStaffService staffService;

@PostConstruct

public void getOneStaff(){

StaffBo staffBo = staffService.selectByPrimaryKey("s01");

System.out.println(staffBo.getName());

}

}

结果是注入成功,运行结果如下:

这样@PostConstruct注入问题就解决了。

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:软件测试面试题:详细的描述一个测试活动完整的过程?
下一篇:软件测试面试题:请详细介绍一下各种测试类型的含义?
相关文章

 发表评论

暂时没有评论,来抢沙发吧~