spring配置不扫描service层的原因解答

目录
  • spring配置自动扫描原理介绍
    • 自动扫描组件的使用
    • 细节问题总结

spring配置不扫描service层原因

我将contoller给springmvc进行扫描,然后其余所有交给spring扫描

然后发现service层的EmployeeService并没有扫描到出现以下问题

Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type ‘springmvc.crud.service.EmployeeService’ available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1493)at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1104)at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1066)at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:585)… 39 more

最终发现原因是spring配置文件里面context:exclude-filter是不要加use-default-filters的,而context:include-filter是需要加的

找了好久问题!!!

spring配置自动扫描原理介绍

Spring利用IOC容器将所有的bean进行有秩序的管理维护,而实际项目中不可能在xml文件中创建bean,而是利用了Spring的组件自动扫描机制,通过在classpath自动扫描的方式把组件纳入到Spring容器中。这大大减少了程序员在配置XML文件上的时间,使得配置文件显得干净,整洁,便于维护。

这种机制的工作步骤是:

1.配置需要扫描的类;

2.在需要被纳入Spring容器的类上加上相应的注解;

3.Spring在类路径下寻找标注了注解的类,并把这些类纳入Spring容器中管理。

它的作用是和在XML文件中使用节点配置组件是一样的。

自动扫描组件的使用

第一步:配置applicationContext.xml文件;

如下:

<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans 
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd
">
<!-- 打开Spring组件自动扫面,并配置要扫描的基本包 -->
<context:component-scan base-package="com.springtest"></context:component-scan>
</beans>

注:节点用于通知Spring容器扫描组件,base-package属性用于指定将要被扫描的组件所在的包名称。

在这里说明一下:context:component-scan有一个use-default-filters属性,默认为true,这就意味着会扫描指定包base-package下的全部的标有@Component@Service,@Repository的类,并注册成bean.

1. context:include-filter 指定扫描位置

2. context:exclude-filter 指定的不扫描

use-default-filters=”true”时,此时指定的include-filter不会起到作用,只有当

use-default-filters=”false”时,context:exclude-filter指定的不扫描,context:include-filter指定的扫描

第二步:为需要被扫描的类添加相应的注解

注解的类型有以下几种:

  • @Service 用于标注业务层组件;
  • @Repository 用于标注数据访问层组件;
  • @Controller 用于标注控制层组件(如:Struts中的action)
  • @Component 表示泛型组件,当组件不好归类的时候,我们可以使用这个组件进行注解。

第三步:当为类添加完成注解后,我们需要测试相应的组件是否被纳入Spring容器,所以我们需要测试组件是否被扫描

如下:

@Test
public void testAddUser()
{
UserBiz userBiz = (UserBiz)context.getBean("userBizImpl");
System.out.println(userBiz);
}

如果输出不为空,则说明测试类已经被扫描并且纳入了Spring容器。

细节问题总结

1.当我们进行测试时,用ApplicationContext对象的getBean()方法寻找组件。

在之前的配置文件中我们会用标签的id属性去定义,在使用注解后怎样获得组建的id呢?

在这种情况下,Spring会将被标注注解的类名拿到,然后再将该类名的第一个字母变为小写,放到getBean()方法中。如:UserBizImpl类的组件Id就会是userBizImpl,获取时为context.getBean(“userBizImpl”);

那么,我们在使用注解时可以自定义组件的Id吗?

当然可以。

我们需要在为相应的类添加注解时,在注解之后添加自定义的类名,例如:

@Service("userBiz")
public class UserBizImpl implements UserBiz {
……
}

当我们在获取该组件时,为context.getBean(“userBiz);

2.在配置文件中我们可以对组件(bean)的作用域范围进行设置,它的默认值是单例模式,那么在添加注解的情况下,我们怎样设置组件的作用域范围呢?

我们可以直接在为类添加注解的同时,运用另一个注解@Scope(“prototype”)来设置,如下

@Service(“userBiz”)@Scope(“prototype”)
public class UserBizImpl implements UserBiz {
……
}

3.在使用注解时,为组件设置初始化和销毁方法

在添加注解的相应的类中,如果想初始化或销毁某个方法,我们可以直接在方法上添加注解,如下:

@PostConstruct
public void addItem() {
System.out.println("初始化方法");
}
@PreDestroy
public void testItem() {
System.out.println("释放资源");
}

4.在使用Spring自动扫描组件后,怎样进行依赖注入?

运用注解@Resource和@Autowired,并为依赖对象设置名称,例如:

@Resource(name="userDao")
private UserDAO userDao = null;

