xie-chong / microservicecloud Goto Github PK
View Code? Open in Web Editor NEW01、【初级架构搭建】SpringCloud从零搭建微服务架构视频教程
01、【初级架构搭建】SpringCloud从零搭建微服务架构视频教程
???
org.eclipse.jgit.errors.TransportException: https://[email protected]/xie-chong/microservicecloud-config.git: Authentication is required but no CredentialsProvider has been registered
目前的解决方案为,把仓库pirvate更改为public
2020-01-06 18:24:21.691 WARN 20252 --- [ restartedMain] ationConfigEmbeddedWebApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource' defined in class path resource [org/springframework/boot/autoconfigure/jdbc/DataSourceConfiguration$Tomcat.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.apache.tomcat.jdbc.pool.DataSource]: Factory method 'dataSource' threw exception; nested exception is org.springframework.boot.autoconfigure.jdbc.DataSourceProperties$DataSourceBeanCreationException: Cannot determine embedded database driver class for database type NONE. If you want an embedded database please put a supported one on the classpath. If you have database settings to be loaded from a particular profile you may need to active it (no profiles are currently active).
解决方案:
在启动类排除数据库配置
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
public class DeptConsumer80_App {
public static void main(String[] args) {
SpringApplication.run(DeptConsumer80_App.class, args);
}
}
或者不要引入
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jetty</artifactId>
</dependency>
代码如下也能正常:
@SpringBootApplication
//(exclude = {DataSourceAutoConfiguration.class})
public class DeptConsumer80_App {
public static void main(String[] args) {
SpringApplication.run(DeptConsumer80_App.class, args);
}
}
在Controller层的请求映射参数需要@PathVariable
@RequestMapping(value = "/consumer/dept/get/{id}")
public Dept get(@PathVariable("id") Long id) {
return this.service.get(id);
}
Feign调用的接口也需要
@FeignClient(value = "microservicecloud-dept", fallbackFactory = DeptClientServiceFallbackFactory.class)
public interface DeptClientService {
@RequestMapping(value = "/dept/get/{id}", method = RequestMethod.GET)
Dept get(@PathVariable("id") Long id);
}
否则,将出现错误
java.net.URISyntaxException: Illegal character in path at index 39: http://MICROSERVICECLOUD-DEPT/dept/get/{id}
at java.net.URI$Parser.fail(URI.java:2848) ~[na:1.8.0_231]
at java.net.URI$Parser.checkChars(URI.java:3021) ~[na:1.8.0_231]
at java.net.URI$Parser.parseHierarchical(URI.java:3105) ~[na:1.8.0_231]
at java.net.URI$Parser.parse(URI.java:3053) ~[na:1.8.0_231]
at java.net.URI.<init>(URI.java:588) ~[na:1.8.0_231]
at java.net.URI.create(URI.java:850) ~[na:1.8.0_231]
at org.springframework.cloud.netflix.feign.ribbon.LoadBalancerFeignClient.execute(LoadBalancerFeignClient.java:56) ~[spring-cloud-netflix-core-1.3.1.RELEASE.jar:1.3.1.RELEASE]
at feign.SynchronousMethodHandler.executeAndDecode(SynchronousMethodHandler.java:97) ~[feign-core-9.5.0.jar:na]
at feign.SynchronousMethodHandler.invoke(SynchronousMethodHandler.java:76) ~[feign-core-9.5.0.jar:na]
at feign.ReflectiveFeign$FeignInvocationHandler.invoke(ReflectiveFeign.java:103) ~[feign-core-9.5.0.jar:na]
at com.sun.proxy.$Proxy71.get(Unknown Source) ~[na:na]
at com.atguigu.springcloud.controller.ConsumerDeptController.get(ConsumerDeptController.java:21) ~[classes/:na]
@Autowired
private DeptDao dao;
/*
Field injection is not recommended
Inspection info: Spring Team recommends: "Always use constructor based dependency
injection in your beans. Always use assertions for mandatory dependencies".
*/
意思就是总是使用构造器的方式强制注入。
优化为:
private final DeptDao dao;
public DeptServiceImpl(DeptDao dao) {
this.dao = dao;
}
依赖注入有三种方式:
先各自看一下实现方式
变量(filed)注入
@Autowired
UserDao userDao;
构造器注入
final UserDao userDao;
@Autowired
public UserServiceImpl(UserDao userDao) {
this.userDao = userDao;
}
set方法注入
private UserDao userDao;
@Autowired
public void setUserDao (UserDao userDao) {
this.userDao = userDao;
}
相比较而言:
优点:变量方式注入非常简洁,没有任何多余代码,非常有效的提高了java的简洁性。即使再多几个依赖一样能解决掉这个问题。
缺点:不能有效的指明依赖。相信很多人都遇见过一个bug,依赖注入的对象为null,在启动依赖容器时遇到这个问题都是配置的依赖注入少了一个注解什么的,然而这种方式就过于依赖注入容器了,当没有启动整个依赖容器时,这个类就不能运转,在反射时无法提供这个类需要的依赖。
在使用set方式时,这是一种选择注入,可有可无,即使没有注入这个依赖,那么也不会影响整个类的运行。
在使用构造器方式时已经显式注明必须强制注入。通过强制指明依赖注入来保证这个类的运行。
另一个方面:
依赖注入的核心**之一就是被容器管理的类不应该依赖被容器管理的依赖,换成白话来说就是如果这个类使用了依赖注入的类,那么这个类摆脱了这几个依赖必须也能正常运行。然而使用变量注入的方式是不能保证这点的。
既然使用了依赖注入方式,那么就表明这个类不再对这些依赖负责,这些都由容器管理,那么如何清楚的知道这个类需要哪些依赖呢?它就要使用set方法方式注入或者构造器注入。
总结:
变量方式注入应该尽量避免,使用set方式注入或者构造器注入,这两种方式的选择就要看这个类是强制依赖的话就用构造器方式,选择依赖的话就用set方法注入。
@qualifier注解了,qualifier的意思是合格者,通过这个标示,表明了哪个实现类才是我们所需要的,我们修改调用代码,添加@qualifier注解,需要注意的是@qualifier的参数名称必须为我们之前定义@service注解的名称之一。
例子:
@Service("a")
public class EmployeeServiceImpl implements EmployeeService {
public EmployeeDto getEmployeeById(Long id) {
return new EmployeeDto();
}
}
@Service("b")
public class EmployeeServiceImpl1 implements EmployeeService {
public EmployeeDto getEmployeeById(Long id) {
return new EmployeeDto();
}
}
@Controller
@RequestMapping("/emplayee.do")
public class EmployeeInfoControl {
@Autowired
@Qualifier("b")
EmployeeService employeeService;
@RequestMapping(params = "method=showEmplayeeInfo")
public void showEmplayeeInfo(HttpServletRequest request, HttpServletResponse response, EmployeeDto dto) {
#略
}
}
各种报错
主启动类提示:
Cannot access org.springframework.context.ConfigurableApplicationContext
强行启动:
"Error:(11, 30) java: 无法访问org.springframework.context.ConfigurableApplicationContext
找不到org.springframework.context.ConfigurableApplicationContext的类文件"
看了网络的各种解决方案,删除xxx.iml文件,但还是未能解决我的问题。
最终解决方案,需要把该灰色的module添加到聚合工程里面。
点击加号"+",选中变灰模块的pom.xml,一路ok下去,之后再选中Module 操作Reimport。(该操作后,xxx.iml文件自动消失)
获取不到值的配置
父工程pom.xml
<build>
<finalName>microservicecloud</finalName>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>2.6</version>
<configuration>
<delimiters>
<delimit>$</delimit>
</delimiters>
</configuration>
</plugin>
</plugins>
</build>
服务模块的yml:
info:
app.name: atguigu-microservicecloud
company.name: www.atguigu.com
build.artifactId: $project.artifactId$
build.version: $project.version$
能获取值的配置(把$修改为@)
<build>
<finalName>microservicecloud</finalName>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>2.6</version>
<configuration>
<delimiters>
<delimit>@</delimit>
</delimiters>
</configuration>
</plugin>
</plugins>
</build>
服务模块的yml:
info:
app.name: atguigu-microservicecloud
company.name: www.atguigu.com
build.artifactId: @project.artifactId@
build.version: @project.version@
ERROR 10544 --- [tp1722536394-30] com.alibaba.druid.pool.DruidDataSource : testWhileIdle is true, validationQuery not set
暂未解决,不影响系统运行。
把 @Mapper 换成 @repository,在启动类需要添加注解 @MapperScan("com.atguigu.springcloud.dao")
作用:在接口类上添加了@Mapper,在编译之后会生成相应的接口实现类
添加位置:接口类上面
@Mapper
public interface UserDAO {
//代码
}
如果想要每个接口都要变成实现类,那么需要在每个接口类上加上@Mapper注解,比较麻烦,解决这个问题用
@MapperScan
作用:指定要变成实现类的接口所在的包,然后包下面的所有接口在编译之后都会生成相应的实现类
添加位置:是在Springboot启动类上面添加
@SpringBootApplication
@MapperScan("com.winter.dao")
public class SpringbootMybatisDemoApplication {
public static void main(String[] args) {
SpringApplication.run(SpringbootMybatisDemoApplication.class, args);
}
}
添加@MapperScan(“com.winter.dao”)注解以后,com.winter.dao包下面的接口类,在编译之后都会生成相应的实现类
(实际用的时候根据自己的包路径进行修改)
@SpringBootApplication
@MapperScan({"com.kfit.demo","com.kfit.user"})
public class App {
public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
}
(没验证过,不确定能否使用,或许需要根据自己定义的包名进行修改路径)
@SpringBootApplication
@MapperScan({"com.kfit.*.mapper","org.kfit.*.mapper"})
public class App {
public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
}
若在项目中使用,可以在父pom.xml中添加如下配置来解决
<build>
<finalName>microservicecloud</finalName>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>2.6</version>
<configuration>
<delimiters>
<delimit>@</delimit>
</delimiters>
</configuration>
</plugin>
</plugins>
</build>
但是如若配置文件是通过springcloud-config从github来获取,则依然没法解决“Do not use @ for indentation”
目前只能把其当作字符串来处理,即把@@添加单引号或双引号:
info:
app.name: atguigu-microservicecloud
company.name: www.atguigu.com
build.artifactId: '@project.artifactId@'
build.version: '@project.version@'
提示:SpringBoot已经把占位符${xxx}修改为@xxx@
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.