The solution for services injected by spring cannot be instantiated in the thread.
Problem description
In Java Web applications, multithreading is used to process data. It is found that the Spring injection service always reports NullPointerException. Null Pointer is reported for both annotation declaration @ Resource and bean declaration configured in XML. Then look for the omnipotent network for help. Some say that spring does not detect the bean in the thread when the project is started because of thread security issues, injection is not supported, and spring bean declaration cycle,. It seems that you can only take the initiative to obtain the spring declaration cycle.
Solution:
(1) Actively instantiate objects (not recommended)
private TestService testService = new TestServiceImpl();
Every time this class is loaded, it will be re-created once, which will consume too much resources.
(2) set the thread as the internal class of the main program, or use the thread constructor to pass the bean over.
When the main program loads a web container, it can certainly inject Spring bean, so you can "share" Spring bean by placing the thread implementation class in the main program class, define the thread pool of the generated thread in the main program class, and the Implementation class of each thread as an internal class is also defined in the main program.
1 public class Test implements InitializingBean {2 3 @ Resource 4 private TestService testService 5 6 public void close () {7} 8 9 public void afterPropertiesSet () throws Exception {10 // use the constructor to pass the bean over 11 new Thread (testService); 12} 13}
(3) use static methods to directly retrieve the spring objects in the container
Write a SpringContextUtil class to implement ApplicationContextAware
1 package com. test. utils; 2 3 import java. util. locale; 4 import java. util. map; 5 6 import org. springframework. beans. beansException; 7 import org. springframework. context. applicationContext; 8 import org. springframework. context. applicationContextAware; 9 10 public class SpringContextUtil implements ApplicationContextAware {11 12 private static ApplicationContext applicationContext = null; 13 14 15 public void setApplicationContext (ApplicationContext context) throws BeansException {16 applicationContext context = context; 17} 18 19 20/** 21 * Get applicationContext object 22 * @ return23 */24 public static ApplicationContext getApplicationContext () {25 return applicationContext; 26} 27 28 29/** 30 * search for object 31 * @ param id32 * @ return33 */34 35 public static <T> T getBeanById (String id) based on bean id) {36 return (T) applicationContext. getBean (id ); 37} 38 39 40/** 41 * search for Objects Based on bean class 42 * @ param c43 * @ return44 */45 public static <T> T getBeanByClass (Class c) {46 return (T) applicationContext. getBean (c); 47} 48 49 50/** 51 * search for all objects (including subclasses) based on the bean class) 52 * @ param c53 * @ return54 */55 public static Map getBeansByClass (Class c) {56 return applicationContext. getBeansOfType (c); 57} 58 59 public static String getMessage (String key) {60 return applicationContext. getMessage (key, null, Locale. getDefault (); 61} 62 63}
Declare SpringContextUtil bean in applicationContext. xml
<bean id="springContextUtil" class="com.test.utils.SpringContextUtil"/>
Other services called by threads or threads can actively load beans and then use them directly (testService must be the bean configured in spring)
1 public void run() {2 TestService testService = (TestService ) SpringContextUtil.getBean("testService");3 testService.queryData();
4 }
(4) I can use BeanFactory to load beans on the Internet, but I haven't implemented it yet. The previous Code serves as a reference.
1 public class SpringBeanFactoryUtils implements BeanFactoryAware { 2 3 private static BeanFactory beanFactory = null; 4 private static SpringBeanFactoryUtils factoryUtils = null; 5 6 public void setBeanFactory(BeanFactory beanFactory) throws BeansException { 7 SpringBeanFactoryUtils.beanFactory = beanFactory; 8 } 9 public static BeanFactory getBeanFactory() { 10 return beanFactory; 11 } 12 public static SpringBeanFactoryUtils getInstance(){ 13 if(factoryUtils==null){ 14 //factoryUtils = (SpringBeanFactoryUtils)beanFactory.getBean("springBeanFactoryUtils"); 15 factoryUtils = new SpringBeanFactoryUtils(); 16 } 17 return factoryUtils; 18 } 19 public static Object getBean(String name){ 20 return beanFactory.getBean(name); 21 } 22 }