应用完全启动后, Spring执行自定义初始化
项目中做敏感词过滤,
因为前台ajax校验要走service ,而后台统一过滤器要走interceptor , 所以把检查器提到一个工具类(HeXieWordFinder)里
这个工具类理应缓存数据库中所有敏感词数据的list
可是直接初始化静态变量的话 spring会报出nullPointer (因为容器首先初始化个各类(static) 而后才是依赖注入)
研究了一下初始化过程 ,才想出在spring完全启动之后 这个时间点上手动初始化的办法
1.监听器
/** * spring初始化结束后,执行onApplicationEvent方法 * 此处初始化避免了初始化static时 bean还没注入的问题 * @author tao */ public class InstantiationTracingBeanPostProcessor implements ApplicationListener<ContextRefreshedEvent> { @Override public void onApplicationEvent(ContextRefreshedEvent event) { if(event.getApplicationContext().getParent() == null)//root applicationContext没有parent,保证是统一的context { //需要执行的逻辑代码,当spring容器初始化完成后就会执行该方法。 HeXieWordFinder h = new HeXieWordFinder(); h.initWords(heXieWordService); } } @Autowired private HeXieWordService heXieWordService;//这里注入不会有生存周期的问题 }
2.spring的xml里配个bean
<bean class="com.tdt.listener.InstantiationTracingBeanPostProcessor"/>
3.查找器(缓存list)
/** * 敏感词查找器 * @author tao */ @Component public class HeXieWordFinder { private static List<String> SensitiveWords = new ArrayList<String>();//禁用词 public HeXieWordFinder() { super(); } /* private static HeXieWordFinder singletonInstance;//单例 public static synchronized HeXieWordFinder getInstance()//线程安全 { if (singletonInstance == null) { singletonInstance = new HeXieWordFinder(); } return singletonInstance; } */ public void initWords(HeXieWordService heXieWordService) { synchronized(SensitiveWords) { //此处如果用@Autowired注入报nullPointer ,因为容器首先初始化个各类(static) 而后才是依赖注入 List<HeXieWord> wordList = heXieWordService.getAllHeXieWord(); if( null != wordList ) { for(int i=0,len=wordList.size();i<len;i++) { SensitiveWords.add(wordList.get(i).getWord()); } } } } public static boolean find(String value)//static { boolean res = false; if( null==value || 0==value.length()) { return res; } for(String regex : SensitiveWords) { Pattern p = Pattern.compile(regex);//正则表达式判断用户输入的内容是否存在 Matcher m = p.matcher(value); if(m.find()) { res = true; return res; } } return res; } }