搭建好的Spring boot运行时出现以下问题:



问题一:

***************************
 APPLICATION FAILED TO START
 ***************************Description:
Failed to auto-configure a DataSource: 'spring.datasource.url' is not specified and no embedded datasource could be auto-configured.
Reason: Failed to determine a suitable driver class
 Action:
Consider the following:
     If you want an embedded database (H2, HSQL or Derby), please put it on the classpath.
     If you have database settings to be loaded from a particular profile you may need to activate it (no profiles are currently active). Process finished with exit code 1
解决方案:

搭建数据库,添加数据库配置信息


spring.datasource.url=jdbc:mysql://127.0.0.1:3306/test
spring.datasource.username=root
spring.datasource.password=654321
spring.datasource.driver-class-name=com.mysql.jdbc.Driver


所使用的数据库为mysql





问题二:service注入失败

***************************

APPLICATION FAILED TO START
 ***************************Description:
Field testInterFace in com.testInterface.TestBootController required a bean of type 'com.testInterface.TestInterface' that could not be found.
 Action:Consider defining a bean of type 'com.testInterface.TestInterface' in your configuration.

根据英文的提示是在配置中找不到一个指定自动注入类型的bean,经过多方排查得出结论: 相信大家对这种异常非常常见,注入失败,这时候问题来了,按照传统的方式,对注入进行检查。service层已经加了@service的注解,怎么还是注入失败了呢,想查看配置文件,发现springboot没有配置文件,那么他是怎么扫描注解的呢?正常情况下加上@Component注解的类会自动被Spring扫描到生成Bean注册到spring容器中,既然他说没找到,也就是该注解被没有被spring识别,问题的核心关键就在application类的注解SpringBootApplication上 

这个注解其实相当于下面这一堆注解的效果,其中一个注解就是@Component,在默认情况下只能扫描与控制器在同一个包下以及其子包下的@Component注解,以及能将指定注解的类自动注册为Bean的@Service@Controller和@ Repository

springboot默认按照包顺序注入,所以在创建controller时service还没有注入,springboot不需要传统的xml配置扫描包,只需要添加注解@ComponentScan(basePackages={“com.testInterface”})

注意:红色部分为需要注入的包

 



问题三:@Autowired注入失败

问题描述:

***************************
 APPLICATION FAILED TO START
 ***************************Description:
Field userDao in com.lar.testInterface.service.impl.TestInterfaceImpl required a bean of type 'com.lar.testInterface.dao.UserDao' that could not be found.
 Action:
Consider defining a bean of type 'com.lar.testInterface.dao.UserDao' in your configuration.

失败注入代码:

idea 查看spring boot 版本 idea怎么用spring boot_java

解决方案:

controller 是作为控制器被spring 调用的,如果你非要用也得使用@Autowired注入,这样才能得到被spring管理的bean,就没问题了



(一)

SpringBoot项目的Bean装配默认规则是根据Application类所在的包位置从上往下扫描!
“Application类”是指SpringBoot项目入口类。这个类的位置很关键:
如果Application类所在的包为:com.boot.app,则只会扫描com.boot.app包及其所有子包,如果service或dao所在包不在com.boot.app及其子包下,则不会被扫描!
即, 把Application类放到dao、service所在包的上级,com.boot.Application



(二)

SpringBoot中Service自动注入很方便,例:

Service.class(接口类)

ServiceImpl.class(实现类)

Controller.class(使用类)

用以上三个类来说一下自动注入:

单项目:分别ServiceImpl头上@Service,Controller中Service对象@Autowired即可享用;

Multi modules 场景,三个(种)类分别在三个module下:

moduleA : Service.class(com.example.moduleA )

moduleB : ServiceImpl.class ( com.example.moduleB )

moduleC : Controller.class ( com.example.moduleC )

此时B依赖A,C依赖A、B,添加好依赖关系。

如何自动注入?

1、接口、实现、使用类,姿势不变,按单项目方式写即可;

2、在moduleC的Application中做手脚!

 

如果你已经试过scanBasePackages,无论是在@SpringBootApplication方式还是@ComponentScan;

抑或试过@SpringBootApplication、@ComponentScan同时用,当你这么做时,一定是绝望的。

 

解决办法@SpringBootApplictaion(scanBasePackages="com.example")

核心就是:

Service 及 ServiceImpl均需在com.example包下

 

因为Service、ServiceImpl同在com.example下(C可以不在),所以我看作是同一次scan过程;

比如若是这样写scanBasePackages={" com.example.moduleA , com.example.moduleB "},则会失败;

当然(@ComponentScan="com.example")也是可以的,因为前者@SpringBootApplication已经包含@ComponentScan;



(三)

mapper(Dao层)



1 package com.demo.mapper;
 2 
 3 import org.apache.ibatis.annotations.Mapper;
 4 
 5 import com.demo.domain.User;
 6 
 7 @Mapper
 8 public interface UserMapper {
 9 
10     public User gYeMian(User u);
11 
12     public int sYeMian(User u);
13 
14 }


(四)

Application(启动类)



1 package com.demo;
 2 
 3 import org.mybatis.spring.annotation.MapperScan;
 4 import org.springframework.boot.SpringApplication;
 5 import org.springframework.boot.autoconfigure.SpringBootApplication;
 6 
 7 @SpringBootApplication
 8 @MapperScan(value = "com.demo.mapper")
 9 public class App 
10 {
11     public static void main(String[] args) throws Exception {
12         SpringApplication.run(App.class, args);
13     }
14 }



原因:在mybatis-spring-boot-autoconfigure的jar包中有一个类 MybatisAutoConfiguration,在这个类中的registerBeanDefinitions方法告诉了我们

1 @Override
 2     public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
 3 
 4       logger.debug("Searching for mappers annotated with @Mapper");
 5 
 6       ClassPathMapperScanner scanner = new ClassPathMapperScanner(registry);
 7 
 8       try {
 9         if (this.resourceLoader != null) {
10           scanner.setResourceLoader(this.resourceLoader);
11         }
12 
13         List<String> packages = AutoConfigurationPackages.get(this.beanFactory);
14         if (logger.isDebugEnabled()) {
15           for (String pkg : packages) {
16             logger.debug("Using auto-configuration base package '{}'", pkg);
17           }
18         }
19 
20         scanner.setAnnotationClass(Mapper.class);
21         scanner.registerFilters();
22         scanner.doScan(StringUtils.toStringArray(packages));
23       } catch (IllegalStateException ex) {
24         logger.debug("Could not determine auto-configuration package, automatic mapper scanning disabled.", ex);
25       }
26     }


(五)

这是由于springBoot启动时,没有扫描到com.lar.testInterface.dao.UserDao ,而在com.lar.testInterface.TestInterface中又使用了@autowired private EnfileDao entFileDao进行装配,所以会发现错误,说没有定义。此时需要在springBoot的启动类上,加个注解:@MapperScan("持久层路径"),这样就会扫描到com.lar.testInterface.dao.UserDao了。