1、典型项目结构
com
+- example
+- myproject
+- Application.java
|
+- domain
| +- Customer.java
| +- CustomerRepository.java
|
+- service
| +- CustomerService.java
|
+- web
| +- CustomerController.java
|
上面的结构中,root package与应用主类(Application.java)的位置是整个结构的关键。由于应用主类在root package中,所以按照上面的规则定义的所有其他类都处于root package下的其他子包之后。默认情况下,Spring Boot的应用主类会自动扫描root package以及所有子包下的所有类来进行初始化,如果改变了其他类的包的位置可能会导致初始化失败。
2、非典型结构下的初始化
那么如果,我们一定要加载非root package下的内容怎么办呢?
方法一:使用@ComponentScan注解指定具体的加载包,比如:
@SpringBootApplication
@ComponentScan(basePackages="com.example")
public class Bootstrap {
public static void main(String[] args) {
SpringApplication.run(Bootstrap.class, args);
}
}
方法二:使用@Bean注解来初始化,比如:
@SpringBootApplication
public class Bootstrap {
public static void main(String[] args) {
SpringApplication.run(Bootstrap.class, args);
}
@Bean
public CustomerController customerController() {
return new CustomerController();
}
}
1、application.properties
Spring Boot的默认配置文件位置为: src/main/resources/application.properties。关于Spring Boot应用的配置内容都可以集中在该文件中了,根据我们引入的不同Starter模块,可以在这里定义诸如:容器端口名、数据库链接信息、日志级别等各种配置信息。比如,我们需要自定义web模块的服务端口号,可以在application.properties中添加server.port=8888来指定服务端口为8888,也可以通过spring.application.name=hello来指定应用名(该名字在Spring Cloud应用中会被注册为服务名)。
2、application.yml
如:
environments:
dev:
url: http://dev.bar.com
name: Developer Setup
prod:
url: http://foo.bar.com
name: My Cool App
以类似大纲的缩进形式来表示,属性后“:”符合号需要有一个空格。
3、springboot多环境配置
首先在application.properties文件中通过spring.profiles.active属性来设置,其值对应{profile}值:
如spring.profiles.active=dev
然后在resource下需要定义对应的文件,文件名为:application-{profile}.properties,其中{profile}对应你的环境标识,比如:
application-dev.properties:开发环境
application-test.properties:测试环境
application-prod.properties:生产环境
样例:
step1:针对各环境新建不同的配置文件application-dev.properties、application-test.properties、application-prod.properties;
step2:在这三个文件均都设置不同的server.port属性,如:dev环境设置为8080,test环境设置为9090,prod环境设置为80;
step3:application.properties中设置spring.profiles.active=dev,就是说默认以dev环境设置;
step4:测试不同配置的加载:
执行java -jar xxx.jar,可以观察到服务端口被设置为8080,也就是默认的开发环境(dev)
执行java -jar xxx.jar --spring.profiles.active=test,可以观察到服务端口被设置为9090,也就是测试环境的配置(test)
执行java -jar xxx.jar --spring.profiles.active=prod,可以观察到服务端口被设置为80,也就是生产环境的配置(prod)
4、自定义参数
我们除了可以在Spring Boot的配置文件中设置各个Starter模块中预定义的配置属性,也定义一些我们需要的自定义属性。比如在application.properties中添加:
book.name=SpringCloudInAction
book.author=ZhaiYongchao
然后,在应用中我们可以通过@Value注解来加载这些自定义的参数,比如:
@Component
public class Book {
@Value("${book.name}")
private String name;
@Value("${book.author}")
private String author;
// 省略getter和setter
}
5、配置文件加载顺序
对于一个相同的属性,在不同的配置文件中加载,spring boot会有不同的加载顺序;
6、2.x版本的新特性
a、移除特殊字符外,配置均以全小写的方式进行匹配和加载。所以,下面的4种配置方式都是等价的:
spring.jpa.databaseplatform=mysql
spring.jpa.database-platform=mysql
spring.jpa.databasePlatform=mysql
spring.JPA.database_platform=mysql
b、在properties文件中使用[]来定位列表类型(list),比如:
spring.my-example.url[0]=http://example.com
spring.my-example.url[1]=http://spring.io
也支持使用逗号分割的配置方式,上面与下面的配置是等价的:
spring.my-example.url=http://example.com,http://spring.io
1、@SpringBootApplication
启动类,此注解是个组合注解,包括了@SpringBootConfiguration、@EnableAutoConfiguration和@ComponentScan注解。
@SpringBootConfiguration:继承至@Configuration,对于熟悉spring的开发者而言,此标注当前类是配置类,并会将当前类内声明的一个或多个以@Bean注解标记的方法的实例纳入到srping容器中,并且实例名就是方法名。
@EnableAutoConfiguration:主要是通过此注解,使所有符合自动配置条件的bean的定义加载到spring容器中,比如根据spring-boot-starter-web ,来判断你的项目是否需要添加了webmvc和tomcat,就会自动的帮你配置web项目中所需要的默认配置。如需要排除一些无需自动配置的类时,可利用exclude进行排除。
@ComponentScan:会扫描当前包及其子包下被@Component,@Controller,@Service,@Repository等注解标记的类并纳入到spring容器中进行管理。
2、@Configuration
用于定义配置类,定义的配置类可以替换xml文件,一般和@Bean注解联合使用。
3、@Controller 和 @RestController
@RestController 是Spring4之后加入的注解,原来在@Controller中返回json需要@ResponseBody来配合,如果直接用@RestController替代@Controller就不需要再配置@ResponseBody,默认返回json格式。而@Controller是用来创建处理http请求的对象,一般结合@RequestMapping使用。
4、@SpringBootTest
是springboot 用于测试的注解,可指定启动类或者测试环境等,这里直接默认。
5、@PropertySource(value = {"demo/props/demo.properties"})
当有多个配置文件时,可以在类上加上该注解获取配置内容,然后属性可以使用@value获取内容。
6、@ConfigurationProperties
根据配置文件中设置的属性,批量注入属性值。支持(lastName可以写作last-name、last_name)。
如果只是某个业务中需要获取配置文件中的某项值或者设置具体值,可以使用@Value;
如果一个JavaBean中大量属性值要和配置文件进行映射,可以使用@ConfigurationProperties;
@ConfigurationProperties使用如下:
userInfo.properties文件配置如下:
spring.user.user-id=123
spring.user.user-name=小明
spring.user.user-password=xiaoming
spring.user.user-address=上海
//实体类代码如下
@ConfigurationProperties(prefix="spring.user")
public class UserInfo{
private Integer userId;
private String userName;
private String userPassword;
private String userAddress;
//省去get/set方法
}
如此,userinfo的各个属性就可以直接get到对应内容。
springboot下过滤器有两种实现方式。
1、注解方式
添加@WebFilter注解,另外还需要@Component注解,将该类作为组件,注入spring容器中。如下:
@Component
@WebFilter(urlPatterns = "/api/hello/*", filterName = "helloFilter")
public class HelloFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
FilterChain filterChain) throws IOException, ServletException {
log.info("进入到过滤器啦");
filterChain.doFilter(servletRequest,servletResponse);
}
@Override
public void destroy() {
}
}
2、bean注入方式
通过容器注入bean的模式主要是通过FilterRegistrationBean类,相较于@WebFilter注解方式FilterRegistrationBean可以设置过滤器的优先级。
step1:实现javax.servlet.Filter接口,覆盖其doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2)方法,决定拦截或放行;
step2:springboot的configuration中配置不同的FilterRegistrationBean实例,来注册自定义过滤器。
public class HelloFilter implements Filter {
@Override
public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2)
throws IOException, ServletException {
HttpServletRequest request=(HttpServletRequest)arg0;
log.info("进入到过滤器啦");
arg2.doFilter(arg0,arg1);
}
}
@Configuration
public class DemoConfiguration {
@Bean
public FilterRegistrationBean RegistTest1(){
FilterRegistrationBean bean = new FilterRegistrationBean();
bean.setFilter(new HelloFilter());//注册自定义过滤器
bean.setName("flilter1");//过滤器名称
bean.addUrlPatterns("/*");//过滤所有路径
bean.setOrder(1);//优先级,最顶级
return bean;
}
}
springboot创建拦截器两步骤:
1、实现HandlerInterceptor接口创建拦截器
public class MyInterceptor implements HandlerInterceptor{
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
String username = request.getParameter("username");
String password = request.getParameter("password");
if("xiongda".equals(username) && "123456".equals(password)) {
return true;
}else {
return false;
}
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception {
System.out.println("================= jin ru after ===============");
}
}
2、实现WebMvcConfigurer接口配置拦截器
@Configuration
public class WebMvcConfig implements WebMvcConfigurer{
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new MyInterceptor())
.addPathPatterns("/**")
.excludePathPatterns("/static/login.html");
}
}
springMVC中使用拦截器需要实现接口,然后还需要在xml中配置,如下: