`
仁生之狼
  • 浏览: 42899 次
  • 性别: Icon_minigender_1
  • 来自: 苏州
社区版块
存档分类
最新评论

spring中xml配置与annotation注解混合

 
阅读更多

 spring的xml配置与annotation注解混合使用无法Autowired的问题

 

问题:

AppUserServiceImpl.java是通过@Service声明的bean,在xml配置文件中重新给AppUserServiceImpl.java配置一个别名“pap_appuser_service”。

普通类AppUserAPIImpl.java中,需要调用AppUserServiceImpl.java,但是运行的时候却报NullPointerException,说明没有注入进来。

java代码

 

public class AppUserAPIImpl implements AppUser {
	private static ApplicationContext context = ContextLoader.getCurrentWebApplicationContext();

	private IAppUserService service;

	public AppUserAPIImpl(String appCode, String userCode) {
		this.service = (IAppUserService) context.getBean("pap_appuser_service");
	}
}

@Service
public class AppUserServiceImpl implements IAppUserService {
	@Autowired
	private IUserService userService;	
}

 

配置

 

<bean id="pap_appuser_service" class="net.yhte.web.pap.user.service.impl.AppUserServiceImpl"/>

 

问题查找:

1. 查找网上资源,未果.

2. 果断debug,跟踪源码.

       将断点定位到 org.springframework.context.support.AbstractRefreshableApplicationContext#loadBeanDefinitions ,该方法是加载bean的必经之路.跟踪发现,该方法共执行两次,生成了两个不同的 org.springframework.beans.factory.support.DefaultListableBeanFactory, 并且后者的parentBeanFactory为前者,根据原设计是后者可以调用前者的bean 并完成注入.

      现在报NullPointerException,很明显是"父调用子",所以肯定拿不到.在打印的log中进行了佐证.

      在debug中发现,两次执行分别来自不同的beans资源文件: spring-servlet.xml 和 pap-service.xml, 按key查找,很容易找到了配置信息如下.

<context-param>
	<param-name>contextConfigLocation</param-name>
	<param-value>
		/WEB-INF/config/applicationContext.xml,
		/WEB-INF/config/application-*.xml,
		/WEB-INF/config/pap/pap-*.xml
	</param-value> 
</context-param>
<servlet>
	<servlet-name>monitor</servlet-name>
	<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
	<init-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>/WEB-INF/spring-servlet.xml</param-value>
	</init-param>
</servlet>
 

既然,两次加载,并且加载了不同的beans,虽然有父子的层级关系,但是限制多多. 那么就尝试合二为一.

    在test中,发现因为修改了spring默认加载的文件名,所以删除任何一个配置都不能正确运行.那么就全部设置成一样的吧. test success......

解决方案:

方案一. 将配置文件路径合并, 分别指定给不同配置.

<context-param>
	<param-name>contextConfigLocation</param-name>
	<param-value>
		/WEB-INF/spring-servlet.xml,
		/WEB-INF/config/applicationContext.xml,
		/WEB-INF/config/application-*.xml,
		/WEB-INF/config/pap/pap-*.xml
	</param-value> 
</context-param>
<servlet>
	<servlet-name>monitor</servlet-name>
	<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
	<init-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>
			/WEB-INF/spring-servlet.xml,
			/WEB-INF/config/applicationContext.xml,
			/WEB-INF/config/application-*.xml,
			/WEB-INF/config/pap/pap-*.xml
		</param-value>
	</init-param>
</servlet>

 

方案二. 原有配置不变,合理规划Bean的定义及合理使用.

在方案一中, 使用的简单,粗暴的解决办法. 没有考虑到spring的设计思想. 既然有ioc容器的父子级划分,那么在使用的时候,一定会有用的.

         在使用annotation定义bean 的时候,是需要增加如下代码,对使用何种注解的类才管理到ioc容器中.

<context:component-scan base-package="net.yhte.web.pap">  
   <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller" />  
   <context:include-filter type="annotation" expression="org.springframework.stereotype.Repository" />  
   <context:include-filter type="annotation" expression="org.springframework.stereotype.Service" />  
   <context:include-filter type="annotation" expression="org.springframework.stereotype.Component" />  
</context:component-scan>
 

上述提到, 在 spring web的使用中, 会加载两个ioc容器,

          1. 一个是contextConfigLocation定义,用来启动spring核心框架的. 所以在该步骤中,应加载应用中的基础服务信息的bean,如 dao,Service 等等.

          2. 另外一个ioc容器是web加载的容器, 那么只需加载Controller相关的bean.

        因为在spring ioc的 DefaultListableBeanFactory类是支持父子关系,

            1. 子容器是可以访问到父容器中的bean,

            2. 然而父容器访问不了子容器的bean,

        这就保证了, Controller可以访问 Service等, 但是Service 访问不了web层的bean, 这样就将职责分开了.所以修改的配置如下:

spring-servlet.xml
<context:component-scan base-package="net.yhte.web.pap">  
	<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller" />  
</context:component-scan>

pap-service.xml
<context:component-scan base-package="net.yhte.web.pap">  
	<context:include-filter type="annotation" expression="org.springframework.stereotype.Repository" />  
	<context:include-filter type="annotation" expression="org.springframework.stereotype.Service" />  
	<context:include-filter type="annotation" expression="org.springframework.stereotype.Component" />  
</context:component-scan>
<bean id="pap_appuser_service" class="net.yhte.web.pap.user.service.impl.AppUserServiceImpl"/>
 在开发定义bean的时候, 也需要注意,把bean定义到哪一层级.
分享到:
评论

相关推荐

    spring 使用annotation替代xml配置实例

    spring 使用annotation替代xml配置实例

    Spring注释 注入方式源码示例,Annotation

    凡带有@Component,@Controller,@Service,@Repository 标志的等于告诉Spring这类将自动产生对象,而@Resource则等于XML配置中的ref,告诉spring此处需要注入对象,所以用@Resource就有了ref的功效。 要用注解注入方式...

    csh框架+cxf+spring+hibernate+mysql 注解 annotation xml json

    csh框架+cxf+spring+hibernate+mysql 注解 annotation xml json, 参考了菠萝大象的文章,感谢。

    Spring总结(四)

    Spring个人总结,基于Annotation注解的方式开发,配置

    基于Struts2.18+Spring2.5+Hibernater3.3+Annotation注解开发的电子商务网站demo

    无聊之秋,做了个电子商务网站demo,巩固了一下对SSH三大开源框架的认识,比且融入了Annotation减少了xml配置文件的出现,本人只是个菜鸟,希望该资源能对一些朋友略有帮助!

    Spring3中配置DBCP,C3P0,Proxool,Bonecp数据源

    在Spring3中配置数据源,包括DBCP,C3P0,Proxool,Bonecp主要的数据源,里面包含这些数据源的jar文件和依赖文件及配置文件。。 如Bonecp目前听说是最快的数据源,速度是传统的c3p0的25倍, bonecp.properties文件: ...

    springweb3.0MVC注解(附实例)

    web.xml 中定义了一个名为 annomvc 的 Spring MVC 模块,按照 Spring MVC 的契约,需要在 WEB-INF/annomvc-servlet.xml 配置文件中定义 Spring MVC 模块的具体配置。annomvc-servlet.xml 的配置内容如下所示: &lt;?xml...

    25个经典的Spring面试问答

    如何用基于XML配置的方式配置Spring 如何用基于Java配置的方式配置Spring 怎样用注解的方式配置Spring 请解释Spring Bean的生命周期 Spring Bean的作用域之间有什么区别 什么是Spring inner beans Spring框架中的...

    spring+hibernate3.2+struts2.0 注解

    spring+hibernate3.2+struts2.0 注解,超级简化,省略hbm.xml、bean注入xml配置等,一切annotation

    Spring boot 示例 官方 Demo

    spring-boot-mybaits-xml:xml配置版本 spring-boot-mybatis-mulidatasource:springboot+mybatis多数据源最简解决方案 spring-boot-mybatis-annotation-mulidatasource:springboot+mybatis(注解版)多数据源最简...

    Spring Boot Examples

    spring-boot-mybaits-xml:xml配置版本 spring-boot-mybatis-mulidatasource:springboot+mybatis多数据源最简解决方案 spring-boot-mybatis-annotation-mulidatasource:springboot+mybatis(注解版)多数据源最...

    Spring Framewor开发手册

    2.2.4. Annotation(注解)驱动配置 2.2.5. 在classpath中自动搜索组件 2.3. 面向切面编程(AOP) 2.3.1. 更加简单的AOP XML配置 2.3.2. 对@AspectJ 切面的支持 2.3.3. 对bean命名pointcut( bean name pointcut element)...

    Spring JDBC与事务管理

    javaEE 实验三 Spring JDBC与事务管理, 一、实验目的 1、掌握Spring JDBC的配置; 2、掌握JdbcTemplae类中增删改查方法的使用; 3、了解Spring事务管理的3个核心接口; 4、了解Spring事务管理的两种方式; 5、掌握...

    Spring的学习笔记

    (一) Annotation注解方式配置事务管理 31 (二) Spring事务选项 35 (三) XML文件形式配置Spring事务管理 37 四、 HibernateTemplate 38 (一) HibernateTemplate 38 (二) HibernateDaoSupport 39 第十一课:Spring整合...

    Spring Boot 整合 Mybatis Annotation 注解的完整 Web 案例

    "}三、springboot-mybatis-annotation 工程配置详解1.pom 添加 Mybatis 依赖&lt;?xml version="1.0" encoding="UTF-8"?&gt;&lt;project xmlns=...

    spring_mvc注解入门

    随着Annotation的流行,一些主流框架都加入了对Annotation的支持。使用Annotation能够简化很多配置工作...本文将 Spring 2.5 新增的 Sping MVC 注解功能,介绍如何使用注解配置替换传统的基于 XML 的 Spring MVC 配置。

    spring2.5开发参考手册

    这些新特性包括:注解驱动的依赖性注入(annotation-driven dependency injection),使用注解而非XML元数据来自动侦测classpath上的Spring组件,注解对生命周期方法的支持,一个新的web控制器模型将请求映射到加...

    Spring中文帮助文档

    2.2.4. Annotation(注解)驱动配置 2.2.5. 在classpath中自动搜索组件 2.3. 面向切面编程(AOP) 2.3.1. 更加简单的AOP XML配置 2.3.2. 对@AspectJ 切面的支持 2.3.3. 对bean命名pointcut( bean name pointcut ...

    spring2.5.chm帮助文档(中文版)

    2.2.4. Annotation(注解)驱动配置 2.2.5. 在classpath中自动搜索组件 2.3. 面向切面编程(AOP) 2.3.1. 更加简单的AOP XML配置 2.3.2. 对@AspectJ 切面的支持 2.3.3. 对bean命名pointcut( bean name pointcut ...

Global site tag (gtag.js) - Google Analytics