搭建好的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.
失败注入代码:
解决方案:
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了。