首先它会根据名称去找Spring自动扫描的并加入到Spring容器的组件(bean),如果有相同的名称,则进行依赖注入,如果没有相同的名称。则会根据类型区寻找组件。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • Spring MVC 注解自动扫描失效原因分析

    关于spring自动扫描,在控制层,采用注解配置@Controller,项目能够成功启动,且无任何报错.但是 在进行页面跳转时,并未进行相应的拦截,整个界面只能在默认界面 ,跳转报404,由于楼主初次尝试,在绕了一个大圈后,初步确认是在扫描时mvc控制器,并未成功,详情请看代码 <!-- 开启controller注解支持 --> <context:component-scan base-package="com.cjw.test.controller" use-def

  • spring注解在自定义jar包中无法被扫描的解决方案

    spring注解在自定义jar包中无法被扫描 前两天,一朋友在开发的时候遇到了一个问题向我求助, service服务为第三方提供的服务里面有spring注解并将service 打成jar包中,使用maven引入. 使用new可以创建,但是使用autowire无法注入提示信息如下图 报错信息 这类问题在开发中一直是我们最不愿意看到的,乍一看,感觉挺对,还挺有道理.但是就是更想要的结果对不上. 我当时给出的判断autowire的类重名导致注入失败,建议用配合使用qualifier或者 使用resou

  • Spring注解方式无法扫描Service注解的解决

    目录 Spring注解方式无法扫描Service注解 场景描述 spring配置不扫描service层的原因 Spring注解方式无法扫描Service注解 场景描述 系统启动没有任何错误,但是单独访问controller就会报错,原因是做了service注入.贴两张图吧 1.分析: 找不到bean的原因就是service注解没有被扫描到spring中生成bean 2.尝试:手动将service在spring的文件中进行配置,启动正常,访问也正常,更证明了第一点的分析结果. 3.查资料,大致查询

  • Spring和SpringMVC扫描注解类冲突的解决方案

    目录 Spring和SpringMVC扫描注解类冲突 最正确的配置方式 也可以用直接扫描的方式 几种不同配置的测试 Spring和SpringMVC注解扫描注意事项 现象 方法 Spring和SpringMVC扫描注解类冲突 最正确的配置方式 在主容器中applicationContext.xml中,将Controller的注解排除掉 <context:component-scan base-package="com"> <context:exclude-filter

  • spring配置不扫描service层的原因解答

    目录 spring配置自动扫描原理介绍 自动扫描组件的使用 细节问题总结 spring配置不扫描service层原因 我将contoller给springmvc进行扫描,然后其余所有交给spring扫描 然后发现service层的EmployeeService并没有扫描到出现以下问题 Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type ‘spr

  • spring配置扫描多个包问题解析

    spring 配置扫描多个包,有时候我们希望不同功能类型的包放在不同的包下,这就需要 <!-- 自动扫描该包,使 SpringMVC 为包下用了@controller注解的类是控制器 --> <context:component-scan base-package="com.weixiao.ssmcleardb.controller" /> <context:component-scan base-package="com.weixiao.lis

  • Spring main方法中如何调用Dao层和Service层的方法

    目录 Spring main方法调用Dao层和Service层的方法 如何在普通类中直接访问service层或dao层 第一种方案 第二种方案 Spring main方法调用Dao层和Service层的方法 在web环境中,一般serviceImpl中的dao之类的数据库连接都由容器启动的时候创建好了,不会报错. 但是在main中,没有这个环境,所以需要获取环境: ApplicationContext ctx = new FileSystemXmlApplicationContext("src/

  • SpringBoot在自定义类中调用service层等Spring其他层操作

    背景: 做了一个TCP服务器来接入智能设备,然后需要将设备实时发送的定位等关键信息存储到数据库. 为了考虑将来可能对外提供rest接口,采用将TCP服务器集成到SpringBoot框架,当然,也是为了能最快利用mybatis框架实现数据访问,然后依次解决了如何启动,如何注销等各种问题,然后在TCP服务器消息处理时,需要写数据库,直接调用DAO层,编译报错. 改为调用Service层,编译正常,运行到调用的地方,报空指针异常,跟踪到异常位置,发现service为空,也就是按照之前controlle

  • spring在service层的方法报错事务不会回滚的解决

    目录 spring在service层方法报错事务不会回滚 解决方法 service手动回滚问题 spring在service层方法报错事务不会回滚 @Transactional(rollbackFor = {Exception.class}) public void insertData() throws Exception {     // 业务代码1     business1();          // 业务代码2     business2();          // 业务代码3  

  • Spring Boot jpa Service层代码实例

    这篇文章主要介绍了Spring Boot jpa Service层代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 package com.fei.service.impl; import java.util.ArrayList; import java.util.List; import javax.persistence.criteria.CriteriaBuilder; import javax.persistence.criter

  • 解决spring boot启动扫描不到自定义注解的问题

    对于自定义注解这里就不唠叨了,百度一大堆,这里有我一个自定义注解 @Retention(RetentionPolicy.RUNTIME) @Target({ ElementType.METHOD }) public @interface MsgEvent { RetailOrderEvent msgEvent(); } 注解实现类 @Component public class MsgEventProcessor implements BeanPostProcessor { /** * 事件消息

  • springBoot service层事务控制的操作

    springBoot使用事物比较简单,在Application启动类s上添加@EnableTransactionManagement注解,然后在service层的方法上添加@Transactional注解 @Transactional属性 属性 类型 描述 value String 可选的限定描述符,指定使用的事务管理器 propagation enum: Propagation 可选的事务传播行为设置 isolation enum: Isolation 可选的事务隔离级别设置 readOnly

  • springboot实现在工具类(util)中调用注入service层方法

    一.新建BeanUtil类 import lombok.extern.slf4j.Slf4j; import org.springframework.beans.BeansException; import org.springframework.beans.factory.DisposableBean; import org.springframework.context.ApplicationContext; import org.springframework.context.Applic

随机推荐