new出來的線程類中無法使用@Autowired注入Bean

根本原因:

@Autowired注入Spring Bean,則當前類必須也是Spring Bean才能注入成功,不能用new xxx()來獲得對象,這種方式獲得的對象也無法使用@Autowired註解注入Bean。

因此,當我們在new一個線程之後,發現線程裏使用@Autowired注入的對象都是空的

解決方法:

1、使用一個類實現ApplicationContextAware接口

/**
 * Interface to be implemented by any object that wishes to be notified
 * of the {@link ApplicationContext} that it runs in.
 *
 * <p>Implementing this interface makes sense for example when an object
 * requires access to a set of collaborating beans. Note that configuration
 * via bean references is preferable to implementing this interface just
 * for bean lookup purposes.
 *
 * <p>This interface can also be implemented if an object needs access to file
 * resources, i.e. wants to call {@code getResource}, wants to publish
 * an application event, or requires access to the MessageSource. However,
 * it is preferable to implement the more specific {@link ResourceLoaderAware},
 * {@link ApplicationEventPublisherAware} or {@link MessageSourceAware} interface
 * in such a specific scenario.
 *
 * <p>Note that file resource dependencies can also be exposed as bean properties
 * of type {@link org.springframework.core.io.Resource}, populated via Strings
 * with automatic type conversion by the bean factory. This removes the need
 * for implementing any callback interface just for the purpose of accessing
 * a specific file resource.
 *
 * <p>{@link org.springframework.context.support.ApplicationObjectSupport} is a
 * convenience base class for application objects, implementing this interface.
 *
 * <p>For a list of all bean lifecycle methods, see the
 * {@link org.springframework.beans.factory.BeanFactory BeanFactory javadocs}.
 *
 * @author Rod Johnson
 * @author Juergen Hoeller
 * @author Chris Beams
 * @see ResourceLoaderAware
 * @see ApplicationEventPublisherAware
 * @see MessageSourceAware
 * @see org.springframework.context.support.ApplicationObjectSupport
 * @see org.springframework.beans.factory.BeanFactoryAware
 */
public interface ApplicationContextAware extends Aware {

	/**
	 * Set the ApplicationContext that this object runs in.
	 * Normally this call will be used to initialize the object.
	 * <p>Invoked after population of normal bean properties but before an init callback such
	 * as {@link org.springframework.beans.factory.InitializingBean#afterPropertiesSet()}
	 * or a custom init-method. Invoked after {@link ResourceLoaderAware#setResourceLoader},
	 * {@link ApplicationEventPublisherAware#setApplicationEventPublisher} and
	 * {@link MessageSourceAware}, if applicable.
	 * @param applicationContext the ApplicationContext object to be used by this object
	 * @throws ApplicationContextException in case of context initialization errors
	 * @throws BeansException if thrown by application context methods
	 * @see org.springframework.beans.factory.BeanInitializationException
	 */
	void setApplicationContext(ApplicationContext applicationContext) throws BeansException;

}

Spring容器啓動的時候,會把上下文環境對象調用實現ApplicationContextAware接口類中的setApplicationContext方法。

我們在ApplicationContextAware的實現類中,就可以通過這個上下文環境對象得到Spring容器中的Bean。

@Service
public class ManageSpringBeans implements ApplicationContextAware {
	private static ApplicationContext context;

	public static <T> T getBean(final Class<T> requiredType) {
		return context.getBean(requiredType);
	}

	public static <T> T getBean(final String beanName) {
		@SuppressWarnings("unchecked")
		final T bean = (T) context.getBean(beanName);
		return bean;
	}

	public static <T> Map<String, T> getBeans(final Class<T> requiredType) {
		return context.getBeansOfType(requiredType);
	}

	public static Map<String, Object> getBeansWithAnnotation(final Class<? extends Annotation> annotationType) {
		return context.getBeansWithAnnotation(annotationType);
	}

	@Override
	public void setApplicationContext(final ApplicationContext applicationContext) {
		context = applicationContext;
	}
}

之後就可以在需要某一個bean的時候使用該類的ManageSpringBeans.getBean(beanName)來獲取Spring的bean對象了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章