spring-web在version2.5.1的时候,在包org.springframework.web.context.support下加入了一个工具类叫SpringBeanAutowiringSupport,主要用来对Spring Web Application上下文的类提供@Autowired注入功能。
官方Doc讲的更清楚点:http://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/context/support/SpringBeanAutowiringSupport.html
具体来说,Servlet中本来不能使用@Autowired注入bean,解决办法是在Servlet的init(ServletConfig)方法中调用SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this),就可以直接使用@Autowired来
注入Web应用程序Context下的一些服务等Bean了。(见下例)
引用
方便的基类,用于在基于Spring的Web应用程序中构建的自动装配类。在当前Spring根Web应用程序上下文中针对Bean解析端点类中的@Autowired注释(由当前线程的上下文ClassLoader确定,它需要是Web应用程序的ClassLoader)。或者可以用作委托而不是基类。
例子:在Servlet中使用:
的Java代码
公共类 InitServlet 扩展 HttpServlet {
@Autowired
私人 服务A服务A;
public void init(ServletConfig config) 抛出 ServletException {
super .init(config);
SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this );
assertNotNull(“应该注入服务。” ,serviceA);
}
//省略了doGet(req,res),doPost(req,res);
}
2.例子:在Quartz Job中使用:
的Java代码
公共类 DumpJob 实现 Job {
@Autowired
私人 服务A服务A;
public void execute(JobExecutionContext context) 抛出 JobExecutionException {
SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this );
assertNotNull(“应该注入服务。” ,serviceA);
}
}
3. SpringBeanAutowiringSupport源码分析:
的Java代码
/ **
*处理给定目标对象的{@code @Autowired}注入,
*基于当前的Web应用程序上下文。
* <p>拟作为代表使用。
* @param定位要处理的目标对象
* @see org.springframework.web.context.ContextLoader#getCurrentWebApplicationContext()
* /
public static void processInjectionBasedOnCurrentContext(Object target){
Assert.notNull(target, “Target对象不能为null” );
WebApplicationContext cc = ContextLoader.getCurrentWebApplicationContext();
if (cc!= null ){
AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor();
bpp.setBeanFactory(cc.getAutowireCapableBeanFactory());
bpp.processInjection(目标);
}
其他 {
if (logger.isDebugEnabled()){
logger.debug(“当前WebApplicationContext不可用于处理” +
ClassUtils.getShortName(target.getClass())+ “:” +
“确保在Spring Web应用程序中构建此类。无需注入即可继续执行。” );
}
}
}
从方法第2行可以看出通过ContextLoader拿到当前的WebApplicationContext对象,再通过AutowiredAnnotationBeanPostProcessor类来解决当前传入的目标类的@Autowired注入能力。
(AutowiredAnnotationBeanPostProcessor在Spring2.5随着注释功能的扩展而增加的,我们平时用context namepace的标签<context:component-scan>时,Spring会默认生成注册AutowiredAnnotationBeanPostProcessor类来帮助解析@Autowired @Value @Inject等标签。)
4。使用另一个工具类WebApplicationContextUtils来获取服务Bean:
的Java代码
WebApplicationContext context = WebApplicationContextUtils.getWebApplicationContext(config.getServletContext());
ServiceA ServiceA = context.getBean(ServiceA .class );
当然这个方法更强大,因为直接拿到WebApplicationContext对象了!
5.补充WebApplicationContext相关:
对于Web项目,通常使用org.springframework.web.context.ContextLoaderListener,设置属性contextConfigLocation来生成
WebApplicationContext类图