基于SSM的全注解模式Web项目的环境搭建

      以往我们用SSM构建Web项目,需要一些配置文件,例如web.xml,spring-*.xml等等,servlet3.0+版本提供了基于注解模式的Web项目构建方式,省去了配置文件。本文主要描述了基于注解方式的Web项目环境搭建。

      既然去掉了配置文件,那么我们需要编写一些配置类,来代替配置文件,构建起基本的项目环境,下面是Web项目基本环境的搭建:

import java.io.IOException;

import javax.sql.DataSource;

import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.mapper.MapperScannerConfigurer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;

import com.alibaba.druid.pool.DruidDataSource;


@Configuration
@PropertySource("classpath:configs.properties")
public class AppRootConfig {
	
	
	public AppRootConfig() {
		System.out.println("AppRootConfig");
	}

	@Bean
	public DruidDataSource getDataSource(
			@Value("${jdbcDriver}")String driver,
			@Value("${jdbcUrl}")String url,
			@Value("${jdbcUser}")String username,
			@Value("${jdbcPassword}")String password){
		DruidDataSource ds=new DruidDataSource();
		ds.setDriverClassName(driver);
		ds.setUrl(url);
		ds.setUsername(username);
		ds.setPassword(password);
		return ds;
	}
	
	@Bean("sqlSessionFactory")
	public SqlSessionFactoryBean getFactory(@Autowired DataSource ds) throws IOException{
		SqlSessionFactoryBean factory=new SqlSessionFactoryBean();
		factory.setDataSource(ds);
		ResourcePatternResolver resolver=new PathMatchingResourcePatternResolver();
		Resource[] mapperLocations=resolver.getResources("classpath:mapper/*.xml");
		factory.setMapperLocations(mapperLocations);
		return factory;
	}
	
	@Bean
	public MapperScannerConfigurer getScanner(){
		MapperScannerConfigurer scanner=new MapperScannerConfigurer();
		scanner.setBasePackage("com.jt.**.dao");
		scanner.setSqlSessionFactoryBeanName("sqlSessionFactory");
		return scanner;
	}
}

这里首先@Configuration表示这是一个配置类,然后加载了一个configs.properties文件,内部定义了数据库连接的相关配置。类中首先利用阿里开发的druid连接池获取数据库连接,接着基于此连接获取了Mybatis中的关键对象sqlSessionFactory,这是Spring关于Mybatis部份的整合,最后注册了一个扫描dao包的扫描器,dao包中用于存放数据持久层的接口,而扫描器扫描后,可以生成这个接口相对应的bean对象,不需要我们再调用getMapper()方法手动获取。

      基本环境搭建完毕,我们需要搭建Servlet环境:

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.ViewResolverRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

@Configuration
@ComponentScan("com.jt")
@EnableWebMvc
public class AppServletConfig extends WebMvcConfigurerAdapter{
	@Override
	public void configureViewResolvers(ViewResolverRegistry registry) {
		registry.jsp("/WEB-INF/pages/", ".html");
	}
}

这里首先同样表明它是一个配置类,然后@ComponentScan("com.jt")表示扫描这个包下的所有组件,即包含有类似@Controller,@Configuration,@Bean等注解的部分。@EnaleWebMvc表示启用WebMvc的相关注解和默认配置。这个类继承了WebMvcConfigurerAdapter,从名字可以看出这是一个关于WebMvc配置的类,可以通过重写父类方法的方式为当前项目进行配置。类中加载了一个视图解析器,视图文件的路径是/WEB-INF/pages,文件的类型是.html文件。此外这个类中还可以通过重写addInterceptors()方法添加拦截器。

      配置类准备就绪,既然作为配置类,那么肯定是要在项目启动时就生效,那么怎样让我们的配置类在服务器启动时就自动加载呢?找到下图中的文件,打开以后找到文件中的那个类org.springframework.web.SpringServletContainerInitializer,


@HandlesTypes(WebApplicationInitializer.class)
public class SpringServletContainerInitializer implements ServletContainerInitializer {

	
	
	@Override
	public void onStartup(Set<Class<?>> webAppInitializerClasses, ServletContext servletContext)
			throws ServletException {

		List<WebApplicationInitializer> initializers = new LinkedList<WebApplicationInitializer>();

		if (webAppInitializerClasses != null) {
			for (Class<?> waiClass : webAppInitializerClasses) {
				// Be defensive: Some servlet containers provide us with invalid classes,
				// no matter what @HandlesTypes says...
				if (!waiClass.isInterface() && !Modifier.isAbstract(waiClass.getModifiers()) &&
						WebApplicationInitializer.class.isAssignableFrom(waiClass)) {
					try {
						initializers.add((WebApplicationInitializer) waiClass.newInstance());
					}
					catch (Throwable ex) {
						throw new ServletException("Failed to instantiate WebApplicationInitializer class", ex);
					}
				}
			}
		}

		if (initializers.isEmpty()) {
			servletContext.log("No Spring WebApplicationInitializer types detected on classpath");
			return;
		}

		servletContext.log(initializers.size() + " Spring WebApplicationInitializers detected on classpath");
		AnnotationAwareOrderComparator.sort(initializers);
		for (WebApplicationInitializer initializer : initializers) {
			initializer.onStartup(servletContext);
		}
	}

}

这个类上的注释@HandlesTypes(WebApplicationInitializer.class),服务器启动时,spring会通过这个类中的onStartup()方法加载WebApplicationInitializer这个接口及其子类,那么我们只需要写一个类实现这个接口,再把我们需要启动时加载的部分放在这个类中即可。

import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;

public class AppWebInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
	@Override
	protected Class<?>[] getRootConfigClasses() {
		return new Class[]{AppRootConfig.class};
	}

	@Override
	protected Class<?>[] getServletConfigClasses() {
		return new Class[]{AppServletConfig.class};
	}

	@Override
	protected String[] getServletMappings() {
		return new String[]{"*.do"};
	}

}

      AbstractAnnotationConfigDispatcherServletInitializer 是WebApplicationInitializer接口的一个实现类,我们写了一个雷,继承了这个实现类,并重写了其中的关键方法,加载了本项目中的配置类。最后的*.do规定了客户端访问时,需要以.do结尾,才能通过前端控制器。

猜你喜欢

转载自blog.csdn.net/sunroyfcb/article/details/80646079