`
仁生之狼
  • 浏览: 45006 次
  • 性别: 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)与AOP中获取注解

    在Spring框架中,自定义注解(Annotation)和AOP(面向切面编程)的结合使用,极大地增强了代码的可读性和可维护性。本文将深入探讨如何在Spring中创建自定义注解以及如何在AOP中有效地获取并利用这些注解。 首先,...

    配置整合DWR3.0和Spring2.5使用annotation注解

    在本文中,我们将探讨如何将Direct Web Remoting (DWR) 3.0与Spring 2.5框架整合,并利用注解(Annotation)进行配置。DWR是一个允许JavaScript与Java服务器端进行交互的库,而Spring 2.5引入了对注解的强大支持,...

    spring annotation注解

    Spring Annotation 注解 Spring 框架中的注解是用于在 Java 类中添加元数据的,通过这些元数据,Spring 框架可以在运行时提供更多的功能。 Spring 框架提供了多种类型的注解,例如 @Autowired、@Resource、@...

    spring事务,xml方式和注解方式

    本节将详细介绍Spring如何通过XML配置和注解方式来实现事务管理。 首先,我们来看Spring事务的XML配置方式。在Spring中,事务管理通常通过`&lt;tx:annotation-driven&gt;`和`&lt;bean&gt;`标签来实现。`&lt;tx:annotation-driven&gt;`...

    Spring中Aop的使用包括xml和注解

    这里我们将深入探讨两种在Spring中实现AOP的方式:XML配置和注解配置。 首先,让我们来看看**XML配置AOP**。在Spring的早期版本中,XML配置是主要的配置方式。在`spring-aop-xml`中,你可能会看到以下关键元素: 1...

    学习Spring笔记_Annotation(注解)_Component

    4. **注解配置与XML配置的对比**:Spring框架既支持XML配置也支持注解配置。XML配置方式直观,但代码量大,维护困难;注解配置简洁,减少了XML配置文件,使代码更加清晰,同时提高了可读性和可维护性。然而,对于...

    Spring的Annotation配置相关讲义

    在Spring框架中,Annotation配置是一种简洁且强大的方式来管理Bean的定义和依赖注入,它消除了传统的XML配置文件,使得代码更加简洁、易读。在Spring 3.0及以上版本中,Annotation配置得到了广泛的应用。 首先,...

    spring和Mybatis的xml配置文件提示约束包

    在实际开发中,为了保证XML配置文件的正确性,我们需要确保引用的DTD与所使用的Spring和Mybatis版本相匹配。随着框架版本的更新,DTD可能会有变动,因此在升级项目时,需要更新XML配置文件中的DTD引用。 在压缩包的...

    spring xml 定时任务

    在Spring框架中,XML配置是传统且广泛使用的方式来设置应用的组件和行为,包括实现定时任务。定时任务在软件开发中扮演着重要角色,它允许应用程序在预设的时间执行特定的任务,例如数据清理、日志归档或者发送通知...

    Spring demo 自动检测注解

    在Spring框架中,自动检测注解(Autowired)是核心特性之一,它极大地简化了依赖注入的过程,使得开发者能够更加专注于业务逻辑,而不是繁琐的配置。本文将深入探讨Spring中的自动检测注解及其工作原理。 首先,`@...

    Spring使用XML配置声明式事务

    在Spring框架中,声明式事务管理是实现事务处理的一种高效且灵活的方式,它允许开发者通过XML配置或注解来定义事务边界,而无需在业务逻辑代码中显式地调用开始、提交或回滚事务的方法。这篇博文"Spring使用XML配置...

    使用Spring的声明式事务----Annotation注解方式

    在Spring中,我们可以使用XML配置文件来声明事务,但更常见的是通过Java注解来完成。这里我们将重点讨论Annotation注解方式。主要涉及的注解有`@Transactional`,`@Rollback`以及`@Transactional(propagation=...

    Spring Annotation (注解)详解

    Spring注解是Spring框架中的一种核心特性,它允许开发者在Java源代码中嵌入元数据,简化了XML配置,提高了代码的可读性和维护性。从Spring 2.5开始,注解成为主流配置方式,提供了更加简洁和直观的Bean定义和依赖...

    Spring IOC之基于注解的容器配置.docx

    通过`&lt;context:annotation-config/&gt;`元素,可以在XML配置中启用注解驱动的配置,它会自动注册相关的Bean后处理器,如@AutowiredAnnotationBeanPostProcessor,以处理注解的装配。 需要注意的是,当同时存在注解和...

    spring-mvc 注解方式xml配置

    在Spring MVC框架中,注解方式的配置是现代开发中常用的方法,它使得代码更加简洁,减少了XML配置的复杂性。下面将详细讲解如何通过注解实现Spring MVC的Controller控制器,以及如何设置访问路径。 首先,`Model1....

    spring 定时器 注解+xml 方式模板

    Spring Schedule模块提供了强大的定时任务支持,既可以通过注解的方式,也可以通过XML配置来实现。本文将深入探讨如何使用`@Scheduled`注解和XML配置来创建和管理定时任务。 首先,我们要引入Spring Schedule的依赖...

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

    在本项目中,这些框架都结合了最新的版本,即Struts2.18、Spring2.5和Hibernate3.3,并且引入了Annotation注解来简化配置,提升开发效率。 Struts2是MVC(Model-View-Controller)设计模式的实现,主要负责处理用户...

    spring基于task标签和通过xml配置实现任务的区别

    你可以在Spring配置文件中直接声明`&lt;task:annotation-driven/&gt;`来启用对`@Scheduled`注解的支持。 - 使用`@Scheduled`注解,可以直接在方法上定义调度规则,如cron表达式或固定延迟,使得任务代码和配置更加紧密...

    Spring xml 配置案例

    Spring XML配置是Spring框架中传统的配置方式,用于定义Bean的创建和依赖关系。在Spring中,事务管理是核心功能之一,确保数据操作的原子性、一致性、隔离性和持久性。本篇文章将详细介绍Spring中XML配置的事务管理...

Global site tag (gtag.js) - Google Analytics