从SpringMVC迁移到Springboot的⽅法步骤springboot和过滤器
在将SpringMVC项⽬转移到Springboot上的过程中,主要做了以下的事情
1. Profile配置
2. 全局变量从properties⽂件读⼊
3. 数据源与Mybatis配置
4. ⽇志⽂件配置
5. WebConfig配置(包括原有的l和l)
6. 去掉多余的bean注⼊
本篇⽂章除了介绍做了些什么和怎么做之外,会多很多多余的废话,关于对原理的⼀些探讨,知其然也要知其所以然。Profile配置
在传统的Spring项⽬中,多个profile的配置⽅式⾸先是在l⽂件中写⼊多个profile,再通过启动项⽬前先执⾏⼀个maven⽂件来预加载选定的profile环境。加载完之后,执⾏项⽬的时候,会根据已加载的En
vironment,来决定去将哪个.properties⽂件load到全局变量中。
⽽在Springboot中对多个profile的管理就⾮常简单了。
可以在jar包⽤命令⾏运⾏时选择profile
java -jar example.jar --spring.profiles.active=test
或者在application.properties这个全局配置中配置
在application.properties中添加spring.profiles.active=test
以上两种⽅法均可启动“test"这个profile,前者在执⾏上的优先级要⾼于后者。
(顺便⼀提,在Springboot⾥⾯,这两种⽅式本质上都是⽤“外部化配置”的⽅式,来对Environment进⾏编辑和替换)另外,每个独⽴的profiles的配置⽅式为以"application-xxx.properties"格式,针对每个不同环境,例如:
1. application-pro.properties 表⽰预演环境
2. application-dev.properties 表⽰开发环境
3. application-test.properties 表⽰测试环境
当我们需要测试是否正常载⼊了profile的时候,可以在对应的.properties⽂件中写⼊
server.port=9080
在启动的时候就可以看到,是否已经启动了这个端⼝。
在这⾥可以顺便提⼀下Springboot加载配置⽂件的顺序
1. home⽬录下的devtools全局设置属性( ~/.spring-boot-devtools.properties ,如果devtools激活)。
2. 测试⽤例上的@TestPropertySource注解。
3. 测试⽤例上的@SpringBootTest#properties注解。
4. 命令⾏参数
5. 来⾃ SPRING_APPLICATION_JSON 的属性(环境变量或系统属性中内嵌的内联JSON)。
6. ServletConfig 初始化参数。
7. ServletContext 初始化参数。
8. 来⾃于 java:comp/env 的JNDI属性。
9. Java系统属性(Properties())。
10. 操作系统环境变量。
11. RandomValuePropertySource,只包含 random.* 中的属性。
12. 没有打进jar包的Profile-specific应⽤属性( application-{profile}.properties 和YAML变量)。
13. 打进jar包中的Profile-specific应⽤属性( application-{profile}.properties 和YAML变量)。
14. 没有打进jar包的应⽤配置( application.properties 和YAML变量)。
15. 打进jar包中的应⽤配置( application.properties 和YAML变量)。
16. @Configuration 类上的 @PropertySource 注解。
17. 默认属性(使⽤ SpringApplication.setDefaultProperties 指定)。
全局变量从properties⽂件读⼊
在上⼀⾯⼀⼩节写了针对不同环境的properties配置,这⾥会写关于如果将这些属性写⼊到全局变量中,⽅便后⾯其他地⽅直接调⽤。
/**
* 全局变量
*/
public class Global {
public static String examplePath;
@Value("${example_path}")
public void setExamplePath(String example) {
}
}
通过这样⼦,我们便将.properties⽂件中的
example_path=localhost:9090
这个属性读到了全局变量中。
数据源与Mybatis配置
在传统的Spring项⽬中,⽤Mybatis连接数据库
1. ⾸先要创建⼀个名为datasource的bean
2. 然后将这个datasource装配到SqlSessionFactory中
3. 最后再将SqlSessionFactory装配到MapperScannerConfigurer中
这⼀切都是在xml配置⽂件中配置的,⽐较繁琐。在Springboot中会尽量去避免这样⼦的xml配置。
Mybatis现在已经为Springboot提供了⽀持,我们只需要添加MyBatis-Spring-Boot-Starter这个依赖,它就会为我们去做好以下的事情:
1. ⾃动检测已有的datasource
2. 创建⼀个SqlSessionFactoryBean的实例SqlSessionFactory,并将datasource装配进去
3. 创建⼀个SqlSessionTemplate的实例,并将SqlSessionFactory装配进去
4. ⾃动扫描你的mapper,将它们连接到SqlSessionTemplate,并将它们注册到Spring的上下⽂,以便将它们注⼊到其他
的bean中。
所以,在Springboot的Mybatis配置中,我们需要去做以下⼏件事情:
在application-{profile}.properties中填⼊数据库信息,例如:
spring.datasource.url=jdbc:oracle:thin:@//localhost:1234/example
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.driver-class-name=oracle.jdbc.driver.OracleDriver
spring.datasource.maxActive=10
spring.datasource.maxIdle=5
spring.datasource.maxWait=-1
通过这种⽅式,我们便在Spring上下⽂中注册了datasource这个bean。
创建⼀个MybatisConfig⽂件,⽤java的⽅式取代xml:
/**
* Created by WuTaoyu on 2017/12/7.
*/
@Configuration
@EnableTransactionManagement
@MapperScan("ample.db.dao")
public class MybatisConfig {
@Autowired
private DataSource dataSource;
@Bean(name = "sqlSessionFactory")
public SqlSessionFactory sqlSessionFactoryBean() {
SqlSessionFactoryBean sqlsession = new SqlSessionFactoryBean();
sqlsession.setDataSource(dataSource);
try {
//添加XML⽬录
ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
sqlsession.Resources("classpath:mapping/*.xml"));
Object();
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
@Bean
public SqlSessionTemplate sqlSessionTemplate(SqlSessionFactory sqlSessionFactory) {
return new SqlSessionTemplate(sqlSessionFactory);
}
@Bean
public PlatformTransactionManager annotationDrivenTransactionManager() {
return new DataSourceTransactionManager(dataSource);
}
@Bean(name = "exampleSequence")
public OracleSequenceMaxValueIncrementer exampleSequenceBean(){
OracleSequenceMaxValueIncrementer exampleSequence = new OracleSequenceMaxValueIncrementer();
exampleSequence.setIncrementerName("EXAMPLE_SEQ");
exampleSequence.setDataSource(dataSource);
return exampleSequence;
}
}
@MapperScan是扫描这个包下⾯的mapper。
另外这⾥l的位置,是在resource⽂件夹下⾯建了⼀个mapping⽂件夹,放在下⾯。
这⾥的作⽤跟XML⽐较类似,是将传统的xml表达⽅式⽤.java⽂件来描述出来,本质上还是将datasource⼀步步注⼊。由于⽰例⽤的是oracle数据库,所以最后⼀个exampleSequence是⽰范如何添加序列。
对所有mapper的interface注解@Mapper
例如:
@Mapper
public interface UserMapper {
...
}
⽇志⽂件配置
Logback⽀持⽤properties的⽅式外部化配置,但是对于⽐较细的配置来说,还是要沿⽤xml配置。
为了让xml⽂件从.properties⽂件读取⼀些路径之类可能需要经常修改的静态配置,需要在l中配置 <property resource="application.properties" />
<property name="level" value="${level}" />
<property name="log.path" value="${log.path}" />
<property name="duleName" value="${dule}" />
这样⼦就可以将application.properties⽂件中的
log.path=/home/logs/example
读⼊到l中,然后再去调⽤。
WebConfig配置
WebConfig的主要作⽤是替代l和l进⾏⼀些基础配置。
1、关于l
传统的Spring项⽬都有配置⼀个l⽂件,这个⽂件的作⽤是:当我们把war包放⼊应⽤容器(例如tomcat)中运⾏时,容器会根据l去加载filter(过滤器)、servlet、error-page、welcome-file-list、listener()、context-param(上下⽂参数)、resource-ref(资源配置)等配置。
包括ContextLoaderListener这个,就是在这⾥加载进去,⽤于在启动容器的时候,⾃动装配ApplicationContext的配置信息。
<listener>
<listener-class>org.t.ContextLoaderListener</listener-class>
</listener>
这个ApplicationContext是Spring IOC的核⼼(继承⾃BeanFactory),所有单例的Bean会在这个时候就被实例化。
以及,SpringMVC中很重要的⼀个DispatcherServlet也是在这⾥加载进去,并制定根据哪个xml⽂件来配置DispatcherServlet。
<servlet>
<servlet-name>SpringMVC</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>l</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
<!--<async-supported>true</async-supported>-->
</servlet>
2、关于l
以上都与Springboot⽆关,主要是为了知其然也知其所以然,如果不感兴趣的可以不看。
再讲回Springboot的配置。Springboot有⼀个说法叫“约定优于配置”,就是尽量⽤约定的⽅式,⽽不是特地去针对性地配置(需要特殊配置的时候再去配置)。
引⼊spring-boot-starter-web这个“开箱即⽤”的依赖之后,spring-boot-starter-web下包含了⼀个spring-boot-autoconfigure。
有了这个依赖之后,就可以使⽤@EnableAutoCongiguration注解。这个注解就会根据引⼊的依赖来猜测你需要的Spring配置并帮你配置好。因为已经引⼊了spring-boot-starter-web的话,这个注解就会将web相关的配置配置好。
另外,@SpringBootApplication这个注解中已经包含了@EnableAutoCongiguration注解。所以只要在启动类ExampleServerApplication上注解@SpringBootApplication就可以⾃动把web配置给配置好了。
当然,我们可能还有⼀些特殊的配置,这时候就可以创建⼀个WebConfig去定制
/**
* Created by WuTaoyu on 2017/12/8.
*/
@Configuration
public class WebConfig extends WebMvcConfigurerAdapter {
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
converters.add(marshallingHttpMessageConverter());
}
public MarshallingHttpMessageConverter marshallingHttpMessageConverter(){
MarshallingHttpMessageConverter marshallingHttpMessageConverter = new MarshallingHttpMessageConverter();
List<MediaType> mediaTypes = new ArrayList<MediaType>();
mediaTypes.add(MediaType.TEXT_XML);
mediaTypes.add(MediaType.APPLICATION_XML);
XStreamMarshaller xStreamMarshaller=new XStreamMarshaller();
marshallingHttpMessageConverter.setSupportedMediaTypes(mediaTypes);
marshallingHttpMessageConverter.setMarshaller(xStreamMarshaller);
marshallingHttpMessageConverter.setUnmarshaller(xStreamMarshaller);
return marshallingHttpMessageConverter;
}
//配置⽂件上传
@Bean(name = {"multipartResolver"})
public MultipartResolver multipartResolver(){
CommonsMultipartResolver commonsMultipartResolver=new CommonsMultipartResolver();
commonsMultipartResolver.setDefaultEncoding("utf-8");
commonsMultipartResolver.setMaxUploadSize(10485760000L);
commonsMultipartResolver.setMaxInMemorySize(40960);
return commonsMultipartResolver;
}
//异常处理
@Bean
public ExceptionHandler exceptionResolver(){
ExceptionHandler exceptionHandler = new ExceptionHandler();
return exceptionHandler;
}
//
@Override
public void addInterceptors(InterceptorRegistry registry){
registry.addInterceptor(new LogInterceptor()).addPathPatterns("/**");
super.addInterceptors(registry);
}
}
我写的这个⽰例⽂件⾥⾯做了⼏件事情:
1. 引⼊⼀个XML的Http消息转换器
2. 引⼊multipartResolver
3. 引⼊⾃定义的异常处理器
4. 引⼊⾃定义
去掉多余的bean注⼊
这个算是⼀个题外话,但也是我实际遇到的问题之⼀。
在实际运⾏的Springboot项⽬的时候,我发现了⼀些在传统Spring项⽬中没有报错的问题,就是多余的bean注⼊。
在传统Spring项⽬中,这是没有报错的,但是在Springboot项⽬中就报错了。我猜测是因为要注⼊bean的类⽅法名取的⽐较精简的时候,与Springboot本⾝⾃动配置的⼀些bean重复了,就会报错。
所以,把有些不需要注⼊的bean去掉吧。
以上就是本⽂的全部内容,希望对⼤家的学习有所帮助,也希望⼤家多多⽀持。