使用配置文件有时比较麻烦,但是spring可以实现完整的注解开发。
spring注解开发基础
使用配置文件启动IoC容器的对象是ClassPathXmlApplicationContext
而使用配置类启动IoC容器的对象是AnnotationConfigApplicationContext
。
配置类
import com.ssm.pojo.Test;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class SpringContextConfig {
@Bean
public Test test1(){
return new Test();
}
}
启动程序
import com.ssm.config.SpringContextConfig;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import java.applet.AppletContext;
public class ConfigTest {
@Test
public void test1(){
ApplicationContext context=new AnnotationConfigApplicationContext(SpringContextConfig.class);
com.ssm.pojo.Test test = context.getBean(com.ssm.pojo.Test.class);
}
}
spring配置类
@配置配置类注解
@ComponentScan("com.ssm.controller") 组件扫描位置注解
@Configuration
@ComponentScans({
@ComponentScan("com.ssm.pojo"),@ComponentScan("com.ssm.dao"),@ComponentScan("com.ssm.service")}) //组件扫描位置,除控制器扫描所有类
public class SpringContextConfig{
@Bean
public Test test1(){
return new Test();
}
}
该类是根配置类相当于spring-context.xml
进行spring的相关配置,可以通过@Bean
注解将java对象注入到IoC容器中也可以使用@ComponentScans
配置扫描的位置,开启注解扫描。
spring mvc配置类
在spring中我们可以通过用java代码配置bean,而不使用xml (相当于applicationContext.xml),改成使用java代码来实现javabean的配置:
@Configuration //定义是spring的bean配置类
@ComponentScan("com.ex.test") //扫描包
@Import(other.class) //导入config
public class ApplicationContext{
@Bean
public User user(){
return new User();}
}
而WebMvcConfigurer
配置类其实是Spring内部的一种配置方式,可以自定义一些Handler,Interceptor,ViewResolver,MessageConverter等等的东西对springmvc框架进行配置。(相当于spring-mvc.xml),除了该类还有其他几个类具有同样的功能:
Spring MVC注解开发,自定义配置类的三种方式:(使用前两种方式时,不会读取application.yml的配置,需要重写某些方法来保证一些默认配置)
- @EnableWebMvc+实现WebMvcConfigurer;不使用@EnableAutoConfiguration中的设置
- 扩展 WebMvcConfigurationSupport;不使用@EnableAutoConfiguration中的设置
- 实现WebMvcConfigurer;使用 @EnableAutoConfiguration 中的设置
自定义框架,可以自定义一些Handler、Interceptor、ViewResolver、MessageConverter。
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
@ComponentScan("com.ssm.controller")
@EnableWebMvc
public class SpringWebmvcConfig implements WebMvcConfigurer {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/../.html").addResourceLocations("/");
registry.addResourceHandler("/../.js").addResourceLocations("/");
registry.addResourceHandler("/../.css").addResourceLocations("/");
registry.addResourceHandler("/../.png").addResourceLocations("/");
} //配置视图解析器,资源管理器,拦截器等
}
还启用注释扫描以释放静态资源。
web容器、web容器的配置文件web.xml及web容器的配置类
Web容器实际上是一个servlet,运行在Web服务器上。 web.xml是Web容器的配置文件,在Web服务器启动时自动加载。在ssm框架中,不需要servlet,取而代之的是DispatcherServlet作为主要的web容器,用来处理所有的请求。 web.xml 也是它的配置文件。
spring mvc框架中自带DispatcherServlet,只需要在配置文件web.xml
中配置。在完全注解开发不需要在web.xml中配置任何东西。那么该如何配置DispatcherServlet呢?代替方案是web容器的初始化对象WebApplicationInitializer
是随web应用启动而加载的 (相当于web.xml)。AbstractAnnotationConfigDispatcherServletInitializer
是已配置了DispatcherServle继承自AbstractDispatcherServletInitializer
该类又集成WebApplicationInitializer(web.xml),于是通过继承后只需要进行属性的配置。
现在JavaConfig配置方式正在逐渐取代xml配置方式。 WebApplicationInitializer可以看作是Web.xml的替代品,它是一个接口。通过实现WebApplicationInitializer,您可以向其中添加servlet、侦听器等。当加载Web项目时,会加载这个接口实现类,从而起到与web.xml相同的作用。
AbstractDispatcherServletInitializer也可以配置DispacherServlet,但AbstractAnnotationConfigDispatcherServletInitializer更简单。
import com.ssm.config.SpringContextConfig;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
/** * 该类相当于web.xml主要用来配置DispatcherServlet和加载spring相关的配置类 * 目的是在tomcat启动时加载IoC容器 */
public class WebConfig extends AbstractAnnotationConfigDispatcherServletInitializer{
//该类随tomcat的启动自动加载
@Override
protected Class<?>[] getRootConfigClasses() {
// 根容器配置类
return new Class[]{
SpringContextConfig.class};
}
@Override
protected Class<?>[] getServletConfigClasses() {
// web-mvc容器配置类
return new Class[]{
SpringWebmvcConfig.class};
}
@Override
protected String[] getServletMappings() {
// 设置拦截的路径
return new String[]{
"/","*.action"};
}
}
分别配置并加载spring的配置类、spring mvc的配置类和拦截路径。
javax.servlet.ServletContainerInitializer
接口的实现类在Servlet3.0环境中,用于配置容器。
Spring提供了上述接口的实现类SpringServletContainerInitializer,SpringServletContainerInitializer反过来会找到实现WebApplicationInitializer的类,并将配置任务交给它们。
Spring 3.2中引入的AbstractAnnotationConfigDispatcherServletInitializer是WebApplicationInitializer的基本实现,因此当部署到servlet3.0容器时,容器会发现它的子类并使用子类来配置Servlet上下文。
可以在子类中重写三个方法:
- getServletMappings():将一条或多条路径映射到DispatcherServlet;
- getServletConfigClasses():返回带有@Configuration注解的类,用于配置DispatcherServlet;
- getRootConfigClasses():返回带有@Configuration注解的类,用于配置ContextLoaderListener;
当DispatcherServlet启动时,它会创建一个Spring应用程序上下文并加载在配置文件或配置类中声明的bean;在 Spring Web 应用程序中,通常还有一个由 ContextLoaderListener 创建的上下文。
DispatcherServlet加载包含Web组件的bean,如控制器、视图解析器以及处理器映射;
ContextLoaderListener加载应用中的其它bean,通常指驱动应用后端的中间层和数据层组件。
AbstractAnnotationConfigDispatcherServletInitializer会同时创建DispatcherServlet和ContextLoaderListener。是传统web.xml方式的替代方式。
AbstractAnnotationConfigDispatcherServletInitializer
参考
上面的位置控制器部分已经配置完毕。编写控制器:
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class TestController {
@GetMapping(value = "/test")
public String method1(){
return "test ok!";
}
}
控制器部分的启动流程:
spring mybatis配置
控制器部分已经配置完毕,查询数据库内容,使用mybatis持久层。如何通过注解将mybatis与spring集成?
@映射器注解可以代替mapper映射文件,和mybatis-config.xml配置文件,该注解会生成一个静态的SqlSessionFactory,和动态的SqlSession然后调用getMapper()
方法返回mapper对象。使用@Repository将该对象注入到IoC容器中。
pom 文件导入必要的依赖项:
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.5</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.3.1</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.11</version>
</dependency>
xml配置中,持久层有两个配置文件mybatis-config.xml和spring-mybatis.xml。这两个配置文件需要的关键信息是:
- DataSource对象包括driver、url、用户名、密码;
- SqlSessionFactoryBean对象,其作用是根据DataSource的信息创建一个静态的SqlSessionFactory;
- MapperScannerConfigurer对象,调用SqlSessionFactory动态生成Mapper。
public class MybatisConfig {
// 注入SqlSessionFactoryBean
@Bean
public SqlSessionFactoryBean sqlSessionFactoryBean(DataSource dataSource){
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(dataSource);
// 实体类别名包
bean.setTypeAliasesPackage("com.ssm.pojo");
return bean;
}
//配置mapper映射
@Bean
public MapperScannerConfigurer mapperScannerConfigurer(){
MapperScannerConfigurer mapperScanner=new MapperScannerConfigurer();
//动态生成mapper的扫描目录
mapperScanner.setBasePackage("com.ssm.dao");
return mapperScanner;
}
}
/** *** */
@Value("${jdbc.driver}")
private String driverClass;
@Value("${jdbc.url}")
private String url;
@Value("${jdbc.username}")
private String username;
@Value("${jdbc.password}")
private String password;
//配置数据源
@Bean
public DataSource dataSource(){
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(driverClass);
dataSource.setPassword(password);
dataSource.setUrl(url);
dataSource.setUsername(username);
return dataSource;
}
在根spring配置中需要使用
@Import(MybatisConfig.class)
引入mybatis配置类。DataSource对象既可以配置在spring根容器,也可以通过在mybatis配置类中配置在@Import引入。
至此,SSM完整的标注开发已经完成。对于业务部分,只需自动组装Mapper并正常编写接口即可。
四个配置类的主要内容:
SpringContactConfig
import com.ssm.pojo.Test;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.*;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import javax.sql.DataSource;
@Configuration
//开启注解扫描的路径
@ComponentScans({
@ComponentScan("com.ssm.pojo"),@ComponentScan("com.ssm.service")}) //组件扫描位置,除控制器扫描所有类
// 加载数据库连接的配置的资源文件
@PropertySource("classpath:datasource.properties")
@Import(MybatisConfig.class)
public class SpringContextConfig{
@Value("${jdbc.driver}")
private String driverClass;
@Value("${jdbc.url}")
private String url;
@Value("${jdbc.username}")
private String username;
@Value("${jdbc.password}")
private String password;
//配置数据源
@Bean
public DataSource dataSource(){
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(driverClass);
dataSource.setPassword(password);
dataSource.setUrl(url);
dataSource.setUsername(username);
return dataSource;
}
}
SpringMvc配置
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
//开启mvc注解扫描
@ComponentScan("com.ssm.controller")
@EnableWebMvc
public class SpringWebmvcConfig implements WebMvcConfigurer {
//释放静态资源
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/../.html").addResourceLocations("/");
registry.addResourceHandler("/../.js").addResourceLocations("/");
registry.addResourceHandler("/../.css").addResourceLocations("/");
registry.addResourceHandler("/../.png").addResourceLocations("/");
} //配置视图解析器,资源管理器,拦截器等
}
Mybatis配置
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.mapper.MapperScannerConfigurer;
import org.springframework.context.annotation.Bean;
import javax.sql.DataSource;
public class MybatisConfig {
// 注入SqlSessionFactoryBean
@Bean
public SqlSessionFactoryBean sqlSessionFactoryBean(DataSource dataSource){
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(dataSource);
// 实体类别名包
bean.setTypeAliasesPackage("com.ssm.pojo");
return bean;
}
//配置mapper映射
@Bean
public MapperScannerConfigurer mapperScannerConfigurer(){
MapperScannerConfigurer mapperScanner=new MapperScannerConfigurer();
mapperScanner.setBasePackage("com.ssm.dao");
return mapperScanner;
}
}
配置类其实和配置文件类似。配置文件被相关对象替换并与Web容器一起初始化。
Web.xml配置类WebConfig
import com.ssm.config.SpringContextConfig;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
/** * 该类相当于web.xml主要用来配置DispatcherServlet和加载spring相关的配置类 * 目的是在tomcat启动时加载IoC容器 */
public class WebConfig extends AbstractAnnotationConfigDispatcherServletInitializer{
//该类随tomcat的启动自动加载
@Override
protected Class<?>[] getRootConfigClasses() {
// 根容器配置类
return new Class[]{
SpringContextConfig.class};
}
@Override
protected Class<?>[] getServletConfigClasses() {
// web-mvc容器配置类
return new Class[]{
SpringWebmvcConfig.class};
}
@Override
protected String[] getServletMappings() {
// 设置拦截的路径
return new String[]{
"/","*.action"};
}
}
上面的对象可能会有所不同,因为有子类或父类可以完成相同的功能,就像HttpServlet和GenericServlet都可以用作Web容器,但提供的功能数量不同。
所有配置类配置完毕后,编写测试接口:
```java
@RestController
public class TestController {
@Resource
private TestMapper testMapper;
@GetMapping(value = "/test")
public String method1(){
return "test ok!";
}
@GetMapping(value = "/users")
public List<User> method2(){
List<User> users = testMapper.users();
return users;
}
}
资源中有配置完整注释的开发示例。下载它们以供参考。